40 lines
1.3 KiB
Text
40 lines
1.3 KiB
Text
module Main
|
|
|
|
-- The haversine of an angle.
|
|
hsin : Double -> Double
|
|
hsin t = let u = sin (t/2) in u*u
|
|
|
|
-- The distance between two points, given by latitude and longtitude, on a
|
|
-- circle. The points are specified in radians.
|
|
distRad : Double -> (Double, Double) -> (Double, Double) -> Double
|
|
distRad radius (lat1, lng1) (lat2, lng2) =
|
|
let hlat = hsin (lat2 - lat1)
|
|
hlng = hsin (lng2 - lng1)
|
|
root = sqrt (hlat + cos lat1 * cos lat2 * hlng)
|
|
in 2 * radius * asin (min 1.0 root)
|
|
|
|
-- The distance between two points, given by latitude and longtitude, on a
|
|
-- circle. The points are specified in degrees.
|
|
distDeg : Double -> (Double, Double) -> (Double, Double) -> Double
|
|
distDeg radius p1 p2 = distRad radius (deg2rad p1) (deg2rad p2)
|
|
where
|
|
d2r : Double -> Double
|
|
d2r t = t * pi / 180
|
|
deg2rad (t, u) = (d2r t, d2r u)
|
|
|
|
-- The approximate distance, in kilometers, between two points on Earth.
|
|
-- The latitude and longtitude are assumed to be in degrees.
|
|
earthDist : (Double, Double) -> (Double, Double) -> Double
|
|
earthDist = distDeg 6372.8
|
|
|
|
main : IO ()
|
|
main = putStrLn $ "The distance between BNA and LAX is about " ++ show (floor dst) ++ " km."
|
|
where
|
|
bna : (Double, Double)
|
|
bna = (36.12, -86.67)
|
|
|
|
lax : (Double, Double)
|
|
lax = (33.94, -118.40)
|
|
|
|
dst : Double
|
|
dst = earthDist bna lax
|