{- | 4-dimensional linear transformations. -} module Data.Vector.Transform.T4 where import Data.Monoid import Data.Vector.Class import Data.Vector.V4 {- | The type of 4D 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 Transform4 = Transform4 { t4_XX, t4_YX, t4_ZX, t4_WX, t4_1X, t4_XY, t4_YY, t4_ZY, t4_WY, t4_1Y, t4_XZ, t4_YZ, t4_ZZ, t4_WZ, t4_1Z, t4_XW, t4_YW, t4_ZW, t4_WW, t4_1W :: {-# UNPACK #-} !Scalar } deriving (Eq, Show) instance Monoid Transform4 where mempty = Transform4 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 mappend a b = Transform4 { t4_XX = t4_XX a * t4_XX b + t4_XY a * t4_YX b + t4_XZ a * t4_ZX b + t4_XW a * t4_WX b, t4_YX = t4_YX a * t4_XX b + t4_YY a * t4_YX b + t4_YZ a * t4_ZX b + t4_YW a * t4_WX b, t4_ZX = t4_ZX a * t4_XX b + t4_ZY a * t4_YX b + t4_ZZ a * t4_ZX b + t4_ZW a * t4_WX b, t4_WX = t4_WX a * t4_XX b + t4_WY a * t4_YX b + t4_WZ a * t4_ZX b + t4_WW a * t4_WX b, t4_1X = t4_1X a * t4_XX b + t4_1Y a * t4_YX b + t4_1Z a * t4_ZX b + t4_1W a * t4_WX b + t4_1X b, t4_XY = t4_XX a * t4_XY b + t4_XY a * t4_YY b + t4_XZ a * t4_ZY b + t4_XW a * t4_WY b, t4_YY = t4_YX a * t4_XY b + t4_YY a * t4_YY b + t4_YZ a * t4_ZY b + t4_YW a * t4_WY b, t4_ZY = t4_ZX a * t4_XY b + t4_ZY a * t4_YY b + t4_ZZ a * t4_ZY b + t4_ZW a * t4_WY b, t4_WY = t4_WX a * t4_XY b + t4_WY a * t4_YY b + t4_WZ a * t4_ZY b + t4_WW a * t4_WY b, t4_1Y = t4_1X a * t4_XY b + t4_1Y a * t4_YY b + t4_1Z a * t4_ZY b + t4_1W a * t4_WY b + t4_1Y b, t4_XZ = t4_XX a * t4_XZ b + t4_XY a * t4_YZ b + t4_XZ a * t4_ZZ b + t4_XW a * t4_WZ b, t4_YZ = t4_YX a * t4_XZ b + t4_YY a * t4_YZ b + t4_YZ a * t4_ZZ b + t4_YW a * t4_WZ b, t4_ZZ = t4_ZX a * t4_XZ b + t4_ZY a * t4_YZ b + t4_ZZ a * t4_ZZ b + t4_ZW a * t4_WZ b, t4_WZ = t4_WX a * t4_XZ b + t4_WY a * t4_YZ b + t4_WZ a * t4_ZZ b + t4_WW a * t4_WZ b, t4_1Z = t4_1X a * t4_XZ b + t4_1Y a * t4_YZ b + t4_1Z a * t4_ZZ b + t4_1W a * t4_WZ b + t4_1Z b, t4_XW = t4_XX a * t4_XW b + t4_XY a * t4_YW b + t4_XZ a * t4_ZW b + t4_XW a * t4_WW b, t4_YW = t4_YX a * t4_XW b + t4_YY a * t4_YW b + t4_YZ a * t4_ZW b + t4_YW a * t4_WW b, t4_ZW = t4_ZX a * t4_XW b + t4_ZY a * t4_YW b + t4_ZZ a * t4_ZW b + t4_ZW a * t4_WW b, t4_WW = t4_WX a * t4_XW b + t4_WY a * t4_YW b + t4_WZ a * t4_ZW b + t4_WW a * t4_WW b, t4_1W = t4_1X a * t4_XW b + t4_1Y a * t4_YW b + t4_1Z a * t4_ZW b + t4_1W a * t4_WW b + t4_1W b } -- | Apply a 4D transformation to a 4D point, yielding a new 4D point. transformP4 :: Transform4 -> Vector4 -> Vector4 transformP4 a (Vector4 x y z w) = Vector4 { v4x = t4_XX a * x + t4_YX a * y + t4_ZX a * z + t4_WX a * w + t4_1X a, v4y = t4_XY a * x + t4_YY a * y + t4_ZY a * z + t4_WY a * w + t4_1Y a, v4z = t4_XZ a * x + t4_YZ a * y + t4_ZZ a * z + t4_WZ a * w + t4_1Z a, v4w = t4_XW a * x + t4_YW a * y + t4_ZW a * z + t4_WW a * w + t4_1W a }