-- | 2d affine transform

module Pdf.Content.Transform
(
  Transform(..),
  Vector(..),
  identity,
  translation,
  scale,
  transform,
  translate,
  multiply
)
where

-- | Affine transform
data Transform a = Transform a a a a a a
  deriving Int -> Transform a -> ShowS
[Transform a] -> ShowS
Transform a -> String
(Int -> Transform a -> ShowS)
-> (Transform a -> String)
-> ([Transform a] -> ShowS)
-> Show (Transform a)
forall a. Show a => Int -> Transform a -> ShowS
forall a. Show a => [Transform a] -> ShowS
forall a. Show a => Transform a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Transform a] -> ShowS
$cshowList :: forall a. Show a => [Transform a] -> ShowS
show :: Transform a -> String
$cshow :: forall a. Show a => Transform a -> String
showsPrec :: Int -> Transform a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Transform a -> ShowS
Show

-- | 2d vector/point
data Vector a = Vector a a
  deriving Int -> Vector a -> ShowS
[Vector a] -> ShowS
Vector a -> String
(Int -> Vector a -> ShowS)
-> (Vector a -> String) -> ([Vector a] -> ShowS) -> Show (Vector a)
forall a. Show a => Int -> Vector a -> ShowS
forall a. Show a => [Vector a] -> ShowS
forall a. Show a => Vector a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Vector a] -> ShowS
$cshowList :: forall a. Show a => [Vector a] -> ShowS
show :: Vector a -> String
$cshow :: forall a. Show a => Vector a -> String
showsPrec :: Int -> Vector a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Vector a -> ShowS
Show

-- | Identity transform
identity :: Num a => Transform a
identity :: Transform a
identity = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
1 a
0 a
0 a
1 a
0 a
0

-- | Translation
translation :: Num a => a -> a -> Transform a
translation :: a -> a -> Transform a
translation a
tx a
ty = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
1 a
0 a
0 a
1 a
tx a
ty

-- | Scale
scale :: Num a => a -> a -> Transform a
scale :: a -> a -> Transform a
scale a
sx a
sy = a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
sx a
0 a
0 a
sy a
0 a
0

-- | Apply transformation to vector
transform :: Num a => Transform a -> Vector a -> Vector a
transform :: Transform a -> Vector a -> Vector a
transform (Transform a
a a
b a
c a
d a
e a
f) (Vector a
x a
y) =
  a -> a -> Vector a
forall a. a -> a -> Vector a
Vector (a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
c a -> a -> a
forall a. Num a => a -> a -> a
* a
y a -> a -> a
forall a. Num a => a -> a -> a
+ a
e) (a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
d a -> a -> a
forall a. Num a => a -> a -> a
* a
y a -> a -> a
forall a. Num a => a -> a -> a
+ a
f)

-- | Translate
translate :: Num a => a -> a -> Transform a -> Transform a
translate :: a -> a -> Transform a -> Transform a
translate a
tx a
ty Transform a
t = a -> a -> Transform a
forall a. Num a => a -> a -> Transform a
translation a
tx a
ty Transform a -> Transform a -> Transform a
forall a. Num a => Transform a -> Transform a -> Transform a
`multiply` Transform a
t

-- | Combine two transformations
multiply :: Num a => Transform a -> Transform a -> Transform a
multiply :: Transform a -> Transform a -> Transform a
multiply (Transform a
a1 a
b1 a
c1 a
d1 a
e1 a
f1) (Transform a
a2 a
b2 a
c2 a
d2 a
e2 a
f2) =
  a -> a -> a -> a -> a -> a -> Transform a
forall a. a -> a -> a -> a -> a -> a -> Transform a
Transform a
a a
b a
c a
d a
e a
f
  where
  a :: a
a = a
a1 a -> a -> a
forall a. Num a => a -> a -> a
* a
a2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
b1 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2
  b :: a
b = a
a1 a -> a -> a
forall a. Num a => a -> a -> a
* a
b2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
b1 a -> a -> a
forall a. Num a => a -> a -> a
* a
d2
  c :: a
c = a
c1 a -> a -> a
forall a. Num a => a -> a -> a
* a
a2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
d1 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2
  d :: a
d = a
c1 a -> a -> a
forall a. Num a => a -> a -> a
* a
b2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
d1 a -> a -> a
forall a. Num a => a -> a -> a
* a
d2
  e :: a
e = a
e1 a -> a -> a
forall a. Num a => a -> a -> a
* a
a2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
f1 a -> a -> a
forall a. Num a => a -> a -> a
* a
c2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
e2
  f :: a
f = a
e1 a -> a -> a
forall a. Num a => a -> a -> a
* a
b2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
f1 a -> a -> a
forall a. Num a => a -> a -> a
* a
d2 a -> a -> a
forall a. Num a => a -> a -> a
+ a
f2