圆圈碰撞问题
问题描述:
我有圆圈碰撞detection.I一个问题所使用的下面的算法圆圈碰撞问题
func collision(id,other.id)
{
var vaP1,vaP2,dis,va1,vb1,va2,vb2,vp1,vp2,dx,dy,dt;
if (id!=other.id)
{
dx=other.x-x;
dy=other.y-y;
dis=sqrt(sqr(dx)+sqr(dy));
if dis<=radius+other.radius
{
//normalize
dx/=dis;
dy/=dis;
//calculate the component of velocity in the direction
vp1=hspeed*dx+vspeed*dy;
vp2=other.hspeed*dx+other.vspeed*dy;
if (vp1-vp2)!=0
{
dt=(radius+other.radius-dis)/(vp1-vp2);
//move the balls back so they just touch
x-=hspeed*dt;
y-=vspeed*dt;
other.x-=other.hspeed*dt;
other.y-=other.vspeed*dt;
//projection of the velocities in these axes
va1=(hspeed*dx+vspeed*dy);
vb1=(vspeed*dx-hspeed*dy);
va2=(other.hspeed*dx+other.vspeed*dy);
vb2=(other.vspeed*dx-other.hspeed*dy);
//new velocities in these axes. take into account the mass of each ball.
vaP1=(va1+bounce*(va2-va1))/(1+mass/other.mass);
vaP2=(va2+other.bounce*(va1-va2))/(1+other.mass/mass);
hspeed=vaP1*dx-vb1*dy;
vspeed=vaP1*dy+vb1*dx;
other.hspeed=vaP2*dx-vb2*dy;
other.vspeed=vaP2*dy+vb2*dx;
//we moved the balls back in time, so we need to move them forward
x+=hspeed*dt;
y+=vspeed*dt;
other.x+=other.hspeed*dt;
other.y+=other.vspeed*dt;
}
}
}
x=ball 1 x-position
y=ball 1 y-position
other.x= ball 2 x position
other.y=ball 2 y position
该算法效果良好,当我具有40×40像素的球图像和球中心是(20,20)意味着图像只包含球。但是当图像大小为80×80,并且球中心位置为(60,60)时,意味着球是半径为20的右下角。在这种情况下,存在这样的问题: 发生多次碰撞意味着该部分
x+=hspeed*dt;
y+=vspeed*dt;
other.x+=other.hspeed*dt;
other.y+=other.vspeed*dt;
无法分离球/速度不会因碰撞而改变。 我已经改变了图像40,40中心的x值到60,60球的中心加20.但结果是一样的。任何人都可以告诉我什么是问题。我认为算法是正确的,因为它在所有其他情况下很好地工作,很多人使用这种算法。问题是从图像中心到球中心的位置发生变化。我应该为此做些什么修正?或任何想法。如果有人想帮助PLZ给我的电子邮件地址,以便我可以发送我的完整项目。
答
我没有精神力量来消化你的整个问题,但这里是我的2对如何解决你的问题美分
1)来检测与另一圈的碰撞,最简单的方法是检查,如果他们的距离小于组合圆的半径。 (我可能是错误的数学,所以纠正我,如果我错了)
Circle c1,c2;
float distance = DISTANCE(c1.center,c2.center);
if(distance < c1.radius + c2.radius)
{
// collision .. BOOOOOOM
}
2)尝试使用准确的数据类型。尽量不要将浮点数转换为整数而不检查溢出,下溢和小数点。更好的是,只需使用浮动。
3)写一个日志并跟踪你的值。看看是否有明显的数学错误。
4)将代码分解为最简单的部分。尝试去除所有速度计算以获得最简单的移动来帮助您进行调试。
答
我不会给你你正在寻找的答案,我不确定别人会。为解决问题而必须解密的代码数量可能无法保证获得回报。我会推荐的是放弃算法中的耦合。上面的功能做得太多了。
理想情况下,您将有一个碰撞检测,只集中在碰撞,而不是推进球。就像下面显示的功能一样,如果您还有问题,可以让其他开发人员更轻松地帮助您。
function(firstCircleCenterX, firstCircleCenterY, secondCircleCenterX, secondCircleCenterY, firstCircleRadius, secondCircleRadius)
{
...this code should concentrate on logic to determine collision
...use pythagoran theory to find distance between the two centers
...if the distance between the two centers is less than ((2*firstCircleRadius)+(2*secondCircleRadius) then you have a collision
...return true or false depending on collision
}
您的代码示例适用于在连续2d坐标系中移动球。但是,在代码示例结尾处的问题中(我并未完全遵循),您将讨论关于图像中心或不在图像中心的球,以及有关像素的内容。我的猜测是:问题在于围绕在此给出的代码的代码中。 – 2009-12-07 08:56:33