2D弹性碰撞不能保持动量

时间:2014-02-03 16:32:45

标签: c# directx physics collision

我有一个小型物理程序,它有大量相同大小和质量的球在2D空间中反弹。我遇到的问题是,在大多数碰撞之后,动量会增加,但有时会减少。

public static void Collide(Ball b1, Ball b2)
{
  Vector2 dist = b2.Position - b1.Position;
  float distance = dist.Length();
  Vector2 normal = dist * (1 / distance); //get collision normal
  float dotprod = Vector2.Dot(normal, b1.Velocity - b2.Velocity);
  Vector2 impulse = normal * dotprod; //compute the impulse in the direction of our normal
  //ball positions at collision: (.7071, 0.2929); (1,0)
  //initial velocities: (2, 0); (0, 0) : total momentum = 2
  b1.Velocity -= impulse;
  b2.Velocity += impulse;
  //new velocities: (1,1); (1, -1) : total momentum = ~2.828
}

这是我简化后的碰撞算法,因为所有的球都是相同的大小和质量。我尝试了几种不同的算法,它们都产生了相同的结果。在一个有100个球的系统中,系统的总动量上升到大约90并且当我从1个球开始时动量为10(弹性壁,没有摩擦力)时平稳。基于我尝试过的算法数量,看起来它似乎是假设的工作方式,但似乎这违反了动量守恒?

我尝试过的一些算法: http://www.vobarian.com/collisions/2dcollisions2.pdf(来自维基百科) 和Ball to Ball Collision - Detection and Handling

2 个答案:

答案 0 :(得分:3)

你似乎错误地将总动量本身的个体动量的大小总和。物质点的动量是矢量:

  

p = m。 v

并且总动量是所有个体动量的向量总和:

  

P =Σm i v i =mΣ v <子> I

(在你的情况下所有质量是相等的)

动能是一个标量:

  

K =(1/2)m。 v 2 = p 2 /(2m)< / p>

并且总动能再次是所有单个动能的总和:

  

K =Σ(1/2)m i v i 2 =(m / 2 )Σ v i 2

在弹性碰撞中,K和 P 都是守恒的。这在您的示例中也适用。实际上,你的球的初始速度是(2,0)和(0,0),因此:

  

P 之前 = m *((2,0)+(0,0))=(2m,0)

     

K 之前 =(m / 2)*((2,0)。(2,0)+(0,0)。(0,0))=(m / 2) *(4 + 0)= 2m

最终速度为(1,1)和(1,-1),因此:

  在 = m *((1,1)+(1,-1))=(2m,0)之后

P

     

之后的 =(m / 2)*((1,1)。(1,1)+(1,-1)。(1,-1))=(m / 2)*(2 + 2)= 2m

显然 P = P 之前和K 之后 = K <前子>

答案 1 :(得分:1)

而不是: float dotprod = Vector2.Dot(normal,b1.Velocity - b2.Velocity); 试试这个: Vector2 velocityDif = b1.Velocity - b2.Velocity; float dotprod = Vector2.Dot(normal,Vector2.Normalize(velocityDif));