{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Diagrams.Direction
( Direction
, _Dir
, direction, dir, fromDirection, fromDir
, angleBetweenDirs
, dirBetween
) where
import Control.Lens (Iso', iso)
import Diagrams.Angle
import Diagrams.Core
import Linear.Affine
import Linear.Metric
import Linear.Vector
newtype Direction v n = Dir (v n)
deriving (Read, Show, Eq, Ord, Functor)
type instance V (Direction v n) = v
type instance N (Direction v n) = n
instance (V (v n) ~ v, N (v n) ~ n, Transformable (v n)) => Transformable (Direction v n) where
transform t (Dir v) = Dir (transform t v)
instance HasTheta v => HasTheta (Direction v) where
_theta = _Dir . _theta
instance HasPhi v => HasPhi (Direction v) where
_phi = _Dir . _phi
_Dir :: Iso' (Direction v n) (v n)
_Dir = iso (\(Dir v) -> v) Dir
direction :: v n -> Direction v n
direction = Dir
dir :: v n -> Direction v n
dir = Dir
fromDirection :: (Metric v, Floating n) => Direction v n -> v n
fromDirection (Dir v) = signorm v
fromDir :: (Metric v, Floating n) => Direction v n -> v n
fromDir (Dir v) = signorm v
angleBetweenDirs :: (Metric v, Floating n, Ord n)
=> Direction v n -> Direction v n -> Angle n
angleBetweenDirs d1 d2 = angleBetween (fromDirection d1) (fromDirection d2)
dirBetween :: (Additive v, Num n) => Point v n -> Point v n -> Direction v n
dirBetween p q = dir $ q .-. p