module Language.Mecha.Solid
( Solid (..)
) where
import Language.Mecha.Types
data Solid = Solid (Vector -> Bool)
transform :: Matrix4 -> Solid -> Solid
transform m (Solid f) = Solid $ \ a -> f $ m4v3 m a
instance Moveable Solid where
move (x, y, z) = transform
( (1, 0, 0, x)
, (0, 1, 0, y)
, (0, 0, 1, z)
, (0, 0, 0, 1)
)
rotate (x', y', z') a' = transform
( (xx + cos a * (1 xx) + sin a * 0 , xy + cos a * (0 xy) + sin a * (z), xz + cos a * (0 xz) + sin a * y , 0)
, (xy + cos a * (0 xy) + sin a * z , yy + cos a * (1 yy) + sin a * 0 , yz + cos a * (0 yz) + sin a * (x), 0)
, (xz + cos a * (0 xz) + sin a * (y), yz + cos a * (0 yz) + sin a * x , zz + cos a * (1 zz) + sin a * 0 , 0)
, (0 , 0 , 0 , 1)
)
where
m = sqrt $ x' ** 2 + y' ** 2 + z' ** 2
x = x' / m
y = y' / m
z = z' / m
xx = x ** 2
yy = y ** 2
zz = z ** 2
xy = x * y
xz = x * z
yz = y * z
a = a'
instance Scaleable Solid where
scale (x, y, z) = transform
( (1/x, 0, 0, 0)
, ( 0, 1/y, 0, 0)
, ( 0, 0, 1/z, 0)
, ( 0, 0, 0, 1)
)
instance Setable Solid where
union (Solid a) (Solid b) = Solid $ \ p -> a p || b p
intersection (Solid a) (Solid b) = Solid $ \ p -> a p && b p
difference (Solid a) (Solid b) = Solid $ \ p -> a p && not (b p)
type Matrix4 = (Vector4, Vector4, Vector4, Vector4)
type Vector4 = (Double, Double, Double, Double)
mv4 :: Matrix4 -> Vector4 -> Vector4
mv4 a b = x
where
((a11, a12, a13, a14), (a21, a22, a23, a24), (a31, a32, a33, a34), (a41, a42, a43, a44)) = a
(b1, b2, b3, b4) = b
x1 = a11 * b1 + a12 * b2 + a13 * b3 + a14 * b4
x2 = a21 * b1 + a22 * b2 + a23 * b3 + a24 * b4
x3 = a31 * b1 + a32 * b2 + a33 * b3 + a34 * b4
x4 = a41 * b1 + a42 * b2 + a43 * b3 + a44 * b4
x = (x1, x2, x3, x4)
to4 :: Vector -> Vector4
to4 (x, y, z) = (x, y, z, 1)
to3 :: Vector4 -> Vector
to3 (x, y, z, w) = (x / w, y / w, z / w)
m4v3 :: Matrix4 -> Vector -> Vector
m4v3 m a = to3 $ mv4 m $ to4 a