Skip to content

Flash向量-12-球和圆弧

现在,让我们一起研究下如何处理运动的球和圆弧。圆弧式圆的一部分,不同的是圆石360度的,而圆弧不足360度。对于球和球的碰撞,之可能存在一个碰撞点。对于球和圆弧的碰撞,可能有……不是1个,也不是2个,而是4个碰撞点。

图中,左边,运动的球从原画的外面碰撞到圆弧,中间,球从圆弧的里面碰撞到圆弧,右边,球碰到了圆弧的端点(圆弧有2个端点,球可能同时碰到这2个端点)

为了定义一个圆,我们需要中心点和半径。为了定义一个圆弧,除了需要中心点和半径,还需要它的起始端点的角度和终终止端点的角度。

例如,我们可以这样定义圆弧:

arc={p0:{x:170, y:90}, r:30, ang1:135, ang2:315};

圆弧的中心点在x=170,,y=90,它的半径为30,起点角度为135度,终点角度为315度。知道了这些,我们可以计算出圆弧的起点和终点的坐标:

ang1rad=ang1*Math.PI/180;
ang2rad=ang2*Math.PI/180;
v1.p0={
x:p0.x+r*Math.cos(ang1rad),
y:p0.y+r*Math.sin(ang1rad)
};
v1.p1={
x:p0.x+r*Math.cos(ang2rad),
y:p0.y+r*Math.sin(ang2rad)
};

向量1是圆弧的起点到终点连线向量。

碰撞

可以使用球和球章节介绍的方法,检测球和圆弧外面的碰撞。当碰撞发生的时候,我们再来检测这个碰撞的位置是否在圆弧上存在。

我们需要找到球和圆弧相切的点p3。我们知道了发生碰撞时球心的位置,所以我们可以画一个向量v2,从圆弧中心到碰撞时球的中心。

v2={p0:arc.p0, p1:ball.p3};

点p3在在这个向量上,它和圆弧中心的距离为圆弧的半径(它和球的中心的距离为球的半径):

p3={
x:arc.p0.x+v2.dx*arc.r,
y:arc.p0.y+v2.dy*arc.r
};

然后我们画一个向量,从圆弧的起点到点p3:

v3={p0:v1.p0, p1:p3};

只有当v3和v1的左法线的点乘大于0时,p3才在圆弧上。

if(dotP(v3, v1LeftNormal)>=0){
  //collision
}else{
  //not on the arc
}

如果碰撞发生在圆弧的外侧,我们可以忽略其他3种情况。然而,如果碰撞点p3,不在圆弧上面,我们就要考虑球是否碰到圆弧的端点,还是碰到了圆弧的内侧。

对于端点,我们可以继续使用球和球的系统,假设端点是看不见的球,半径为0,坐落在端点坐标。和球碰撞的圆弧是:

ballvsBall(ball, arc.p0, arc.r);

我们可以这样检测端点碰撞:

ballvsBall(ball, v1.p0, 0);
ballvsBall(ball, v1.p1, 0);

对于球和圆弧内部碰撞,我们使用外部碰撞系统的略加修改版。外部碰撞检测方法是:

r=arc.r+ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x-moveBack*v.dx,
y:ball.p2.y-moveBack*v.dy};

内部碰撞检测方法:

r=arc.r-ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x+moveBack*v.dx,
y:ball.p2.y+moveBack*v.dy};

由于球可能和圆弧的多个点碰撞,我们可以取最短路径。

下面的例子中展示了球和圆弧的碰撞,你可以体验下:

你可以下载fla源文件

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*