Distance calculations

On a project I currently work on, we are doing a lot of distance calucations in javascript. I got really interested in the different formulas that was out there for distance calucation. The most commonly used is a formula called “the Haversine formula” but I also took a look at “the Cartesian coordinate system” for calculating distances between points in 3d space.

The haversine formula
The haversine formula has for long been used in sea-navigation to calculate a “great circle distance” between 2 coordinates on the planet.
Basically it’s a formula for calculating the distance between 2 points on a sphere by. The downside to the haversine formula is when you want really accurate distances between 2 points in a real terrain, since it doesn’t take the elevation into account, therefore I started to look at the cartesian formula;

The Cartesian coordinate system
There’s an Cartesian version of Pythagoras’ theorem to calculate distances between points in three-dimensional space which is interesting to use to try to measure “real distance” in terrains with high altitude differences. This formula is actually better if you move in a relatively small area on the globe but with high altitude differences.

When taking some testdata from a gps on a somewhat altered altitude track ( from 20 m.a.s to 100 m.a.s ) the two formulas differed around 400-800m on a 10,000m track. The Cartesian calculation came very close to the actual measured distance of the track (80-220m less) while the haversine formula usually gave a result further below the control distance.

Cartesian js example:

var cartesian = function(pointarray){
	/*
	The function expects an array of arrays with [long,lat,elevation] values
	*/
	var distance = 0;
	var legDistance;
	if(pointarray.length>1){
		for(var r = 0; r < pointarray.length; r++){

			var alt = 6370000 + pointarray[r][2]
			var x0 = alt * Math.cos( pointarray[r][1].toRad() ) * Math.sin(pointarray[r][0].toRad())
			var y0 = alt * Math.sin(pointarray[r][1].toRad())
			var z0 = alt * Math.cos(pointarray[r][1].toRad()) * Math.cos(pointarray[r][0].toRad())

			if(pointarray[r+1]){
				var alt2 = 6370000 + pointarray[r+1][2]
				var x1 = alt2 * Math.cos(pointarray[r+1][1].toRad()) * Math.sin(pointarray[r+1][0].toRad())
				var y1 = alt2 * Math.sin(pointarray[r+1][1].toRad())
				var z1 = alt2 * Math.cos(pointarray[r+1][1].toRad()) * Math.cos(pointarray[r+1][0].toRad())

				legDistance = Math.sqrt( Math.pow((x1-x0),2) + (Math.pow((y1-y0),2)) + Math.pow((z1-z0),2 ));

				if(!isNaN(legDistance)){
					distance+=legDistance;
				}

			}
		}
	}

	return distance;
}

Further reading:
Chris Veness have made a great set of js functions for doing haversine calucations with javascript, they can be found here.

Categories