Skip to content

Instantly share code, notes, and snippets.

@kevinadi
Created May 25, 2016 02:06
Show Gist options
  • Save kevinadi/e1f72b8d026901f11e6159d1ee38f218 to your computer and use it in GitHub Desktop.
Save kevinadi/e1f72b8d026901f11e6159d1ee38f218 to your computer and use it in GitHub Desktop.
Distance between two points on a great circle
-- Calculates distances between two points (a,b) and (x,y) on a great circle with radius r
-- Coordinates are in the form of (longitude,latitude)
--
-- Example: calculate distance between points (0,0) and (1,1) on earth:
-- ghci> geodist 6378.1 0 0 1 1
-- 157.42462387232553
--
-- Result should be identical to MongoDB's $geoNear
--
-- Formula was taken from http://andrew.hedges.name/experiments/haversine/
geodist r a b x y = let
rad x = pi * x / 180
a' x y a b = (sin ((b-y)/2))^2 + cos y * cos b * (sin ((a-x)/2))^2
d' r x y a b = r * 2 * atan2 (sqrt (a' x y a b)) (sqrt (1 - (a' x y a b)))
in d' r (rad x) (rad y) (rad a) (rad b)
@kevinadi
Copy link
Author

Scala version:

def geodist(R:Double, x:Double, y:Double, a:Double, b:Double) = {
    import Math._

    def A(x:Double, y:Double, a:Double, b:Double) =
        pow(sin ((b-y)/2), 2) + cos (y) * cos (b) * pow(sin ((a-x)/2), 2)

    def D(R:Double, x:Double, y:Double, a:Double, b:Double) =
        R * 2 * atan2 (sqrt (A (x, y, a, b)), sqrt (1 - (A (x, y, a, b))))

    D(R, x.toRadians, y.toRadians, a.toRadians, b.toRadians)
}

@kevinadi
Copy link
Author

Javascript version:

function geodist(R, x, y, a, b) {

    function rad(x) {
        return Math.PI * x / 180
    }

    function A(x, y, a, b) {
        return Math.pow(Math.sin ((b-y)/2), 2) + Math.cos (y) * Math.cos (b) * Math.pow(Math.sin ((a-x)/2), 2)
    }

    function D(R, x, y, a, b) {
        return R * 2 * Math.atan2 (Math.sqrt (A (x, y, a, b)), Math.sqrt (1 - (A (x, y, a, b))))
    }

    return D(R, rad(x), rad(y), rad(a), rad(b))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment