1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Ball collisions in terms of vector components

  1. Mar 17, 2009 #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.
  2. jcsd
  3. Mar 17, 2009 #2
    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: http://people.sc.fsu.edu/~dduke/manual/collisions.htm [Broken]
    Last edited by a moderator: May 4, 2017
  4. Mar 18, 2009 #3
    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...
  5. Mar 18, 2009 #4
    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: Mar 18, 2009
  6. Mar 18, 2009 #5
    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.
  7. Mar 18, 2009 #6
    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.
  8. Mar 18, 2009 #7
    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...
  9. Mar 18, 2009 #8
    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: http://en.wikipedia.org/wiki/Elastic_collision.

    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: Mar 18, 2009
  10. Mar 18, 2009 #9
    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.
  11. Mar 18, 2009 #10
    Tell me the angle between the centers when you got 77 and 19 pixels per second?
  12. Mar 18, 2009 #11
    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
  13. Mar 18, 2009 #12
    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?
  14. Mar 18, 2009 #13

    Attached Files:

    Last edited: Mar 18, 2009
  15. Mar 18, 2009 #14
    Yes, I can work out the angles, I have problems with formulating an expression how to get the new velocities with these angles.
  16. Mar 18, 2009 #15
    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.
  17. Mar 18, 2009 #16
    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...
    Code (Text):

    /// 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);

  18. Mar 19, 2009 #17
    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: Mar 19, 2009
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook