Game Development Reference
In-Depth Information
//Calculate angular distance
float C = 2 * atan(sqrt(a)/sqrt(1-a));
//Find arclength
float distance = 6371 * C; //6371 is radius of earth in km
return distance;
}
One limitation of the preceding method is that if the two locations are nearly antipodal
—that is, on opposite sides of the earth—then the haversine formula may have round-
off issues that could results in errors on the order of 2 km. These, however, will be over
a distance of 20,000 km. If extreme accuracy is required for nearly antipodal coordinates,
you can fall back to the spherical law of cosines, which is best suited for large distances
such as the antipodal case.
As discussed before, to follow the shortest path between two points on a sphere you
must travel along a great circle. However, this requires that your heading be constantly
changing with time. The formula to calculate your initial heading, or forward azi‐
muth , is:
Θ i = atan2[sin(Δ long )cos(lat 2 ), cos(lat 1 )sin(lat 2 ) -
sin(lat 1 )cos(lat 2 )cos(Δ long )]
Recall that atan2 is the two-argument variation of the arctangent function. It returns
a normalized angle in radians between −π and π (−180° and 180°). The code that cal‐
culates the value and returns the compass bearing is as follows:
float initialBearing (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;
//Calculate deltas
float dLat = lat2 - lat1;
float dLon = lon2 - lon1;