Game Development Reference
In-Depth Information
large penalties are rarely encountered because ships have to alter course to avoid land!
This makes “as the crow flies” examples unrealistic.
If your game is providing navigation information to anyone but pilots, it will probably
be using rhumb lines. The following are the formulas used to calculate distance and
bearing between two coordinates on a rhumb line. The easiest way to begin is to flatten
the globe. In a Mercator projection, rhumb lines are straight. In fact, this makes graph‐
ically solving the problem very simple. You use a ruler. Mathematically, things get a bit
more complicated. The following equation gives Δφ, which is the difference in latitude
after taking into account that we have stretched them in order to flatten the sphere:
Δφ = ln[tan(lat2/2 + π/4) / tan(lat1/2 + π/4)]
The distance between two points on a rhumb line is given by:
D = Δ la 2 + q 2 * Δ lon 2 * R
The variable q is a value whose formula depends on Δφ. If Δφ is equal to 0, that means
that the calculated course is going to be either directly east or west. If that is the case,
then the intermediate value of q is:
q = cos(lat1)
if Δφ is not equal to 0, then:
q = Δ lat /Δφ
You can see that if not properly implemented, a direct east or west course would result
in division by 0. Finally, the constant bearing is:
Θ rhumb = atan2(Δ long , Δφ)
There are, in fact, an infinite number of rhumb lines that will get us to our end point.
However, the longer ones will either take us the wrong way around the globe, or spiral
around the globe before hitting our end point. At any rate, the shortest route will be the
one in which Δ long is less that 180°. The preceding is implemented in Objective-C as
follows:
float rhumbBearing ( Coordinate2D startPoint, Coordinate2D endPoint){
//Convert location from degrees to radians
float lat1 = (M_PI/180.) * startPoint.lat;
float lon1 = (M_PI/180.) * startPoint.longi;
float lat2 = (M_PI/180.) * endPoint.lat;
float lon2 = (M_PI/180.) * endPoint.longi;