I realise the code, variable names, etc, may not be entirely clear, and you may not know the theory I'm using, so here's an explanation.
First, we declare the ship properties - shipx and shipy for its starting position coordinates, shipr for its radius, and shipi and shipj for its velocity.
Next are the moon properties - moonx and moony for position and moonr for radius.
I'll explain the calculation variables as we meet them.
Then we get the values that are user set in this demo. The user isn't allowed to set shipi and shipj both to zero because that means that a) the ship isn't moving so the collision check is rather moot and b) you get a divide by zero.

The first actual calculation is finding the vector perpendicular to the ship's velocity vector. If you think about a line passing near to a point and draw a line from the point to the nearest point on the line, you'll realise the two lines are perpendicular. We need the closest distance between the two objects, so we need the length of the perpendicular vector from the point to the line. Finding the perpendicular vector is done by swapping the i and j values and making one negative. It doesn't matter which one is negative. These are saved to ppdi and ppdj, standing for perpendicular i and j.
Next, we display the ship's position vector and the perpendicular vector. This is a method of writing the vector for an object including its start position, where we give the position vector for its start point added to (a number) of its vector. The numbers are generally given random Greek letters; lambda and theta seem fairly standard. The Greek letter represents time; at time 0 the position is just its start position, at time one it's the start position plus one lot of the velocity, etc etc.
Next, as we know the two vectors intersect, we say that for some values of lambda and theta, the i component and the j component are equal. These are rearranged to get the unknown quantities on the left side and known quantities on the right. [shipi * lambda - ppdi * theta = moonx - shipx] and [shipj * lambda - ppdj * theta = moony - shipy] The right hand side is reduced to a single constant by doing the subtraction, [moonx - shipx] and [moony - shipy].
Since we need the theta term, ie, the length of the perpendicular vector to the ship's velocity vector, to find how close the ship approaches the planet, we solve the simultaneous equations multiply each equation through by the lambda coefficient of the other equation to get the lambda coefficients equal so that by subtracting the two equations the lambda value is removed. Note we don't do the multiplication for the lambda coefficients because we know they'll end up equal and be cancelled out.
The two equations are then subtracted from each other, resulting in a single equation containing a theta coefficient and a constant.
The constant is then divided by the theta coefficient to get theta.
We then find the length (magnitude) of the perpendicular vector by using Pythagoras' theorem. The two short sides are equal to theta multiplied by the i and j components of the vector.

We now know the distance from the centre of the ship to the centre of the moon at its closest point. Subtract the moon radius and the ship radius from that distance and we get the distance between the edges of the bounding circles of the ship and moon.
Then, simply check if that distance is less than or equal to 0. If the value is negative, they collide before reaching the cloeset point, and if it is 0 they just touch as they pass at the closest point. You could just use less than 0 and allow just touching, but I doubt you'd want to come quite that close to an object...

Simple as that. Back to main page