2

I have a small physics program that has a large number of balls of equal size and mass that bounce around in 2D space. The problem I am having is that after most collisions, the momentum is increased, though sometimes it decreases.

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
}

This is the collision algorithm after I simplified it a lot because all the balls are the same size and mass. I've tried several different algorithms and they all produce the same results. In a system with 100 balls, the total momentum of the system climbs to about 90 and levels off when I start with 1 ball with momentum 10 (elastic walls, no friction). Based on the number of algorithms I have tried, it almost seems like this is how it's supposed to work, but it seems this is violating conservation of momentum?

Some of the algorithms I've tried: http://www.vobarian.com/collisions/2dcollisions2.pdf (from Wikipedia) and Ball to Ball Collision - Detection and Handling

Community
  • 1
  • 1
HypnoToad
  • 585
  • 1
  • 6
  • 18

2 Answers2

4

You seem to be mistaking the sum of the magnitudes of the individual momenta for the total momentum itself. The momentum of a material point is a vector quantity:

p = m.v

and the total momentum is the vector sum of all individual momenta:

P = ∑ mi.vi = m ∑ vi

(as in your case all masses are equal)

The kinetic energy is a scalar quantity:

K = (1/2) m.v2 = p2 / (2m)

and the total kinetic energy is again the sum of all individual kinetic energies:

K = ∑ (1/2) mi.vi2 = (m/2) ∑ vi2

In an elastic collision both K and P are conserved. This holds true in your example. Indeed, your balls' initial velocities are (2,0) and (0,0), therefore:

Pbefore = m * ((2,0) + (0,0)) = (2m, 0)

Kbefore = (m/2) * ((2,0).(2,0) + (0,0).(0,0)) = (m/2) * (4 + 0) = 2m

The final velocities are (1,1) and (1,-1), therefore:

Pafter = m * ((1,1) + (1,-1)) = (2m, 0)

Kafter = (m/2) * ((1,1).(1,1) + (1,-1).(1,-1)) = (m/2) * (2 + 2) = 2m

Obviously Pafter = Pbefore and Kafter = Kbefore.

Community
  • 1
  • 1
Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
  • Ohhhhhhhh... after thinking about it, what you're saying makes sense. But then what would you call the sum of the magnitudes of the individual momenta? My brain keeps wanting to believe that is the total kinetic engery (taking a physics course would probably help). – HypnoToad Feb 07 '14 at 04:01
  • The sum of the magnitudes bears no physical meaning that I am aware of. – Hristo Iliev Feb 09 '14 at 13:45
1

Instead of: float dotprod = Vector2.Dot(normal, b1.Velocity - b2.Velocity); Try this: Vector2 velocityDif = b1.Velocity - b2.Velocity; float dotprod = Vector2.Dot(normal, Vector2.Normalize(velocityDif));

Tamir Vered
  • 10,187
  • 5
  • 45
  • 57