module Language.Mecha.Solid
( Solid
, PrimQuery (..)
, primitive
, transform
, translate
, scale
, rotate
, union
, intersection
, difference
) where
import Language.Mecha.Octree (Vertex)
import qualified Language.Mecha.Octree as OT
type Matrix = (Vector, Vector, Vector, Vector)
type Vector = (Double, Double, Double, Double)
identity :: Matrix
identity =
( (1, 0, 0, 0)
, (0, 1, 0, 0)
, (0, 0, 1, 0)
, (0, 0, 0, 1)
)
mm :: Matrix -> Matrix -> Matrix
mm a b = x
where
((a11, a12, a13, a14), (a21, a22, a23, a24), (a31, a32, a33, a34), (a41, a42, a43, a44)) = a
((b11, b12, b13, b14), (b21, b22, b23, b24), (b31, b32, b33, b34), (b41, b42, b43, b44)) = b
x = ((x11, x12, x13, x14), (x21, x22, x23, x24), (x31, x32, x33, x34), (x41, x42, x43, x44))
x11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41
x12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42
x13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43
x14 = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44
x21 = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41
x22 = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42
x23 = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43
x24 = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44
x31 = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41
x32 = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42
x33 = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43
x34 = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44
x41 = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41
x42 = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42
x43 = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43
x44 = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44
mv :: Matrix -> Vector -> Vector
mv 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)
type Curve = [(Double, Double)]
data PrimQuery
= PrimInside
| PrimOutside
| PrimSurface Double Double Double
data Solid
= Primitive Matrix Matrix (Vertex -> Double -> PrimQuery)
| Union Solid Solid
| Intersection Solid Solid
| Difference Solid Solid
primitive :: (Vertex -> Double -> PrimQuery) -> Solid
primitive = Primitive identity identity
transform :: Matrix -> Matrix -> Solid -> Solid
transform m m' s = case s of
Primitive n n' f -> Primitive (mm m n) (mm n' m') f
Union a b -> Union (transform m m' a) (transform m m' b)
Intersection a b -> Intersection (transform m m' a) (transform m m' b)
Difference a b -> Difference (transform m m' a) (transform m m' b)
translate :: Double -> Double -> Double -> Solid -> Solid
translate x y z = transform
( (1, 0, 0, x)
, (0, 1, 0, y)
, (0, 0, 1, z)
, (0, 0, 0, 1)
)
( (1, 0, 0, x)
, (0, 1, 0, y)
, (0, 0, 1, z)
, (0, 0, 0, 1)
)
scale :: Double -> Double -> Double -> Solid -> Solid
scale x y z = transform
( (x, 0, 0, 0)
, (0, y, 0, 0)
, (0, 0, z, 0)
, (0, 0, 0, 1)
)
( (1/x, 0, 0, 0)
, ( 0, 1/y, 0, 0)
, ( 0, 0, 1/z, 0)
, ( 0, 0, 0, 1)
)
rotate :: Double -> Double -> Double -> Double -> Solid -> Solid
rotate x y z a = error "rotations not supported yet"
union :: Solid -> Solid -> Solid
union = Union
intersection :: Solid -> Solid -> Solid
intersection = Intersection
difference :: Solid -> Solid -> Solid
difference = Difference