X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FFunctionValues.hs;h=681a23b9fa517a935faf3d553d1202deaacb6bae;hb=627cae8a6bd5da6cd1a4b51b3eb5bb0f60ecbce2;hp=e9ff0647f413b3f530757725f3bab382ac33a730;hpb=6fb9ab6b6068870323e996da931fc04c7710e3e4;p=spline3.git diff --git a/src/FunctionValues.hs b/src/FunctionValues.hs index e9ff064..681a23b 100644 --- a/src/FunctionValues.hs +++ b/src/FunctionValues.hs @@ -1,3 +1,5 @@ +-- | The FunctionValues module contains the 'FunctionValues' type and +-- the functions used to manipulate it. module FunctionValues where @@ -5,6 +7,10 @@ import Prelude hiding (LT) import Cardinal +-- | The FunctionValues type represents the value of our function f at +-- the 27 points surrounding (and including) the center of a +-- cube. Each value of f can be accessed by the name of its +-- direction. data FunctionValues = FunctionValues { front :: Double, back :: Double, @@ -14,31 +20,38 @@ data FunctionValues = down :: Double, front_left :: Double, front_right :: Double, - front_top :: Double, front_down :: Double, + front_top :: Double, back_left :: Double, back_right :: Double, - back_top :: Double, back_down :: Double, - left_top :: Double, + back_top :: Double, left_down :: Double, - right_top :: Double, + left_top :: Double, right_down :: Double, - front_left_top :: Double, + right_top :: Double, front_left_down :: Double, - front_right_top :: Double, + front_left_top :: Double, front_right_down :: Double, - back_left_top :: Double, + front_right_top :: Double, back_left_down :: Double, - back_right_top :: Double, + back_left_top :: Double, back_right_down :: Double, + back_right_top :: Double, interior :: Double } deriving (Eq, Show) +-- | Return a 'FunctionValues' with a bunch of zeros for data points. empty_values :: FunctionValues empty_values = FunctionValues 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-- | The eval function is where the magic happens for the +-- FunctionValues type. Given a 'Cardinal' direction and a +-- 'FunctionValues' object, eval will return the value of the +-- function f in that 'Cardinal' direction. Note that 'Cardinal' can +-- be a composite type; eval is what performs the \"arithmetic\" on +-- 'Cardinal' directions. eval :: FunctionValues -> Cardinal -> Double eval f F = front f eval f B = back f @@ -73,10 +86,23 @@ eval f (Difference x y) = (eval f x) - (eval f y) eval f (Product x y) = (eval f x) * (eval f y) eval f (Quotient x y) = (eval f x) / (eval f y) -value_at :: [[[Double]]] -> Int -> Int -> Int -> Double -value_at values i j k = - ((values !! k) !! j) !! i +-- | Takes a three-dimensional list of 'Double' and a set of 3D +-- coordinates (i,j,k), and returns the value at (i,j,k) in the +-- supplied list. If there is no such value, zero is returned. +value_at :: [[[Double]]] -> Int -> Int -> Int -> Double +value_at values i j k + | i < 0 = 0 + | j < 0 = 0 + | k < 0 = 0 + | length values <= k = 0 + | length (values !! k) <= j = 0 + | length ((values !! k) !! j) <= i = 0 + | otherwise = ((values !! k) !! j) !! i + +-- | Given a three-dimensional list of 'Double' and a set of 3D +-- coordinates (i,j,k), constructs and returns the 'FunctionValues' +-- object centered at (i,j,k) make_values :: [[[Double]]] -> Int -> Int -> Int -> FunctionValues make_values values i j k = empty_values { front = value_at values (i-1) j k, @@ -95,14 +121,48 @@ make_values values i j k = back_top = value_at values (i+1) j (k+1), left_down = value_at values i (j-1) (k-1), left_top = value_at values i (j-1) (k+1), - right_top = value_at values i (j+1) (k+1), right_down = value_at values i (j+1) (k-1), + right_top = value_at values i (j+1) (k+1), front_left_down = value_at values (i-1) (j-1) (k-1), front_left_top = value_at values (i-1) (j-1) (k+1), front_right_down = value_at values (i-1) (j+1) (k-1), front_right_top = value_at values (i-1) (j+1) (k+1), - back_left_down = value_at values (i-1) (j-1) (k-1), + back_left_down = value_at values (i+1) (j-1) (k-1), back_left_top = value_at values (i+1) (j-1) (k+1), back_right_down = value_at values (i+1) (j+1) (k-1), back_right_top = value_at values (i+1) (j+1) (k+1), interior = value_at values i j k } + +-- | Takes a 'FunctionValues' and a function that transforms one +-- 'Cardinal' to another (called a rotation). Then it applies the +-- rotation to each element of the 'FunctionValues' object, and +-- returns the result. +rotate :: (Cardinal -> Cardinal) -> FunctionValues -> FunctionValues +rotate rotation fv = + FunctionValues { front = eval fv (rotation F), + back = eval fv (rotation B), + left = eval fv (rotation L), + right = eval fv (rotation R), + down = eval fv (rotation D), + top = eval fv (rotation T), + front_left = eval fv (rotation FL), + front_right = eval fv (rotation FR), + front_down = eval fv (rotation FD), + front_top = eval fv (rotation FT), + back_left = eval fv (rotation BL), + back_right = eval fv (rotation BR), + back_down = eval fv (rotation BD), + back_top = eval fv (rotation BT), + left_down = eval fv (rotation LD), + left_top = eval fv (rotation LT), + right_down = eval fv (rotation RD), + right_top = eval fv (rotation RT), + front_left_down = eval fv (rotation FLD), + front_left_top = eval fv (rotation FLT), + front_right_down = eval fv (rotation FRD), + front_right_top = eval fv (rotation FRT), + back_left_down = eval fv (rotation BLD), + back_left_top = eval fv (rotation BLT), + back_right_down = eval fv (rotation BRD), + back_right_top = eval fv (rotation BRT), + interior = interior fv }