{- | 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.Fancy import Data.Vector.Transform.T1 import Data.Vector.Transform.T2 import Data.Vector.Transform.T3 import Data.Vector.Transform.T4 -- | Class for transforms. class HasSpace t => Transform t where -- | 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. Includes instances for all the vector types. class HasSpace x => Transformable x where -- | Apply a transformation. transform :: (Transform t, Point t ~ Point x) => t -> x -> x instance HasSpace Transform1 where type Point Transform1 = Vector1 instance Transform Transform1 where transformP = transformP1 translateT (Vector1 x) = Transform1 1 x scaleT (Vector1 x) = Transform1 x 0 scaleT_ k = Transform1 k 0 instance HasSpace Transform2 where type Point Transform2 = Vector2 instance Transform Transform2 where 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 HasSpace Transform3 where type Point Transform3 = Vector3 instance Transform Transform3 where 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 HasSpace Transform4 where type Point Transform4 = Vector4 instance Transform Transform4 where 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 Vector1 where transform = transformP instance Transformable Vector2 where transform = transformP instance Transformable Vector3 where transform = transformP instance Transformable Vector4 where transform = transformP 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