{- |
  3-dimensional linear transformations.
-}

module Data.Vector.Transform.T3 where

import Data.Semigroup
import Data.Monoid

import Data.Vector.Class
import Data.Vector.V3

{- |
  The type of 3D linear transformations.

  Note the @Monoid@ instance, which gives you access to the identity transform (@mempty@) and the ability to combine a series of transforms into a single transform (@mappend@).
-}
data Transform3 =
    Transform3
    {
      Transform3 -> Scalar
t3_XX, Transform3 -> Scalar
t3_YX, Transform3 -> Scalar
t3_ZX, Transform3 -> Scalar
t3_1X,
      Transform3 -> Scalar
t3_XY, Transform3 -> Scalar
t3_YY, Transform3 -> Scalar
t3_ZY, Transform3 -> Scalar
t3_1Y,
      Transform3 -> Scalar
t3_XZ, Transform3 -> Scalar
t3_YZ, Transform3 -> Scalar
t3_ZZ, Transform3 -> Scalar
t3_1Z :: {-# UNPACK #-} !Scalar
    }
  deriving (Transform3 -> Transform3 -> Bool
(Transform3 -> Transform3 -> Bool)
-> (Transform3 -> Transform3 -> Bool) -> Eq Transform3
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Transform3 -> Transform3 -> Bool
== :: Transform3 -> Transform3 -> Bool
$c/= :: Transform3 -> Transform3 -> Bool
/= :: Transform3 -> Transform3 -> Bool
Eq, Int -> Transform3 -> ShowS
[Transform3] -> ShowS
Transform3 -> String
(Int -> Transform3 -> ShowS)
-> (Transform3 -> String)
-> ([Transform3] -> ShowS)
-> Show Transform3
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Transform3 -> ShowS
showsPrec :: Int -> Transform3 -> ShowS
$cshow :: Transform3 -> String
show :: Transform3 -> String
$cshowList :: [Transform3] -> ShowS
showList :: [Transform3] -> ShowS
Show)

instance Monoid Transform3 where
  mempty :: Transform3
mempty = Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Scalar
-> Transform3
Transform3  Scalar
1 Scalar
0 Scalar
0 Scalar
0  Scalar
0 Scalar
1 Scalar
0 Scalar
0  Scalar
0 Scalar
0 Scalar
1 Scalar
0

instance Semigroup Transform3 where
  Transform3
a <> :: Transform3 -> Transform3 -> Transform3
<> Transform3
b =
    Transform3
    {
      t3_XX :: Scalar
t3_XX = Transform3 -> Scalar
t3_XX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZX Transform3
b,
      t3_YX :: Scalar
t3_YX = Transform3 -> Scalar
t3_YX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZX Transform3
b,
      t3_ZX :: Scalar
t3_ZX = Transform3 -> Scalar
t3_ZX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZX Transform3
b,
      t3_1X :: Scalar
t3_1X = Transform3 -> Scalar
t3_1X Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Y Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Z Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZX Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1X Transform3
b,

      t3_XY :: Scalar
t3_XY = Transform3 -> Scalar
t3_XX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZY Transform3
b,
      t3_YY :: Scalar
t3_YY = Transform3 -> Scalar
t3_YX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZY Transform3
b,
      t3_ZY :: Scalar
t3_ZY = Transform3 -> Scalar
t3_ZX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZY Transform3
b,
      t3_1Y :: Scalar
t3_1Y = Transform3 -> Scalar
t3_1X Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Y Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Z Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZY Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Y Transform3
b,

      t3_XZ :: Scalar
t3_XZ = Transform3 -> Scalar
t3_XX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_XZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZZ Transform3
b,
      t3_YZ :: Scalar
t3_YZ = Transform3 -> Scalar
t3_YX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_YZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZZ Transform3
b,
      t3_ZZ :: Scalar
t3_ZZ = Transform3 -> Scalar
t3_ZX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_ZZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZZ Transform3
b,
      t3_1Z :: Scalar
t3_1Z = Transform3 -> Scalar
t3_1X Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_XZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Y Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_YZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Z Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Transform3 -> Scalar
t3_ZZ Transform3
b  Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+  Transform3 -> Scalar
t3_1Z Transform3
b
    }

-- | Apply a 3D transformation to a 3D point, yielding a new 3D point.
transformP3 :: Transform3 -> Vector3 -> Vector3
transformP3 :: Transform3 -> Vector3 -> Vector3
transformP3 Transform3
a (Vector3 Scalar
x Scalar
y Scalar
z) =
  Vector3
  {
    v3x :: Scalar
v3x = Transform3 -> Scalar
t3_XX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
x Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_YX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
y Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_ZX Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
z Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_1X Transform3
a,
    v3y :: Scalar
v3y = Transform3 -> Scalar
t3_XY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
x Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_YY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
y Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_ZY Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
z Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_1Y Transform3
a,
    v3z :: Scalar
v3z = Transform3 -> Scalar
t3_XZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
x Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_YZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
y Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_ZZ Transform3
a Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
* Scalar
z Scalar -> Scalar -> Scalar
forall a. Num a => a -> a -> a
+ Transform3 -> Scalar
t3_1Z Transform3
a
  }