{- | Generically handle transforms, and things that are transformable. -} {-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-} module Data.Vector.Transform.Fancy where import Data.Angle import Data.Vector.Class import Data.Vector.V1 import Data.Vector.V2 import Data.Vector.V3 import Data.Vector.V4 import Data.Vector.Axis import Data.Vector.Transform.T1 import Data.Vector.Transform.T2 import Data.Vector.Transform.T3 import Data.Vector.Transform.T4 -- | Class for transforms. class Transform t where -- | The type of vector that can be transformed. (E.g., for @Transform3@, this would be @Vector3@.) type Point t :: * -- | Transform a vector. transformP :: t -> Point t -> Point t -- | Build transform: translate by the given vector. translateT :: Point t -> t -- | Build transform: scale each coordinate axis according to the given vector. scaleT :: Point t -> t -- | Build transform: scale all axies uniformly. scaleT_ :: Scalar -> t -- | Class for performing rotationes. (The rotations that exist vary with the number of spatial dimensions available.) class (Transform t) => Rotate t axis1 axis2 where -- | Build transform: rotate in the plane defined by the two axies. rotateT :: (Angle a) => axis1 -> axis2 -> a Scalar -> t -- | Class for things that can be transformed (by a specific type of transform). class (Transform t) => Transformable t x where -- | Transform anything that can be transformed (for a given type of transform). transform :: t -> x -> x instance Transform Transform1 where type Point Transform1 = Vector1 transformP = transformP1 translateT (Vector1 x) = Transform1 1 x scaleT (Vector1 x) = Transform1 x 0 scaleT_ k = Transform1 k 0 instance Transform Transform2 where type Point Transform2 = Vector2 transformP = transformP2 translateT (Vector2 x y) = Transform2 1 0 x 0 1 y scaleT (Vector2 x y) = Transform2 x 0 0 0 y 0 scaleT_ k = Transform2 k 0 0 0 k 0 instance Transform Transform3 where type Point Transform3 = Vector3 transformP = transformP3 translateT (Vector3 x y z) = Transform3 1 0 0 x 0 1 0 y 0 0 1 z scaleT (Vector3 x y z) = Transform3 x 0 0 0 0 y 0 0 0 0 z 0 scaleT_ k = Transform3 k 0 0 0 0 k 0 0 0 0 k 0 instance Transform Transform4 where type Point Transform4 = Vector4 transformP = transformP4 translateT (Vector4 x y z w) = Transform4 1 0 0 0 x 0 1 0 0 y 0 0 1 0 z 0 0 0 1 w scaleT (Vector4 x y z w) = Transform4 x 0 0 0 0 0 y 0 0 0 0 0 z 0 0 0 0 0 w 0 scaleT_ k = Transform4 k 0 0 0 0 0 k 0 0 0 0 0 k 0 0 0 0 0 k 0 instance Transformable Transform1 Vector1 where transform = transformP1 instance Transformable Transform2 Vector2 where transform = transformP2 instance Transformable Transform3 Vector3 where transform = transformP3 instance Transformable Transform4 Vector4 where transform = transformP4 instance Rotate Transform2 AxisX AxisY where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform2 c s' 0 s c 0 instance Rotate Transform3 AxisX AxisY where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform3 c s' 0 0 s c 0 0 0 0 1 0 instance Rotate Transform3 AxisX AxisZ where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform3 c 0 s' 0 0 1 0 0 s 0 c 0 instance Rotate Transform3 AxisY AxisZ where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform3 1 0 0 0 0 c s' 0 0 s c 0 instance Rotate Transform4 AxisX AxisY where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 c s' 0 0 0 s c 0 0 0 0 0 1 0 0 0 0 0 1 0 instance Rotate Transform4 AxisX AxisZ where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 c 0 s' 0 0 0 1 0 0 0 s 0 c 0 0 0 0 0 1 0 instance Rotate Transform4 AxisX AxisW where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 c 0 0 s' 0 0 1 0 0 0 0 0 1 0 0 s 0 0 c 0 instance Rotate Transform4 AxisY AxisZ where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 1 0 0 0 0 0 c s' 0 0 0 s c 0 0 0 0 0 1 0 instance Rotate Transform4 AxisY AxisW where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 1 0 0 0 0 0 c 0 s' 0 0 0 1 0 0 0 s 0 c 0 instance Rotate Transform4 AxisZ AxisW where rotateT _ _ a = let s = sine a c = cosine a s' = negate s in Transform4 1 0 0 0 0 0 1 0 0 0 0 0 c s' 0 0 0 s c 0