diagrams-lib-1.3: src/Diagrams/Transform.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
-----------------------------------------------------------------------------
-- |
-- Module : Diagrams.Transform
-- Copyright : (c) 2011-15 diagrams-lib team (see LICENSE)
-- License : BSD-style (see LICENSE)
-- Maintainer : diagrams-discuss@googlegroups.com
--
-- Affine transformations, parameterized by any vector space. For
-- transformations on particular vector spaces, see /e.g./
-- "Diagrams.TwoD.Transform".
--
-----------------------------------------------------------------------------
module Diagrams.Transform
( -- * Transformations
Transformation, inv, transl, apply, papply
-- * The Transformable class
, Transformable(..)
-- * Some specific transformations
, translation, translate, moveTo, place, scaling, scale
-- * Miscellaneous transformation-related utilities
, conjugate, underT, transformed, translated, movedTo, movedFrom
-- * The HasOrigin class
, HasOrigin(..), moveOriginBy
) where
import Control.Lens hiding (transform)
import Data.Semigroup
import Diagrams.Core
import Linear.Vector
-- | Conjugate one transformation by another. @conjugate t1 t2@ is the
-- transformation which performs first @t1@, then @t2@, then the
-- inverse of @t1@.
conjugate :: (Additive v, Num n, Functor v)
=> Transformation v n -> Transformation v n -> Transformation v n
conjugate t1 t2 = inv t1 <> t2 <> t1
-- | Carry out some transformation \"under\" another one: @f ``underT``
-- t@ first applies @t@, then @f@, then the inverse of @t@. For
-- example, @'scaleX' 2 ``underT`` 'rotation' (-1/8 \@\@ Turn)@
-- is the transformation which scales by a factor of 2 along the
-- diagonal line y = x.
--
-- Note that
--
-- @
-- (transform t2) `underT` t1 == transform (conjugate t1 t2)
-- @
--
-- for all transformations @t1@ and @t2@.
--
-- See also the isomorphisms like 'transformed', 'movedTo',
-- 'movedFrom', and 'translated'.
underT :: (InSpace v n a, SameSpace a b, Transformable a, Transformable b)
=> (a -> b) -> Transformation v n -> a -> b
f `underT` t = transform (inv t) . f . transform t
-- | Use a 'Transformation' to make an 'Iso' between an object
-- transformed and untransformed. This is useful for carrying out
-- functions 'under' another transform:
--
-- @
-- under (transformed t) f == transform (inv t) . f . transform t
-- under (transformed t1) (transform t2) == transform (conjugate t1 t2)
-- transformed t ## a == transform t a
-- a ^. transformed t == transform (inv t) a
-- @
transformed :: (InSpace v n a, SameSpace a b, Transformable a, Transformable b)
=> Transformation v n -> Iso a b a b
transformed t = iso (transform $ inv t) (transform t)
-- | Use a 'Point' to make an 'Iso' between an object
-- moved to and from that point:
--
-- @
-- under (movedTo p) f == moveTo (-p) . f . moveTo p
-- over (movedTo p) f == moveTo p . f . moveTo (-p)
-- movedTo p == from (movedFrom p)
-- movedTo p ## a == moveTo p a
-- a ^. movedTo p == moveOriginTo p a
-- @
movedTo :: (InSpace v n a, SameSpace a b, HasOrigin a, HasOrigin b)
=> Point v n -> Iso a b a b
movedTo p = iso (moveTo (negated p)) (moveTo p)
-- | Use a 'Transformation' to make an 'Iso' between an object
-- transformed and untransformed. We have
--
-- @
-- under (movedFrom p) f == moveTo p . f . moveTo (-p)
-- movedFrom p == from (movedTo p)
-- movedFrom p ## a == moveOriginTo p a
-- a ^. movedFrom p == moveTo p a
-- over (movedFrom p) f == moveTo (-p) . f . moveTo p
-- @
movedFrom :: (InSpace v n a, SameSpace a b, HasOrigin a, HasOrigin b)
=> Point v n -> Iso a b a b
movedFrom p = iso (moveOriginTo (negated p)) (moveOriginTo p)
-- | Use a vector to make an 'Iso' between an object translated and
-- untranslated.
--
-- @
-- under (translated v) f == translate (-v) . f . translate v
-- translated v ## a == translate v a
-- a ^. translated v == translate (-v) a
-- over (translated v) f == translate v . f . translate (-v)
-- @
translated :: (InSpace v n a, SameSpace a b, Transformable a, Transformable b)
=> v n -> Iso a b a b
translated = transformed . translation