Ball to Ball Collision – Detection and Handling

With the help of the Stack Overflow community I’ve written a pretty basic-but fun physics simulator.

alt text

You click and drag the mouse to launch a ball. It will bounce around and eventually stop on the “floor”.

My next big feature I want to add in is ball to ball collision. The ball’s movement is broken up into a x and y speed vector. I have gravity (small reduction of the y vector each step), I have friction (small reduction of both vectors each collision with a wall). The balls honestly move around in a surprisingly realistic way.

I guess my question has two parts:

  1. What is the best method to detect ball to ball collision?
    Do I just have an O(n^2) loop that iterates over each ball and checks every other ball to see if it’s radius overlaps?
  2. What equations do I use to handle the ball to ball collisions? Physics 101
    How does it effect the two balls speed x/y vectors? What is the resulting direction the two balls head off in? How do I apply this to each ball?

alt text

Handling the collision detection of the “walls” and the resulting vector changes were easy but I see more complications with ball-ball collisions. With walls I simply had to take the negative of the appropriate x or y vector and off it would go in the correct direction. With balls I don’t think it is that way.

Some quick clarifications: for simplicity I’m ok with a perfectly elastic collision for now, also all my balls have the same mass right now, but I might change that in the future.


Edit: Resources I have found useful

2d Ball physics with vectors: 2-Dimensional Collisions Without Trigonometry.pdf
2d Ball collision detection example: Adding Collision Detection


Success!

I have the ball collision detection and response working great!

Relevant code:

Collision Detection:

for (int i = 0; i < ballCount; i++)  
{  
    for (int j = i + 1; j < ballCount; j++)  
    {  
        if (balls[i].colliding(balls[j]))  
        {
            balls[i].resolveCollision(balls[j]);
        }
    }
}

This will check for collisions between every ball but skip redundant checks (if you have to check if ball 1 collides with ball 2 then you don’t need to check if ball 2 collides with ball 1. Also, it skips checking for collisions with itself).

Then, in my ball class I have my colliding() and resolveCollision() methods:

public boolean colliding(Ball ball)
{
    float xd = position.getX() - ball.position.getX();
    float yd = position.getY() - ball.position.getY();

    float sumRadius = getRadius() + ball.getRadius();
    float sqrRadius = sumRadius * sumRadius;

    float distSqr = (xd * xd) + (yd * yd);

    if (distSqr <= sqrRadius)
    {
        return true;
    }

    return false;
}

public void resolveCollision(Ball ball)
{
    // get the mtd
    Vector2d delta = (position.subtract(ball.position));
    float d = delta.getLength();
    // minimum translation distance to push balls apart after intersecting
    Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d); 


    // resolve intersection --
    // inverse mass quantities
    float im1 = 1 / getMass(); 
    float im2 = 1 / ball.getMass();

    // push-pull them apart based off their mass
    position = position.add(mtd.multiply(im1 / (im1 + im2)));
    ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));

    // impact speed
    Vector2d v = (this.velocity.subtract(ball.velocity));
    float vn = v.dot(mtd.normalize());

    // sphere intersecting but moving away from each other already
    if (vn > 0.0f) return;

    // collision impulse
    float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
    Vector2d impulse = mtd.normalize().multiply(i);

    // change in momentum
    this.velocity = this.velocity.add(impulse.multiply(im1));
    ball.velocity = ball.velocity.subtract(impulse.multiply(im2));

}

Source Code: Complete source for ball to ball collider.

If anyone has some suggestions for how to improve this basic physics simulator let me know! One thing I have yet to add is angular momentum so the balls will roll more realistically. Any other suggestions? Leave a comment!

15 Answers
15

Leave a Comment