helm-1.0.0: src/Helm/Graphics2D/Transform.hs
-- | Contains the 2D transform matrix type and functions for composing
-- transformation matricies.
module Helm.Graphics2D.Transform
(
-- * Types
Transform(..)
-- * Composing
, identity
, matrix
, rotation
, translation
, scale
, multiply
) where
import qualified Linear.Matrix as Matrix
import Linear.V2 (V2(V2))
import Linear.V3 (V3(V3))
-- | Represents a transformation matrix that can be used to transform
-- forms. This is more useful than just using the composing methods
-- in the graphics API, as it can perform skewing and other
-- complex transformation techniques.
data Transform = Transform (Matrix.M33 Double) deriving (Show, Eq, Ord, Read)
instance Num Transform where
(*) (Transform a) (Transform b) = Transform $ a * b
(+) (Transform a) (Transform b) = Transform $ a + b
(-) (Transform a) (Transform b) = Transform $ a - b
negate (Transform a) = Transform $ negate a
abs (Transform a) = Transform $ abs a
signum (Transform a) = Transform $ signum a
fromInteger n = Transform $ V3 (V3 (fromInteger n) 0 0) (V3 (fromInteger n) 0 0) (V3 0 0 1)
-- | Construct an identity transformation matrix. Anything transformed by this matrix
-- will remain the same.
identity :: Transform
identity = Transform Matrix.identity
-- | Construct a transformation matrix with specific row/column values.
--
-- > matrix a b c d x y
--
-- / a b x \
-- \ c d y /
matrix :: Double -> Double -> Double -> Double -> Double -> Double -> Transform
matrix a b c d x y = Transform $ V3 (V3 a b x) (V3 c d y) (V3 0 0 1)
-- | Construct a counter-clockwise rotating transformation matrix.
--
-- > rotation t
--
-- / cos t -sin t 0 \
-- \ sin t cos t 0 /
rotation :: Double -> Transform
rotation t = Transform $ V3 (V3 c (-s) 0) (V3 s c 0) (V3 0 0 1)
where
s = sin t
c = cos t
-- | Construct a translating transformation matrix.
--
-- > translation (V2 x y)
--
-- / 1 0 x \
-- \ 0 1 y /
translation :: V2 Double -> Transform
translation (V2 x y) = Transform $ V3 (V3 1 0 x) (V3 0 1 y) (V3 0 0 1)
-- | Construction a scaling transformation matrix. To scale in all directions,
-- simply have the x and y values the same. Alternatively,
-- to scale by only one direction, keep the excluded dimenion's
-- vector component as 1.
--
-- > scale (V2 x y)
--
-- / x 0 0 \
-- \ 0 y 0 /
scale :: V2 Double -> Transform
scale (V2 x y) = Transform $ V3 (V3 x 0 0) (V3 y 0 0) (V3 0 0 1)
-- | Multiply two transformatio nmatrices together..
multiply :: Transform -> Transform -> Transform
multiply (Transform a) (Transform b) = Transform $ a * b