aviation-navigation-0.1.0.0: src/Data/Aviation/Navigation/Vector.hs
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Aviation.Navigation.Vector(
Vector(..)
, vectorDegrees
, HasVector(..)
) where
import Control.Category ( Category(id, (.)) )
import Control.Lens ( view, Lens' )
import Data.Eq ( Eq )
import Data.Functor ( Functor(fmap) )
import Data.Monoid ( Monoid(mempty) )
import Data.Ord ( Ord )
import Data.Radian ( fromRadians )
import Data.Semigroup ( Semigroup((<>)) )
import GHC.Show(Show)
import Prelude(Double, Num((*), (-), (+)), Fractional((/)), sqrt, atan, sin, cos, pi)
data Vector =
Vector
Double -- angle
Double -- magnitude
deriving (Eq, Ord, Show)
vectorDegrees ::
Double
-> Double
-> Vector
vectorDegrees =
Vector . view fromRadians
instance Semigroup Vector where
Vector aa am <> Vector ba bm =
let square x = x * x
t = aa - ba
mag = sqrt (square am + square bm - 2 * am * bm * cos (pi - t))
ang = atan (bm * sin t / (am + bm * cos t))
in Vector (aa - ang) mag
instance Monoid Vector where
mempty =
Vector 0 0
class HasVector a where
vector ::
Lens' a Vector
{-# INLINE angle #-}
angle ::
Lens' a Double
angle =
vector . angle
{-# INLINE magnitude #-}
magnitude ::
Lens' a Double
magnitude =
vector . magnitude
instance HasVector Vector where
vector =
id
{-# INLINE angle #-}
angle f (Vector a m) =
fmap (\a' -> Vector a' m) (f a)
{-# INLINE magnitude #-}
magnitude f (Vector a m) =
fmap (\m' -> Vector a m') (f m)