Distance measurement between latitude/longiture pairs.

I need to calculate the distance between two lat/lng coordinate pairs. In addition, If given an initial lat/lng coordinate, angle of travel, and distance, I need to calculate the resulting lat/lng coordinate.

• $f(lat1, lng1, lat2, lng2) = what (angle, distance)$
• $f(lat1, lng1, angle, distance) = what (lat1, lng1)$

I come from a programming background so please bear with my lack of exposure to math notation.

Here is a jsfiddle which appears to work: as you can see, I tested it by feeding the output of one function into the other. The azimuth ("angle" in your notation) is calculated as described in Wikipedia. The second function assumes that the trajectory of motion is an arc of a great circle (aka geodesic, aka shortest path on the sphere). In particular, this means that starting in London and going initially to the east (azimuth 90 degrees), you will actually be going southeast soon. If one maintained constant azimuth during the travel, the resulting trajectory would not be a geodesic but a loxodromic curve.

In case something happens to jsfiddle, here is the code. (By the way, I am sure that this particular problem has been solved many times, in various languages and in better ways than I did here.)

function f(lat1, lng1, lat2, lng2) {
var Lat1 = lat1 * Math.PI / 180;
var Lng1 = lng1 * Math.PI / 180;
var Lat2 = lat2 * Math.PI / 180;
var Lng2 = lng2 * Math.PI / 180;
// find cartesian coordinates
var x1 = Math.cos(Lat1) * Math.cos(Lng1);
var y1 = Math.cos(Lat1) * Math.sin(Lng1);
var z1 = Math.sin(Lat1);
var x2 = Math.cos(Lat2) * Math.cos(Lng2);
var y2 = Math.cos(Lat2) * Math.sin(Lng2);
var z2 = Math.sin(Lat2);
// vector from initial to terminal point
var xv = x2 - x1;
var yv = y2 - y1;
var zv = z2 - z1;
// distance
var distanceChordal = Math.sqrt(xv * xv + yv * yv + zv * zv);
var distance = 2 * Math.asin(distanceChordal / 2);
// magic formula for azimuth from  http://en.wikipedia.org/wiki/Azimuth
var Azimuth = Math.atan(Math.sin(Lng2 - Lng1) / (Math.cos(Lat1) * Math.tan(Lat2) - Math.sin(Lat1) * Math.cos(Lng2 - Lng1)));
if (lat2 < lat1) {
Azimuth = Azimuth + Math.PI;
}
// output
var azimuth = Azimuth * 180 / Math.PI;
document.write("<p>From latitude ", lat1, " and longitude ", lng1, ", to latitude ", lat2, " and longitude ", lng2, ":</p>");
document.write("<p>Distance is ", distance, " (times the radius). Azimuth is ", azimuth, " degrees.</p><hr>");
}

function g(lat1, lng1, azimuth, distance) {
var Lat1 = lat1 * Math.PI / 180;
var Lng1 = lng1 * Math.PI / 180;
var Azimuth = azimuth * Math.PI / 180;
// find cartesian coordinates
var x1 = Math.cos(Lat1) * Math.cos(Lng1);
var y1 = Math.cos(Lat1) * Math.sin(Lng1);
var z1 = Math.sin(Lat1);
// unit vectors pointing East and North
var xEast = -y1 / Math.sqrt(x1 * x1 + y1 * y1);
var yEast = x1 / Math.sqrt(x1 * x1 + y1 * y1);
var zEast = 0;
var xNorth = -x1 * z1 / Math.sqrt(x1 * x1 + y1 * y1);
var yNorth = -y1 * z1 / Math.sqrt(x1 * x1 + y1 * y1);
var zNorth = Math.sqrt(x1 * x1 + y1 * y1);
// unit vector with the given azimuth angle
var xv = xNorth * Math.cos(Azimuth) + xEast * Math.sin(Azimuth);
var yv = yNorth * Math.cos(Azimuth) + yEast * Math.sin(Azimuth);
var zv = zNorth * Math.cos(Azimuth) + zEast * Math.sin(Azimuth);
// terminal point in Cartesian coordinates
var x2 = x1 * Math.cos(distance) + xv * Math.sin(distance);
var y2 = y1 * Math.cos(distance) + yv * Math.sin(distance);
var z2 = z1 * Math.cos(distance) + zv * Math.sin(distance);
// terminal point in spherical coordinates
var lat2 = Math.asin(z2) * 180 / Math.PI;
var lng2 = Math.atan2(y2, x2) * 180 / Math.PI;
// output
document.write("<p>From latitude ", lat1, " and longitude ", lng1, ", starting with azimuth ", azimuth, " and going for distance ", distance, " (times the radius):</p>");
document.write("<p>New latitude is ", lat2, " degrees. New longitude is ", lng2, " degrees.</p>");
}

f(24, 53, -55, 30);
g(24, 53, 193, 1.42);