]> gitweb.michael.orlitzky.com - spline3.git/blobdiff - src/Tetrahedron.hs
Fix the tetrahedron collision detection.
[spline3.git] / src / Tetrahedron.hs
index 81fe91c11772122d0643b884e4fc3aea52163a43..6c13f4bbb429f2a185cdd1eaae3a541f1b147cb8 100644 (file)
@@ -3,8 +3,10 @@ where
 
 import Numeric.LinearAlgebra hiding (i, scale)
 import Prelude hiding (LT)
+import Test.QuickCheck (Arbitrary(..), Gen)
 
 import Cardinal
+import Comparisons (nearly_ge)
 import FunctionValues
 import Misc (factorial)
 import Point
@@ -18,6 +20,17 @@ data Tetrahedron = Tetrahedron { fv :: FunctionValues,
                                  v3 :: Point }
                    deriving (Eq)
 
+
+instance Arbitrary Tetrahedron where
+    arbitrary = do
+      rnd_v0 <- arbitrary :: Gen Point
+      rnd_v1 <- arbitrary :: Gen Point
+      rnd_v2 <- arbitrary :: Gen Point
+      rnd_v3 <- arbitrary :: Gen Point
+      rnd_fv <- arbitrary :: Gen FunctionValues
+      return (Tetrahedron rnd_fv rnd_v0 rnd_v1 rnd_v2 rnd_v3)
+
+
 instance Show Tetrahedron where
     show t = "Tetrahedron:\n" ++
              "  fv: " ++ (show (fv t)) ++ "\n" ++
@@ -30,7 +43,10 @@ instance Show Tetrahedron where
 instance ThreeDimensional Tetrahedron where
     center t = ((v0 t) + (v1 t) + (v2 t) + (v3 t)) `scale` (1/4)
     contains_point t p =
-        (b0 t p) >= 0 && (b1 t p) >= 0 && (b2 t p) >= 0 && (b3 t p) >= 0
+      (b0 t p) `nearly_ge` 0 &&
+      (b1 t p) `nearly_ge` 0 &&
+      (b2 t p) `nearly_ge` 0 &&
+      (b3 t p) `nearly_ge` 0
 
 
 polynomial :: Tetrahedron -> (RealFunction Point)
@@ -76,6 +92,11 @@ beta t i j k l
     b3_term = (b3 t) `fexp` l
 
 
+-- | The coefficient function. c t i j k l returns the coefficient
+--   c_ijkl with respect to the tetrahedron t. The definition uses
+--   pattern matching to mimic the definitions given in Sorokina and
+--   Zeilfelder, pp. 84-86. If incorrect indices are supplied, the
+--   function will simply error.
 c :: Tetrahedron -> Int -> Int -> Int -> Int -> Double
 c t 0 0 3 0 = eval (fv t) $
               (1/8) * (I + F + L + T + LT + FL + FT + FLT)
@@ -197,28 +218,22 @@ c _ _ _ _ _ = error "coefficient index out of bounds"
 
 
 
+-- | The matrix used in the tetrahedron volume calculation as given in
+--   Lai & Schumaker, Definition 15.4, page 436.
 vol_matrix :: Tetrahedron -> Matrix Double
-vol_matrix t = (4><4) $
+vol_matrix t = (4><4)
                [1,  1,  1,  1,
                 x1, x2, x3, x4,
                 y1, y2, y3, y4,
                 z1, z2, z3, z4 ]
     where
-      x1 = x_coord (v0 t)
-      x2 = x_coord (v1 t)
-      x3 = x_coord (v2 t)
-      x4 = x_coord (v3 t)
-      y1 = y_coord (v0 t)
-      y2 = y_coord (v1 t)
-      y3 = y_coord (v2 t)
-      y4 = y_coord (v3 t)
-      z1 = z_coord (v0 t)
-      z2 = z_coord (v1 t)
-      z3 = z_coord (v2 t)
-      z4 = z_coord (v3 t)
-
--- Computed using the formula from Lai & Schumaker, Definition 15.4,
--- page 436.
+      (x1, y1, z1) = v0 t
+      (x2, y2, z2) = v1 t
+      (x3, y3, z3) = v2 t
+      (x4, y4, z4) = v3 t
+
+-- | Computed using the formula from Lai & Schumaker, Definition 15.4,
+--   page 436.
 volume :: Tetrahedron -> Double
 volume t
        | (v0 t) == (v1 t) = 0
@@ -230,21 +245,28 @@ volume t
        | otherwise = (1/6)*(det (vol_matrix t))
 
 
+-- | The barycentric coordinates of a point with respect to v0.
 b0 :: Tetrahedron -> (RealFunction Point)
 b0 t point = (volume inner_tetrahedron) / (volume t)
              where
                inner_tetrahedron = t { v0 = point }
 
+
+-- | The barycentric coordinates of a point with respect to v1.
 b1 :: Tetrahedron -> (RealFunction Point)
 b1 t point = (volume inner_tetrahedron) / (volume t)
              where
                inner_tetrahedron = t { v1 = point }
 
+
+-- | The barycentric coordinates of a point with respect to v2.
 b2 :: Tetrahedron -> (RealFunction Point)
 b2 t point = (volume inner_tetrahedron) / (volume t)
              where
                inner_tetrahedron = t { v2 = point }
 
+
+-- | The barycentric coordinates of a point with respect to v3.
 b3 :: Tetrahedron -> (RealFunction Point)
 b3 t point = (volume inner_tetrahedron) / (volume t)
              where