问题描述
我有一个很小的物理程序,里面有大量大小和质量相等的球,它们在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个,当我从一个动量为10的球开始时,系统的总动量趋于平稳(弹性墙,没有摩擦)。根据我尝试的算法数量,似乎这就是应该工作的方式,但这似乎违反了动量守恒定律?
我尝试过的一些算法: http://www.vobarian.com/collisions/2dcollisions2.pdf(来自维基百科) 和Ball to Ball Collision - Detection and Handling
推荐答案
您似乎将单个动量的大小之和误认为总动量本身。物质点的动量是一个矢量量:
p=mv
总动量是所有单个动量的矢量和:
P=∑mi.vi=m∑vi
(与您的情况相同)
动能是标量:
总动能也是所有单个动能的总和:K=(1/2)mv2=p2/(2m)
K=mi.vi2(1/2)vi2=(m/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),因此:
P之后=m*((1,1)+(1,-1))=(2m,0)
K后=(m/2)*((1,1).(1,1)+(1,-1).(1,-1))=(m/2)*(2+2)=2m
明显PAfter=P之前和K之后=K之前。
这篇关于2D弹性碰撞不能保持动量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!