In this post, we will finally complete our pool game. We’ve already seen how to detect collisions between balls: we just need to check if two circles are overlapping. We’ve also seen how to resolve a collision when bouncing a ball off a wall (i.e. one moving object and one stationary). The final piece of the puzzle is just to put it all together in the case of two moving balls.
Bouncy Balls
The principle behind collision resolution for pool balls is as follows. You have a situation where two balls are colliding, and you know their velocities (step 1 in the diagram below). You separate out each ball’s velocity (the solid blue and green arrows in step 1, below) into two perpendicular components: the component heading towards the other ball (the dotted blue and green arrows in step 2) and the component that is perpendicular to the other ball (the dashed blue and green arrows in step 2).
This is the same principle as we used when colliding with a wall. The difference here is that while you still leave alone the components that are parallel, instead of reversing each ball’s component that heads towards the other ball, you swap the components between the two balls (as we move from step 2 to step 3), then finally recombine the velocities for each ball to leave the result (step 4):
This means that the code we need is actually only a small modification on the previous code for wall collision:
double towardsThem = distAlong(b.getMoveX(), b.getMoveY(), distX, distY); double towardsMe = distAlong(c.getMoveX(), c.getMoveY(), distX, distY); double myOrtho = distAlong(b.getMoveX(), b.getMoveY(), distY, -distX); double theirOrtho = distAlong(c.getMoveX(), c.getMoveY(), distY, -distX); b.setMove(towardsMe * distX + myOrtho * distY, towardsMe * distY + myOrtho * -distX); c.setMove(towardsThem * distX + theirOrtho * distY, towardsThem * distY + theirOrtho * -distX);
You can have a play with the relevant scenario over on the Greenfoot site.
Programming Challenge Task
The scenario needs a bit more work to make a finished game: interface polish, a second player (with two types of balls, and a black 8-ball) and scoring. Feel free to take the code and finish off the game.
Mathematical Challenge Task
The collision resolution is not as precise as it could be. Because it uses the destination position at the end of the frame for resolving the collision, two balls which move towards each quickly can potentially bounce off at a strange angle. This could be fixed by modelling a ball’s position as:
Where varies from 0 (at the start of the frame) to 1 (at the end). You can then find at which value of
the two balls collide (building on the circle collision work), and use these positions of the exact collision when resolving the collision. If you feel like a challenge, have a go at using that idea to improve the collision mechanism.
Leave a Reply