圆圈之间的2d碰撞响应

时间:2011-06-23 18:40:22

标签: math physics collision-detection

我正在尝试计算2个碰撞球的新速度,但在解决另一个问题之前无法真正做到这一点。

由于在数字世界中几乎从未发生过真正的碰撞,我们总会遇到“碰撞”球重叠的情况。

想象一下有100个球在随机移动,所以,如果我理解正确的话,程序应该如下:

  • 移动球(x += vx; y+= vy;)
  • 获取最重要的(或完全碰撞的)球
  • 将球“及时”移回到那一刻
  • 执行碰撞计算

如果上述情况正确,那么,我怎样才能将球“及时”移动到第一次碰撞的位置?已知数据:

  • 球的所有坐标(b[i].xb[i].y
  • Ball XY速度(b[i].vxb[i].vy
  • 重叠球之间的距离(dist

我应该只计算dist与碰撞完美距离的百分之几,然后简单地将xy坐标移回{{1}的相同百分比1}}和vx

4 个答案:

答案 0 :(得分:3)

你的移动碰撞策略是否有意义取决于你想要模拟的东西,以及准确性和速度之间的权衡。如果你是,比如写一个斯诺克模拟器,或者超级猴子球,那么移动然后碰撞可能不够好,原因有三个。

首先,碰撞后球会有错误的速度。差异将是微妙的,但玩家会觉得不对:

  

enter image description here see text

在左侧,在检测到碰撞之前允许球相交的时间步结束时的速度。在右边:在正确的时间和地点碰撞后立即的速度。

其次,移动得足够快的物体可以相互穿过而不会发生碰撞。或者即使您检测到碰撞,也可能以错误的方式弹出物体,导致某种非法运动。 (请参阅tasvideos.org了解超级马里奥兄弟游戏中的collection of collision bugs,这是由此移动然后弹出策略引起的。)

第三,物体可能会在你的时间步骤结束时交叉,没有空间将它们分开(因为其他物体挡住了它们)。所以你最终不得不在交叉位置绘制对象,这看起来是错误的。

在这些问题很重要的应用中,最好在移动球之前确定碰撞点。有关此碰撞然后移动方法的基本介绍,请参阅this article of mine

答案 1 :(得分:3)

对于像这样的碰撞,通常最容易从其中一个球的参考框架中查看它。

假设您有ball1ball2。这些球的位置分别为p1p2,速度为v1v2。设ball1相对于ball2的相对速度为v1-v2=v

我们想知道||p1-p2||何时小于||r1||+||r2||,其中r1是第一个球在朝向第二个球的方向上的半径长度的向量,并且r2反之亦然。

ball2的角度来看,ball1正以速度v1+v2移动。在t时间,ball2位于p2+(v1+v2)*t位置。

球在以下情况下发生碰撞:

(p1-(p2+vt)) = (r1+r2)
-(p2+vt) = (r1+r2)-p1
-p2-vt = (r1+r2)-p1
-vt = (r1+r2)-p1+p2
vt = (p1-p2)-(r1+r2)

现在||a|| = ||b||+||c|| a = b+c以后||v||t = ||p1-p2|| - ||r1+r2|| t = (||p1-p2|| - ||r1+r2||)/||v|| ,我们知道

p1 = (7,5)

例如:p2=(4,1)||r1||=1||r1||=2v1=(1,2)v2=(-2,-2)v=(3,4),然后t = (||(3,4)|| - 3)/||(3,4)|| t = (5-3)/(5) = 2/5 = 0.4 。碰撞发生在:

p = p1-p2
v = v1-v2
t = (sqrt(p.x*p.x + p.y*p.y) - (r1+r2)) / sqrt(v.x*v.x + v.y*v.y)

现在您已经有了碰撞的时间,弄清楚球的位置很容易: - )

编辑将vectormath放入伪代码:

{{1}}

答案 2 :(得分:1)

考虑一个圆心在原点和静止的情况下,另一个在例如 -x 方向向它移动的情况。 (您可以使用一些简单的向量代数将任何碰撞情况转换为此。)

因此第二个圆的中心位置是(x,y),其中y是常数,x是减小的。当x 2 + y 2 =(r 1 + r 2 2时发生碰撞/ sup>,称之为x crit 。但是在模拟过程中,我们已经超越了某些x&lt; X <子>暴。因此我们必须回滚足够的时间将其带回x crit ,我们可以轻松计算,因为我们知道x,x crit v

答案 3 :(得分:0)

编辑:没关系,我找到碰撞点的算法是不正确的。我会再考虑一下这个。

EDIT2:好的,抱歉。试试这个:

  1. 找出他们相撞的时间。我们在T秒前打电话给我们。这将是T,使得两个球之间的距离等于它们的半径之和。等式为((x1 - v_x1 * T) - (x2 - v_x2 * T))^ 2 = r1 + r2
  2. 将球移回时间T
  3. 继续您的碰撞
  4. 对不起,我不知道如何在SO上格式化数学方程式。 :S

    回到碰撞时,你可以使用基本物理学相当容易地计算出它们的新速度。见http://en.wikipedia.org/wiki/Elastic_collision#Two-_and_three-dimensional