{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}
{-# LANGUAGE ExistentialQuantification, MultiParamTypeClasses, FlexibleInstances, StandaloneDeriving #-}
module Data.Vector2 (
Vector2,
vector2,
vector2X,
vector2Y,
vector2XY,
vector2Polar,
vector2Rho,
vector2Theta,
vector2RhoTheta,
vector2Rotate
) where
import Control.DeepSeq (NFData(..))
import Data.VectorSpace
data Vector2 a = RealFloat a => Vector2 !a !a
deriving instance Eq a => Eq (Vector2 a)
deriving instance Show a => Show (Vector2 a)
instance NFData a => NFData (Vector2 a) where
rnf (Vector2 x y) = rnf x `seq` rnf y `seq` ()
vector2 :: RealFloat a => a -> a -> Vector2 a
vector2 = Vector2
vector2X :: RealFloat a => Vector2 a -> a
vector2X (Vector2 x _) = x
vector2Y :: RealFloat a => Vector2 a -> a
vector2Y (Vector2 _ y) = y
vector2XY :: RealFloat a => Vector2 a -> (a, a)
vector2XY (Vector2 x y) = (x, y)
vector2Polar :: RealFloat a => a -> a -> Vector2 a
vector2Polar rho theta = Vector2 (rho * cos theta) (rho * sin theta)
vector2Rho :: RealFloat a => Vector2 a -> a
vector2Rho (Vector2 x y) = sqrt (x * x + y * y)
vector2Theta :: RealFloat a => Vector2 a -> a
vector2Theta (Vector2 x y) = atan2 y x
vector2RhoTheta :: RealFloat a => Vector2 a -> (a, a)
vector2RhoTheta v = (vector2Rho v, vector2Theta v)
instance RealFloat a => VectorSpace (Vector2 a) a where
zeroVector = Vector2 0 0
a *^ (Vector2 x y) = Vector2 (a * x) (a * y)
(Vector2 x y) ^/ a = Vector2 (x / a) (y / a)
negateVector (Vector2 x y) = (Vector2 (-x) (-y))
(Vector2 x1 y1) ^+^ (Vector2 x2 y2) = Vector2 (x1 + x2) (y1 + y2)
(Vector2 x1 y1) ^-^ (Vector2 x2 y2) = Vector2 (x1 - x2) (y1 - y2)
(Vector2 x1 y1) `dot` (Vector2 x2 y2) = x1 * x2 + y1 * y2
vector2Rotate :: RealFloat a => a -> Vector2 a -> Vector2 a
vector2Rotate theta' v = vector2Polar (vector2Rho v) (vector2Theta v + theta')