47 lines
1.2 KiB
Haskell
47 lines
1.2 KiB
Haskell
import Control.Monad (join)
|
|
import Data.Bifunctor (bimap)
|
|
import Text.Printf (printf)
|
|
|
|
-------------------- HAVERSINE FORMULA -------------------
|
|
|
|
-- The haversine of an angle.
|
|
haversine :: Float -> Float
|
|
haversine = (^ 2) . sin . (/ 2)
|
|
|
|
-- The approximate distance, in kilometers,
|
|
-- between two points on Earth.
|
|
-- The latitude and longtitude are assumed to be in degrees.
|
|
greatCircleDistance ::
|
|
(Float, Float) ->
|
|
(Float, Float) ->
|
|
Float
|
|
greatCircleDistance = distDeg 6371
|
|
where
|
|
distDeg radius p1 p2 =
|
|
distRad
|
|
radius
|
|
(deg2rad p1)
|
|
(deg2rad p2)
|
|
distRad radius (lat1, lng1) (lat2, lng2) =
|
|
(2 * radius)
|
|
* asin
|
|
( min
|
|
1.0
|
|
( sqrt $
|
|
haversine (lat2 - lat1)
|
|
+ ( (cos lat1 * cos lat2)
|
|
* haversine (lng2 - lng1)
|
|
)
|
|
)
|
|
)
|
|
deg2rad = join bimap ((/ 180) . (pi *))
|
|
|
|
--------------------------- TEST -------------------------
|
|
main :: IO ()
|
|
main =
|
|
printf
|
|
"The distance between BNA and LAX is about %0.f km.\n"
|
|
(greatCircleDistance bna lax)
|
|
where
|
|
bna = (36.12, -86.67)
|
|
lax = (33.94, -118.40)
|