Ball collisions in terms of vector components (1 Viewer)

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

I'm writing a pool simulation program and have an awful problem with my ball collisions (elastic collisions).
The theory (in terms of vectors) is that when two balls collide you take the line between their centers and the velocity components which are perpendicular to this line are unaffected, while the parallel ones are calculated from the formula:
v '_{1} = \frac{2m _{2}v _{2}-v _{1}(m _{2} -m _{1}) }{m _{1}+m _{2} }

v '_{2} = \frac{2m _{1}v _{1}-v _{2}(m _{1} -m _{2}) }{m _{1}+m _{2} }
What I do is when I find that the balls are in touch I find a vector which is the line joining the centers. I then find the polar angle (in radians).
I then premultiply the velocity vectors by the (counter-clockwise) rotation matrix:
1st row(cos(angle) sin(angle))
2nd row(-sin(angle) cos(angle))
Then I take the x components (which are now the components parallel to the line joining centers?) And apply the formulas given above. Now I have new x components in the new basis and the old y components in the new basis.
So I rotate everything back and I should get the right velocity components?
The simulation looks ok, it even works fine for a head-on collision. But When I print out the balls velocities I find that the momentum wasn't conserved. Eg. balls of same mass, one ball is initially stationary, other going at 80pix/s:
After collision I find that the velocity magnitudes are 77 and 19
That's way too much.

Can anyone find the error? I'm pretty sure my code if fine, especially because I also calculated it on the calculator and got a meaningless result.
Can anyone find the error? I'm pretty sure my code if fine, especially because I also calculated it on the calculator and got a meaningless result.
So your calculated result is wrong too? If so, then you don't properly understand the physics. This is a two dimensional problem, so you should find that momentum is conserved; that is, the x- and y-components of the total momentum before the collision should be the same as after the collision.

Here's a link to a decent diagram at the bottom of the page that shows a similar scenario to yours: [Broken]
Last edited by a moderator:
I was asking what i'm doing wrong. I do undestand that momentum is coserved but if you apply the laws I had given it must be. I'm probably doing something wrong with the rotation of vectors...
Sorry, yes you did say momentum is conserved already.

Test a simple scenario where the angle between two centers is 0 degrees. This reduces the problem to one dimension. Is momentum conserved? You could also try a 90 degree angle; this isn't possible physically but you can analyze it mathematically. You should find that the momentum of the incoming ball in the x-direction is equal to the sum of the momentum of the other balls in the y-direction (there is no x-direction motion after collision).
Last edited:
I don't care if it works for simple cases. I need to make it to work in all cases. When The collision is not that simple the math fails.
Yes, I understand that you want it work in all cases. My point is that if your hand calculations are correct for the simple cases, but not for the program, then it will be easier to find out what the problem is in the program. If your hand calculations don't work out right, then review your solutions to this physics problem.
I don't really understand what you are trying to say. It doesn't matter if I perform the calculation by hand or in the program, if it is a more advanced case my method fails. I really suspect it has something to do with the rotation matrices...
Okay, let me show you. First, refer to the the wikipedia page and the "the average of the momenta before and after the collision is the same for both particles" diagram:

Let's assume the collision is head on (angle between centers equals zero) and that the target ball is at rest. This now becomes a 1-dimensional problem. Then as in the diagram, we should see that all of the momentum is transferred to the second ball. More specifically, after the collision, the velocity of the target ball is the same the initial velocity of the Q-ball, and the Q-ball is now at rest. So we have the following:

Before the collision: v1 = k (constant), v2 = 0
After collision: v1' = 0 and v2' = k (constant)

Now, look at your first two given equations. Note that the masses are the same, so we will use m = m1 = m2. For the first equation we have, v1' = 0, which is correct. For the second equation, we have v2' = v1 = k, which is correct. So these equations are not the problem. Continue this process with your hand calculations by doing the rotations with angle = 0. You should find that the answers remain the same.

Can your program mimic this simple result? If not add an output statement for each calculation in the algorithm and compare to your hand calculation to find the problem in the code.

I recommended starting with the easiest cases first because it is easier to find the problem.

EDIT: Sorry, I just saw that you said it works find for a head on collision.
Last edited:
Yeah, my problem has the output. My had calculations are always like the program's. They work in the simple cases, in others they don't. I've really been trying to find this problem for as long as I've been writing the whole program. i'm just not good enough with the vectors.
The program is not the problem, I just don't know how to do it correctly even on paper.
Tell me the angle between the centers when you got 77 and 19 pixels per second?
Sorry I don't remember that one. Now I did a different case. Initial velocities 80 & 0.
After 79 and 12. Angle in radians: -2.99. [roughly]
The program performs the calculations correctly, just as I do with a calculator. The methos with the roattion matrix I'm trying to use simply doesn't seem to work
Angle in radians: -2.99. [roughly]
This result is interesting. Before the Q-ball is hit, draw a straight line through the two centers of the balls. Now at the point of contact, draw a line between the two centers again. Let the positive x-axis be to the immediate right of the target ball. Is this angle, the angle from the positive x-axis going clockwise to the slanted line?


Last edited:
Yes, I can work out the angles, I have problems with formulating an expression how to get the new velocities with these angles.
You have the right idea it looks like. At the point of contact, you want to redefine the initial momentum vector of the Q-ball so that the two components are now normal (perpendicular) and parallel to the surface; this is your new reference frame. It appears that you do this. Since the masses are equal, the angle between the balls after the collision is always a right angle.
I don't think that's what I get in the end though. I think that when I rotate and calculate the new components everything is fine, but later when I try to rerotate I mess up.
I'll post my code maybe you'll understand that I'm doing.
Line between centers is in the direction of the A ball.
And if you don't know java, its easy to make out what i'm doing. Math.sin is just a sin.
A.getVel.getX is just the x component of A's velocity and so on...
/// Method for collision of two balls- sets their' new velocities
	public static void Collide(Ball A, Ball B){
		Vector2d joining = LineBetweenCentres(A, B);
		System.out.println(joining.GetX() + "  " +joining.GetY() + "  "+ joining.magnitude());
		/// angle is the angle of line joining centres in terms of polar coordinates
		double angle = Math.atan2(joining.GetY(), joining.GetX());
		/// rotate the system of coordinates so that fixed velocities vector's x component is parallel to the line joining centres
		double AvelXrotated = A.GetVel().GetX()*Math.cos(angle) + A.GetVel().GetY()*Math.sin(angle);
		double AvelYrotated = -A.GetVel().GetX()*Math.sin(angle) + A.GetVel().GetY()*Math.cos(angle);
		double BvelXrotated = B.GetVel().GetX()*Math.cos(angle) + B.GetVel().GetY()*Math.sin(angle);
		double BvelYrotated = -B.GetVel().GetX()*Math.sin(angle) + B.GetVel().GetY()*Math.cos(angle);
		/// perpendicular (y) velocity components are not affected, the new (x) components (in terms of new basis) are calculated:
		double AvelXnew = (2.0*B.GetMass()*BvelXrotated - AvelXrotated*(B.GetMass() - A.GetMass()))/(A.GetMass() + B.GetMass());
		double BvelXnew = (2.0*A.GetMass()*AvelXrotated - BvelXrotated*(A.GetMass() - B.GetMass()))/(A.GetMass() + B.GetMass());
		/// now the vectors need to be rotated back to the standard basis:
		double AvelXrerotated = AvelXnew*Math.cos(angle) - AvelYrotated*Math.sin(angle);
		double AvelYrerotated = AvelXnew*Math.sin(angle) + AvelYrotated*Math.cos(angle);
		double BvelXrerotated = BvelXnew*Math.cos(angle) - BvelYrotated*Math.sin(angle);
		double BvelYrerotated = BvelXnew*Math.sin(angle) + BvelYrotated*Math.cos(angle);
		/// set the new velocity components to the balls
		A.SetVelocity(AvelXrerotated, AvelYrerotated);
		B.SetVelocity(BvelXrerotated, BvelYrerotated);
Have you done any hand calculations besides the simple cases? Were they successful in obeying momentum conservation (or velocity conservation in this case, since both masses are equal)? I guess velocity conservation will depend on where you apply frictional losses in the code. You can always turn off the friction coefficient until you figure out where the problem is.

If so, just put the following code after every defined variable. This will pinpoint it exactly.

EDIT: If you find that all outputs match each step of your hand calculations and that momentum is not conserved, then you probably determined some angle incorrectly.
Last edited:

The Physics Forums Way

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving