How do I calculate the Azimuth (angle to north) between two WGS84 coordinates
The formulas that you refer to in the text are to calculate the great circle distance between 2 points. Here's how I calculate the angle between points:
uses Math, ...;
...
const
cNO_ANGLE=-999;
...
function getAngleBetweenPoints(X1,Y1,X2,Y2:double):double;
var
dx,dy:double;
begin
dx := X2 - X1;
dy := Y2 - Y1;
if (dx > 0) then result := (Pi*0.5) - ArcTan(dy/dx) else
if (dx < 0) then result := (Pi*1.5) - ArcTan(dy/dx) else
if (dy > 0) then result := 0 else
if (dy < 0) then result := Pi else
result := cNO_ANGLE; // the 2 points are equal
result := RadToDeg(result);
end;
Remember to handle the situation where 2 points are equal (check if the result equals cNO_ANGLE, or modify the function to throw an exception);
This function assumes that you're on a flat surface. With the small distances that you've mentioned this is all fine, but if you're going to be calculating the heading between cities all over the world you might want to look into something that takes the shape of the earth in count;
It's best to provide this function with coordinates that are already mapped to a flat surface. You could feed WGS84 Latitude directly into Y (and lon into X) to get a rough approximation though.
Here is the C# solution. Tested for 0, 45, 90, 135, 180, 225, 270 and 315 angles.
Edit I replaced my previous ugly solution, by the C# translation of Wouter's solution:
public double GetAzimuth(LatLng destination)
{
var longitudinalDifference = destination.Lng - this.Lng;
var latitudinalDifference = destination.Lat - this.Lat;
var azimuth = (Math.PI * .5d) - Math.Atan(latitudinalDifference / longitudinalDifference);
if (longitudinalDifference > 0) return azimuth;
else if (longitudinalDifference < 0) return azimuth + Math.PI;
else if (latitudinalDifference < 0) return Math.PI;
return 0d;
}
public double GetDegreesAzimuth(LatLng destination)
{
return RadiansToDegreesConversionFactor * GetAzimuth(destination);
}
I found this link
http://williams.best.vwh.net/avform.htm
given in the answer to
Lat/Lon + Distance + Heading --> Lat/Lon
This looks promising, especially the flat earth approximation given near the end.