Learning and Applying Mathematics using Computing

Rack ‘Em Up

In recent posts, we’ve been building a pool game. One aspect of pool that we need to implement is positioning the balls for the start. There are fifteen balls to line up in a tightly packed triangle. But to actually put down this triangle in a program, we need to know the exact coordinates of the balls! And it turns out, this needs some maths too.

Rows

You can think of the triangle of balls as being a series of rows, each with one ball more than the last:

Each ball in a left-hand row has two balls behind it in the right-hand row. The gap between the balls on the right must align with the centre of the ball on the left (the dotted line below), and the balls nestle so close that the distance between each pair must be the same (the solid line below):

We can now start labelling the distances on this diagram. If the balls exactly touched then the distance between the two centres would be two times the ball radius. But due to the way our collision detection will work, it’s best if the balls don’t completely touch, but instead have a small gap. So we’ll define \text{radiusPlus} to be slightly bigger than the ball radius, which will give us this gap. Then:

So we know the vertical distances between the centres. All we need now is the horizontal distance (i.e. the length of the dashed line above). This is actually just a case for Pythagoras:

\text{horizDist}^2 + \text{radiusPlus}^2 = (2 \times \text{radiusPlus})^2
\text{horizDist}^2 + \text{radiusPlus}^2 = 4 \times \text{radiusPlus}^2
\text{horizDist}^2  = 3 \times \text{radiusPlus}^2
\text{horizDist}  = \sqrt{3} \times \text{radiusPlus}

Here’s the code:

        final int radiusPlus = 25 + 2; //radius + 2
        for (int row = 0; row < 5; row++)
        {
            int startY = 300 - row * radiusPlus; // Each row starts radiusPlus further up
            int x = 500 + (int)(row * (Math.sqrt(3) * (double)radiusPlus));
            for (int ball = 0; ball < row + 1; ball++)
            {
                addObject(new PoolBall(Color.RED), x, startY + ball * (2 * radiusPlus));
                // Each ball in a row is 2*radiusPlus further down ^^
            }
        }

This gives the finished layout:

I haven’t uploaded the scenario because it’s only the small bit of code above that has been added. Next time we’ll look at adding collision detection and collision resolution.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s