[canvas] 碰撞
碰撞检测的方法
判断物体与物体之间是否有重叠,这里使用物体的外接矩形边界来确定。
判断物体与物体之间的距离,当距离小于某个值时,满足碰撞条件,物体产生碰撞效果。
光线投射法
画一条与物体速度向量相重合的线,
然后再从待检测物体出发,绘制第二条线,根据两条线的交点位置来判定是否发生碰撞。
#1
是与小球速度向量相重合的线,
#2
线是从待测物体触发绘制的第二条线。
在小球的飞行过程中,程序不断地擦出并重回从小球到1,2号交点处的连线。
小球落入桶中的条件:
1号线与2号线的交点在同口的左边沿与右边沿之间。
小球位于2号线下方。
斜截式
y = kx + b
k表示斜率,
b表示与y轴的截距,也就是直线与y轴交点的纵坐标。
寻找两条直线的交点,
就是寻找同时满足两条直线方程的点,
我们假设这个点为(X0, Y0)
,
两条直线方程分别为 y = (k1)X + b1, y = (k2)X + b2
。
交点就是同时满足的点,那么就有:
(k1)X0 + b1 = (k2)X0 + b2
X0(k1 - k2) = b2 - b1
X0 = (b2 - b1)/(k1 - k2)
Y0 = (k1b2 - k2b1)/(k1 - k2)
该方法也有弊端,当小球做水平运动或是垂直运动时,
其斜率为0或是无穷,这时用该方法就不适用了。
catchBall = {
intersectionPoint: {x:0, y:0},
isBallInBucket: function () {
if(lastBallPosition.left === ball.left ||
lastBallPosition.top === ball.top){
return;
}
//(x1, y1) = Last ball position
//(x2, y2) = Current ball position
//(x3, y3) = Bucket left
//(x4, y4) = Bucket right
var x1 = lastBallPosition.left,
y1 = lastBallPosition.top,
x2 = ball.left,
y2 = ball.top,
x3 = bucket_left + bucket_width/4,
y3 = bucket_top,
x4 = bucket_left + bucket_width,
y4 = y3;
//(x1, y1)到(x2, y2)的斜率
var k1 = (ball.top - lastBallPosition.top)/(ball.left - lastBallPosition.left);
//(x3, y3)到(x4, y4)的斜率
var k2 = (y4 - y3) / (x4 - x3);
//截距b1
var b1 = y1 - k1*x1;
//截距b2
var b2 = y3 - k2*x3;
this.intersectionPoint.x = (b2 - b1) / (k1 - k2);
this.intersectionPoint.y = k1 * this.intersectionPoint.x + b1;
return intersectionPoint.x > x3 &&
intersectionPoint.x < x4 &&
ball.top + ball.height > y3 &&
ball.left + ball.width < x4;
}
}
分离轴定理(SAT)
分离轴定理只适用于凸多边形,也就是所有内角均小于180度的多边形。
比如矩形,三角形等。
而如果有一个内角大于180度,就如吃豆人的形状,就不适合使用该定理。
把受测的两个物体置于一睹墙前面,然后用光线照射它们,
根据阴影部分是否香蕉来判断二者有没有相撞。
碰到了
没碰到