tags:

views:

120

answers:

3
public static double Distance(LatLong from, LatLong to)
{
    double lat1 = from.Latitude * (Math.PI / 180.0);
    double lat2 = to.Latitude * (Math.PI / 180.0);

    return
        Math.Acos((Math.Sin(lat1) * Math.Sin(lat2)) +
        (Math.Cos(lat1) * Math.Cos(lat2) *
        Math.Cos((Math.PI / 180.0) * (to.Longitude - from.Longitude)))) * 3958.760;
}

Can you shorten this code any stretch? I'm just wondering ...

+2  A: 

That's the standard spherical law of cosines formula. You won't get it any simpler than that. At best, you could clean up the code a little:

public static double Distance(LatLong from, LatLong to)
{
    double lat1 = Math.PI/180.0*from.Latitude;
    double lat2 = Math.PI/180.0*to.Latitude;
    double dLng = Math.PI/180.0*(to.Longitude - from.Longitude);
    double R = 3958.760;

    return Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) +
                     Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(dLng)) * R;
}
Marcelo Cantos
Nice reworking of the algorithm implementation in a way that makes its intention much more clear.
Michael Petrotta
A: 

The formula looks like it is computing the distance along the surface of a sphere, and would thus be reasonably accurate even for points that were practically on opposite sides of the world. If the distances will be very close together, you could approximate it by projecting the points onto the surface of a cylinder (coaxial with the Earth) passing through one of the points; scale the cylinder so north/south and east/west distances on the cylinder match those on the Earth. This will simply require taking the cosine of one of the latitudes. Note that if the points are far enough apart that it matters which point's latitude you use, they are too far apart for this to be a good approximation, but for small distances this approach is quick and easy.

Note, btw, that something like a conical projection will be accurate over wider distances, but will also require more calculation; if one is going to that much trouble, one may as well use the 'right' calculations.

supercat
A: 

No, but I can offer a shorter, faster way, but far less accurate way to obtain relative distances:

public static double RelativeDistance(LatLong from, LatLong to)
{
  return (from.Latitude - to.Latitude) * (from.Latitude - to.Latitude) + (from.Longitude - to.Longitude) * (from.Longitude - to.Longitude);
}

This returns a value relative to the square of the distance in terms of the projection of coordinates unto a square 2D grid (as if the world were a 2:1 rectangle). It's so useless for real distances that I wouldn't even bother to take a square root to bring it back to being proportional to the projection (since the projection is silly), but what it can serve for is rapidly sorting by relative distances within such a small area (and far enough from the poles) that the gross inaccuracy doesn't matter much.

Hence, it won't help you calculate your fuel costs, but it will help you work out which pub is (probably) nearest. If you wanted to sort by relative distance to a given point, it could serve well and its speed be a boon. Outside of that use, it's pointless.

Jon Hanna