Taken from: http://www.movable-type.co.uk/scripts/latlong.html
Reproduced here just in case the original site goes down.
To be implemented in Java.
This uses the ‘Haversine’ formula to calculate great-circle distances between the two points – that is, the shortest distance over the earth’s surface – giving an ‘as-the-crow-flies’ distance between the points (ignoring any hills!).
| Haversine formula: | R = earth’s radius (mean radius = 6,371km) Δlat = lat2− lat1 Δlong = long2− long1 a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2) c = 2.atan2(√a, √(1−a)) d = R.c (Note that angles need to be in radians to pass to trig functions). |
| JavaScript: |
var R = 6371; // km var dLat = (lat2-lat1).toRad(); var dLon = (lon2-lon1).toRad(); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLon/2) * Math.sin(dLon/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; |
The Haversine formula ‘remains particularly well-conditioned for numerical computation even at small distances’ – unlike calculations based on the spherical law of cosines. (It was published by R W Sinnott in Sky and Telescope, 1984, though has been known about for much longer; the ‘half-versed-sine’ is (1-cosθ)/2, or sin²(θ/2) – don’t ask, I’m not a mathematician).
Spherical Law of Cosines
In fact, when Sinnott published the Haversine formula, computational precision was limited. Nowadays, JavaScript (and most modern computers & languages) use IEEE 754 64-bit floating-point numbers, which provide 15 significant figures of precision. With this precision, the simple spherical law of cosines formula gives well-conditioned results down to distances as small as around 1 metre. In view of this it is probably worth, in most situations, using either the simpler law of cosines or the more accurate ellipsoidal Vincenty formula in preference to Haversine! (bearing in mind notes below on the limitations in accuracy of the spherical model).
| Spherical law of cosines: |
d = acos(sin(lat1).sin(lat2)+cos(lat1).cos(lat2).cos(long2−long1)).R |
| JavaScript: |
var R = 6371; // km var d = Math.acos(Math.sin(lat1)*Math.sin(lat2) + Math.cos(lat1)*Math.cos(lat2) * Math.cos(lon2-lon1)) * R; |
| Excel: | =ACOS(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371 |
(Note that here and in all subsequent code fragments, for simplicity I do not show conversions from degrees to radians; see below for complete versions).
Comments
Leave a comment Trackback