Simple 2d billard physics: when 2 balls collide

Started by
7 comments, last by VanKurt 14 years, 4 months ago
Hi guys! I'm stuck on a very simple problem which makes me quite angry ;-) Imagine a 2D world with two colliding balls, like in the billards game. These balls are given as: Vector2 position; Vecttor2 velocity; Now after detecting a collision, I'd like to apply the proper collision response. What I do so far is: 1. Calculate the collison-normal (is it called like this?) between the balls 2. Reflect each balls velocity at this normal In many cases this looks right, but there are also cases where this approach completely fails (e.g. when both balls are moving in the same direction). So I started reading all kinds of articles on inelastic collisions but got only more confused. I guess physic's arent't my thing :-( So here's my question to you: How would I do the collision response corretly? A simple solution would be much appreciated! ;-) (BTW: I'm doing this in C#)
Advertisement
well, what you are trying to achieve here is elastic collision(in which energy and momentum is conserved) and not an inelastic one(just the opposite).
so IF YOUR BALLS ARE OF SAME SIZE(which is the case in billiards), you have to exchange the velocity among the colliding balls and not reflect them along the collision normal.
like you have ball A moving at velocity VA and ball B at VB, then instead of making A move at -VA and B at -VB, make A move at +VB and B at +VA...
this should solve your problem i guess. if you have to collide balls of different sizes, then formulas for collisions have to be used.
Hi Antzy, thanks a lot. Your approach works fine :-)

But now I have another question (if I may?):
What, if one of the balls is moved by hand, while the other one is rolling around on his own? Let's say during collision the ball in your hand is fixed, so it is used like a bat. Now all the force (of both balls) would go into the free-roaming ball.

What would be the right way to approach this?
I think one way to handle this is to give the fixed ball infinite mass.
Maybe this old thread can help you : http://www.gamedev.net/community/forums/topic.asp?topic_id=390861
In the last post, i decribe how i handle the collision of two balls.
Hi guys!
I'm still working on this problem... here's what I got so far:

Vector2 batToPuk = puk.pos - bat.pos;       // Vector from bat to pukVector2 batToPukN = new Vector2(batToPuk);  // Normalized vector from bat to pukbatToPukN.Normalize();// Now project velocities onto normalVector2 pukVelProjected = batToPukN * pos.velocity.dot(batToPukN);Vector2 batVelProjected = batToPukN * bat.velocity.dot(batToPukN);// Modify velocitiespuk.velocity += batVelProjected;bat.velocity += pukVelProjected;


This code gets the velocities of puk and bat along the distance vector, and then exchanges these components.
What do you think? So far so good?
Now the only thing left to do is make the bat fixed, and put all the force into the puk. I can't seem to get that working tho :-(

Any help is appreciated!
I think it cannot work that way. I don't know where this "exchange velocity along normal" method comes from but it is physically wrong : energy of the system is not conserved.
Try this with one ball with zero velocity and the other one striking it in a straight way, you will see that at the end of the collision you will have twice as much energy in the system as before the collision. :-/
I took that idea from this page:
http://www.billardgl.de/technik_physik-de.html (It's in German, but has lots of images)
It describes a billard game, so I thought it would be physically correct...

This is driving me SOOO nuts. I just spent another afternoon trying stuff and getting only crappy results. How hard can this be??? :-(

BTW: I also took a look at your code, but didn't completely understand what you are doing there.
Your formula was: VA = vA + (f/MA).AB
As far as I can see the new vector is the old vector + a scalar value? I'm a little confused...
Quote:Original post by VanKurt
I took that idea from this page:
http://www.billardgl.de/technik_physik-de.html (It's in German, but has lots of images)
It describes a billard game, so I thought it would be physically correct...


What is described on this page is correct, but it is not what is in the program you have posted. ;-)

Quote:Original post by VanKurt
BTW: I also took a look at your code, but didn't completely understand what you are doing there.
Your formula was: VA = vA + (f/MA).AB
As far as I can see the new vector is the old vector + a scalar value? I'm a little confused...


I agree, the notation i used is very confusing.
(f/MA).AB is not a scalar.
(f/MA) is a scalar, AB is a vector, so the result is a vector.

Anyway, to be as described in my post or as in the webpage you mentioned, your code should be something like :

Vector2 batToPuk = puk.pos - bat.pos;       // Vector from bat to pukVector2 batToPukN = new Vector2(batToPuk);  // Normalized vector from bat to pukbatToPukN.Normalize();// Now project velocities onto normalVector2 velDiff = puk.velocity - bat.velocity;Vector2 velDiffProjected = batToPukN * velDiff.dot(batToPukN);// Modify velocitiespuk.velocity -= velDiffProjected;bat.velocity += velDiffProjected;


and in the case where the "bat" is fixed, i think it is enough to replace the last lines with :
// Modify velocitiespuk.velocity -= 2 * velDiffProjected;


This has not been tested, there could be a sign error somewhere.
Great, thanks for your patience. With your help I got it working now.
Awesome! :-D

This topic is closed to new replies.

Advertisement