Billiard simulation–part 3: collision between two balls

May 13, 2013 at 1:27 PMMichele Mottini

..or more formally: elastic collision of spheres in two dimensions.

Let’s start with a simple case: ball 1 moving with velocity \((\bar v_1, \bar w_2)\) hitting ball 2 at rest. To make things even easier ball 1 and ball 2 are aligned horizontally at the moment of impact – i.e.  they have the same \(y\) coordinate:


In our model (at the moment being at least) balls are not spinning, and there is no ball-ball friction, so the force between balls in such a collision is only along the horizontal line connecting their centers. This means that the vertical components of the velocities before and after the collision are the same:

$$ \bar{w}’_1 = \bar{w} $$

$$ \bar{w}’_2 = 0 $$

- where the primed values are the ones after the collision. The horizontal components of the velocities on the other hand are related by the ball-ball coefficient of restitution \(c\):

$$ \bar{v}’_2 - \bar{v}’_1 = c(\bar{v}_1 - \bar{v}_2) = c\bar{v}_1  $$

(\(\bar{v}_2\) is zero). The horizontal momentum must be the same before and after the collision:

$$ m_1\bar{v}’_1 + m_2\bar{v}’_2 = m_1\bar{v}_1 $$

- where \(m_1\) and \(m_2\) are the masses of the two balls. Combining these two equation gives:

$$ \bar{v}’_1 = \frac{m_1 – cm_2}{m_1+m_2}\bar{v}_1 $$

$$ \bar{v}’_2 = \frac{(1+c)m_1}{m_1+m_2}\bar{v}_1 $$

that is the result for this simple case: the velocities after the collision in terms of the (known) velocities before the collision.

What abut the general case in which both balls move and are not aligned?


This second case can be converted in the simple one with a coordinate transformation: subtract the velocity of the second ball from all velocities – i.e. use the frame of reference of the second ball - and rotate the axis by the angle \(\alpha\):

$$ \bar{v} = (v-v_2)\cos\alpha + (w-w_2)\sin\alpha $$

$$ \bar{w} = -(v-v_2)\sin\alpha + (w-w_2)\cos\alpha $$

where \((v, w)\) is an arbitrary velocity and \((\bar{v}, \bar{w})\) is the corresponding transformed velocity. The angle \(\alpha\) is*:

$$ \alpha = \arctan \frac{y_1– y_2}{x_1 – x_2} $$

where \((x_1, y_1)\) and \((x_2, y_2)\) are the positions of the two balls.

The inverse transformation is:

$$ v = \bar{v}\cos\alpha - \bar{w}\sin\alpha + v_2 $$

$$ w = \bar{v}\sin\alpha + \bar{w}\cos\alpha + w_2 $$

Now the procedure to solve the general case is: transform the original velocities in their ‘bar’ equivalent; apply the formula of the simple case; apply the inverse transformation to go back to the velocities in the original coordinate system (without ‘bar’). These steps produce the following results:

$$ v’_1 = \frac{1}{m_1+m_2}\Big[\big(m_1-m_2(c\cos^2\alpha-\sin^2\alpha)\big)(v_1-v_2)-(1+c)m_2\sin\alpha\cos\alpha(w_1-w_2)\Big]+v_2$$

$$ w’_1 = \frac{1}{m_1+m_2}\Big[-(1+c)m_2\sin\alpha\cos\alpha(v_1-v_2) + \big(m_1-m_2(c\sin^2\alpha-\cos^2\alpha)\big)(w_1-w_2)\Big]+w_2$$

$$ v’_2 = \frac{(1+c)m_1}{m_1+m_2}\cos\alpha\Big[(v_1-v_2)\cos\alpha + (w_1-w_2)\sin\alpha\Big] + v_2 $$

$$ w’_2 = \frac{(1+c)m_1}{m_1+m_2}\sin\alpha\Big[(v_1-v_2)\cos\alpha + (w_1-w_2)\sin\alpha\Big] + w_2 $$

The first two equations are quite unwieldy, but adding and subtracting \(v_1\) from the first one and \(w_1\) from the second one, and then doing some algebra produces:

$$ v’_1 = –m_2a\cos\alpha+ v_1 $$

$$ w’_1 = –m_2a\sin\alpha+ w_1 $$

$$ v’_2 = m_1a\cos\alpha+ v_2 $$

$$ w’_2 = m_1a\sin\alpha+ w_2 $$


$$ a = \frac{1+c}{m_1+m_2}\Big[(v_1-v_2)\cos\alpha + (w_1-w_2)\sin\alpha\Big] $$

A nice symmetric solution – and correct to boot.

Assuming that all the balls have the same density, their mass is a fixed constant times their radius cubed. In the formulas above the masses appear always as a quotient, so they can be replaced with the balls’ cubed radiuses.

The final code is this:

   * Updates the velocities of this ball and another one after a collision
   * The coordinate of the balls must be at the collision point.
   * @param otherBall second colliding ball
   * @param restitution coefficient of restitution for a ball-ball collision
  collide(otherBall: Ball, restitution: number) {
    var dx = this.x - otherBall.x;
    var dy = this.y - otherBall.y;
    var dv = this.v - otherBall.v;
    var dw = this.w - otherBall.w;
    var alpha = Math.atan2(dy, dx);
    var sinAlpha = Math.sin(alpha);
    var cosAlpha = Math.cos(alpha);
    var m1 = Math.pow(this.radius, 3);
    var m2 = Math.pow(otherBall.radius, 3);
    var a = (1 + restitution) / (m1 + m2) * (cosAlpha * dv + sinAlpha * dw);
    this.v = -m2 * a * cosAlpha + this.v;
    this.w = -m2 * a * sinAlpha + this.w;
    otherBall.v = m1 * a * cosAlpha + otherBall.v;
    otherBall.w = m1 * a * sinAlpha + otherBall.w;
  } // collide



(*) That ‘naïve’ formula for \(\alpha\) does not work when \(x_1-x_2\) is zero, nor it handles the various possible combination of signs of the numerator and denominator, but in the code all that is handled by Math.atan2().

Posted in: Physics | Programming

Tags: , , ,

Add comment

  Country flag

  • Comment
  • Preview