snoc,
unsafeIndex
)
+
import Prelude hiding (LT)
import Test.Framework (Test, testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Point (Point(..), dot)
import Tetrahedron (Tetrahedron(..), barycenter, c, volume)
-data Cube = Cube { h :: !Double,
- i :: !Int,
+data Cube = Cube { i :: !Int,
j :: !Int,
k :: !Int,
fv :: !FunctionValues,
instance Arbitrary Cube where
arbitrary = do
- (Positive h') <- arbitrary :: Gen (Positive Double)
i' <- choose (coordmin, coordmax)
j' <- choose (coordmin, coordmax)
k' <- choose (coordmin, coordmax)
fv' <- arbitrary :: Gen FunctionValues
(Positive tet_vol) <- arbitrary :: Gen (Positive Double)
- return (Cube h' i' j' k' fv' tet_vol)
+ return (Cube i' j' k' fv' tet_vol)
where
-- The idea here is that, when cubed in the volume formula,
-- these numbers don't overflow 64 bits. This number is not
instance Show Cube where
show cube =
"Cube_" ++ subscript ++ "\n" ++
- " h: " ++ (show (h cube)) ++ "\n" ++
" Center: " ++ (show (center cube)) ++ "\n" ++
" xmin: " ++ (show (xmin cube)) ++ "\n" ++
" xmax: " ++ (show (xmax cube)) ++ "\n" ++
-- | The left-side boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
xmin :: Cube -> Double
-xmin cube = (i' - 1/2)*delta
+xmin cube = (i' - 1/2)
where
i' = fromIntegral (i cube) :: Double
- delta = h cube
-- | The right-side boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
xmax :: Cube -> Double
-xmax cube = (i' + 1/2)*delta
+xmax cube = (i' + 1/2)
where
i' = fromIntegral (i cube) :: Double
- delta = h cube
-- | The front boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
ymin :: Cube -> Double
-ymin cube = (j' - 1/2)*delta
+ymin cube = (j' - 1/2)
where
j' = fromIntegral (j cube) :: Double
- delta = h cube
-- | The back boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
ymax :: Cube -> Double
-ymax cube = (j' + 1/2)*delta
+ymax cube = (j' + 1/2)
where
j' = fromIntegral (j cube) :: Double
- delta = h cube
-- | The bottom boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
zmin :: Cube -> Double
-zmin cube = (k' - 1/2)*delta
+zmin cube = (k' - 1/2)
where
k' = fromIntegral (k cube) :: Double
- delta = h cube
-- | The top boundary of the cube. See Sorokina and Zeilfelder,
-- p. 76.
zmax :: Cube -> Double
-zmax cube = (k' + 1/2)*delta
+zmax cube = (k' + 1/2)
where
k' = fromIntegral (k cube) :: Double
- delta = h cube
-- | The center of Cube_ijk coincides with v_ijk at
--- (ih, jh, kh). See Sorokina and Zeilfelder, p. 76.
+-- (i, j, k). See Sorokina and Zeilfelder, p. 76.
center :: Cube -> Point
center cube =
Point x y z
where
- delta = h cube
- i' = fromIntegral (i cube) :: Double
- j' = fromIntegral (j cube) :: Double
- k' = fromIntegral (k cube) :: Double
- x = delta * i'
- y = delta * j'
- z = delta * k'
+ x = fromIntegral (i cube) :: Double
+ y = fromIntegral (j cube) :: Double
+ z = fromIntegral (k cube) :: Double
-- Face stuff.
top_face :: Cube -> Face.Face
top_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point delta (-delta) delta )
v1' = cc + ( Point delta delta delta )
back_face :: Cube -> Face.Face
back_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point delta (-delta) (-delta) )
v1' = cc + ( Point delta delta (-delta) )
down_face :: Cube -> Face.Face
down_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point (-delta) (-delta) (-delta) )
v1' = cc + ( Point (-delta) delta (-delta) )
front_face :: Cube -> Face.Face
front_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point (-delta) (-delta) delta )
v1' = cc + ( Point (-delta) delta delta )
left_face :: Cube -> Face.Face
left_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point delta (-delta) delta )
v1' = cc + ( Point (-delta) (-delta) delta )
right_face :: Cube -> Face.Face
right_face cube = Face.Face v0' v1' v2' v3'
where
- delta = (1/2)*(h cube)
+ delta = 1/2
cc = center cube
v0' = cc + ( Point (-delta) delta delta)
v1' = cc + ( Point delta delta delta )
-- | In fact, since all of the tetrahedra are identical, we should
-- already know their volumes. There's 24 tetrahedra to a cube, so
--- we'd expect the volume of each one to be (1/24)*h^3.
+-- we'd expect the volume of each one to be 1/24.
prop_all_volumes_exact :: Cube -> Bool
prop_all_volumes_exact cube =
- and [volume t ~~= (1/24)*(delta^(3::Int)) | t <- tetrahedra cube]
- where
- delta = h cube
+ and [volume t ~~= 1/24 | t <- tetrahedra cube]
-- | All tetrahedron should have their v0 located at the center of the
-- cube.
-- This test checks the rotation works as expected.
prop_c_tilde_2100_rotation_correct :: Cube -> Bool
prop_c_tilde_2100_rotation_correct cube =
- expr1 == expr2
+ expr1 ~= expr2
where
t0 = tetrahedron cube 0
t6 = tetrahedron cube 6
-- even meaningful!
prop_c_tilde_2100_correct :: Cube -> Bool
prop_c_tilde_2100_correct cube =
- c t6 2 1 0 0 == expected
+ c t6 2 1 0 0 ~= expected
where
t0 = tetrahedron cube 0
t6 = tetrahedron cube 6