packages feed

mini-1.6.4.0: src/Mini/Linear/Transform2D.hs

-- | Affine transform matrices for two-dimensional Euclidean space
module Mini.Linear.Transform2D (
  -- * Translation
  translate,

  -- * Scaling
  scale,

  -- * Shearing
  shearByX,
  shearByY,

  -- * Rotation
  rotate,
) where

import Mini.Linear.Matrix (
  diagonal,
  identity,
 )
import Mini.Linear.Space (
  V2,
  V3,
  x,
  xy,
  y,
  z,
 )
import Mini.Optics.Lens (
  set,
 )
import Prelude (
  Floating,
  Num,
  cos,
  negate,
  sin,
  ($),
  (.),
 )

-- Translation

-- | Translate each dimension by the respective components of a vector
translate :: (Num a) => V2 a -> V3 (V3 a)
translate v = set (z . xy) v identity

-- Scaling

-- | Scale each dimension by the respective components of a vector
scale :: (Num a) => V2 a -> V3 (V3 a)
scale v = set (diagonal . xy) v identity

-- Shearing

-- | Shear /y/ w.r.t. /x/ by a factor
shearByX :: (Num a) => a -> V3 (V3 a)
shearByX s = set (x . y) s identity

-- | Shear /x/ w.r.t. /y/ by a factor
shearByY :: (Num a) => a -> V3 (V3 a)
shearByY s = set (y . x) s identity

-- Rotation

-- | Rotate by a number of radians
rotate :: (Floating a) => a -> V3 (V3 a)
rotate phi =
  set (x . x) (cos phi)
    . set (x . y) (sin phi)
    . set (y . x) (negate $ sin phi)
    . set (y . y) (cos phi)
    $ identity