2009-12-07 100 views
1

我有圆圈碰撞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给我的电子邮件地址,以便我可以发送我的完整项目。

+0

您的代码示例适用于在连续2d坐标系中移动球。但是,在代码示例结尾处的问题中(我并未完全遵循),您将讨论关于图像中心或不在图像中心的球,以及有关像素的内容。我的猜测是:问题在于围绕在此给出的代码的代码中。 – 2009-12-07 08:56:33

回答

3

我没有精神力量来消化你的整个问题,但这里是我的2对如何解决你的问题美分

1)来检测与另一圈的碰撞,最简单的方法是检查,如果他们的距离小于组合圆的半径。 (我可能是错误的数学,所以纠正我,如果我错了)

Circle c1,c2; 
float distance = DISTANCE(c1.center,c2.center); 
if(distance < c1.radius + c2.radius) 
{ 
    // collision .. BOOOOOOM 
} 

2)尝试使用准确的数据类型。尽量不要将浮点数转换为整数而不检查溢出,下溢和小数点。更好的是,只需使用浮动。

3)写一个日志并跟踪你的值。看看是否有明显的数学错误。

4)将代码分解为最简单的部分。尝试去除所有速度计算以获得最简单的移动来帮助您进行调试。

-1

我不会给你你正在寻找的答案,我不确定别人会。为解决问题而必须解密的代码数量可能无法保证获得回报。我会推荐的是放弃算法中的耦合。上面的功能做得太多了。

理想情况下,您将有一个碰撞检测,只集中在碰撞,而不是推进球。就像下面显示的功能一样,如果您还有问题,可以让其他开发人员更轻松地帮助您。

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 
} 
+1

......嗯,我想你的意思是(firstCircleRadius + secondCircleRadius) – Pedery 2009-12-07 06:16:08

+0

在这里。 OP应该创建单独的“碰撞”(或可能是“didCollide”)和“反弹”功能。 – outis 2009-12-07 06:25:47

+0

啊......是的..(firstCircleRadius + secondCircleRadius) – FernandoZ 2009-12-30 04:53:26