module Graphics.FieldTrip.Vector2
(
Vector2(..), vector2
, vector2x, vector2y
, xVector2, yVector2
, vector2Polar
, vector2PolarCoords
, vector2D, unvector2D
) where
import Control.Applicative
import Graphics.Rendering.OpenGL.GL.CoordTrans (Vector2(..))
import Data.VectorSpace
import Data.MemoTrie
import Data.Basis
import Data.Derivative
import Data.Cross
vector2 :: s -> s -> Vector2 s
vector2 = Vector2
xVector2 :: Num s => Vector2 s
xVector2 = Vector2 1 0
yVector2 :: Num s => Vector2 s
yVector2 = Vector2 0 1
vector2x, vector2y :: Vector2 s -> s
vector2x (Vector2 x _) = x
vector2y (Vector2 _ y) = y
vector2Polar :: Floating s => s -> s -> Vector2 s
vector2Polar rho theta = Vector2 (rho * cos theta) (rho * sin theta)
vector2PolarCoords :: (InnerSpace s, Floating s, Scalar s ~ s)
=> Vector2 s -> (s,s)
vector2PolarCoords v@(Vector2 x y) = (rho, theta)
where
rho = magnitude v
theta = atan (y/x)
instance Functor Vector2 where
fmap f (Vector2 x y) = Vector2 (f x) (f y)
instance Applicative Vector2 where
pure x = Vector2 x x
Vector2 f g <*> Vector2 x y = Vector2 (f x) (g y)
instance AdditiveGroup u => AdditiveGroup (Vector2 u) where
zeroV = Vector2 zeroV zeroV
Vector2 u v ^+^ Vector2 u' v' = Vector2 (u^+^u') (v^+^v')
negateV (Vector2 u v) = Vector2 (negateV u) (negateV v)
instance (VectorSpace u) => VectorSpace (Vector2 u) where
type Scalar (Vector2 u) = Scalar u
s *^ Vector2 u v = Vector2 (s*^u) (s*^v)
instance (InnerSpace u, AdditiveGroup (Scalar u))
=> InnerSpace (Vector2 u) where
Vector2 u v <.> Vector2 u' v' = u<.>u' ^+^ v<.>v'
instance HasBasis u => HasBasis (Vector2 u) where
type Basis (Vector2 u) = Basis (u,u)
basisValue = toV2 . basisValue
decompose = decompose . fromV2
decompose' = decompose' . fromV2
toV2 :: (u,u) -> Vector2 u
toV2 (u,v) = Vector2 u v
fromV2 :: Vector2 u -> (u,u)
fromV2 (Vector2 u v) = (u,v)
instance Num s => HasCross2 (Vector2 s) where
cross2 (Vector2 x y) = Vector2 (y) x
instance HasNormal (Float :> Vector2 Float) where
normalVec v = cross2 (derivative v `untrie` ())
vector2D :: (HasBasis a, HasTrie (Basis a), VectorSpace s) =>
Two (a :> s) -> a :> (Vector2 s)
vector2D (u,v) = liftD2 Vector2 u v
unvector2D :: (HasBasis a, HasTrie (Basis a), VectorSpace s) =>
a :> (Vector2 s) -> Two (a :> s)
unvector2D d = (vector2x <$>> d, vector2y <$>> d)