50 lines
1.1 KiB
Haskell
50 lines
1.1 KiB
Haskell
import Control.Monad (join)
|
|
import Data.Bifunctor (bimap)
|
|
import Text.Printf (printf)
|
|
|
|
type Radians = Float
|
|
|
|
type Degrees = Float
|
|
|
|
---------- ANGLE DIFFERENCE BETWEEN TWO BEARINGS ---------
|
|
|
|
bearingDelta :: (Radians, Radians) -> Radians
|
|
bearingDelta (a, b) -- sign * dot-product
|
|
=
|
|
sign * acos ((ax * bx) + (ay * by))
|
|
where
|
|
(ax, ay) = (sin a, cos a)
|
|
(bx, by) = (sin b, cos b)
|
|
sign
|
|
| ((ay * bx) - (by * ax)) > 0 = 1
|
|
| otherwise = -1
|
|
|
|
angleBetweenDegrees :: (Degrees, Degrees) -> Degrees
|
|
angleBetweenDegrees =
|
|
degrees
|
|
. bearingDelta
|
|
. join bimap radians
|
|
|
|
--------------------------- TEST -------------------------
|
|
main :: IO ()
|
|
main =
|
|
putStrLn . unlines $
|
|
fmap
|
|
( uncurry (printf "%6.2f° - %6.2f° -> %7.2f°")
|
|
<*> angleBetweenDegrees
|
|
)
|
|
[ (20.0, 45.0),
|
|
(-45.0, 45.0),
|
|
(-85.0, 90.0),
|
|
(-95.0, 90.0),
|
|
(-45.0, 125.0),
|
|
(-45.0, 145.0)
|
|
]
|
|
|
|
------------------------- GENERIC ------------------------
|
|
|
|
degrees :: Radians -> Degrees
|
|
degrees = (/ pi) . (180 *)
|
|
|
|
radians :: Degrees -> Radians
|
|
radians = (/ 180) . (pi *)
|