]> gitweb.michael.orlitzky.com - spline3.git/blob - src/FunctionValues.hs
Add a bunch of documentation.
[spline3.git] / src / FunctionValues.hs
1 -- | The FunctionValues module contains the 'FunctionValues' type and
2 -- the functions used to manipulate it.
3 module FunctionValues
4 where
5
6 import Prelude hiding (LT)
7
8 import Cardinal
9
10 -- | The FunctionValues type represents the value of our function f at
11 -- the 27 points surrounding the center of a cube. Each value of f
12 -- can be accessed by the name of its direction.
13 data FunctionValues =
14 FunctionValues { front :: Double,
15 back :: Double,
16 left :: Double,
17 right :: Double,
18 top :: Double,
19 down :: Double,
20 front_left :: Double,
21 front_right :: Double,
22 front_top :: Double,
23 front_down :: Double,
24 back_left :: Double,
25 back_right :: Double,
26 back_top :: Double,
27 back_down :: Double,
28 left_top :: Double,
29 left_down :: Double,
30 right_top :: Double,
31 right_down :: Double,
32 front_left_top :: Double,
33 front_left_down :: Double,
34 front_right_top :: Double,
35 front_right_down :: Double,
36 back_left_top :: Double,
37 back_left_down :: Double,
38 back_right_top :: Double,
39 back_right_down :: Double,
40 interior :: Double }
41 deriving (Eq, Show)
42
43 -- | Return a 'FunctionValues' with a bunch of zeros for data points.
44 empty_values :: FunctionValues
45 empty_values =
46 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
47
48 -- | The eval function is where the magic happens for the
49 -- FunctionValues type. Given a 'Cardinal' direction and a
50 -- 'FunctionValues' object, eval will return the value of the
51 -- function f in that 'Cardinal' direction. Note that 'Cardinal' can
52 -- be a composite type; eval is what performs the "arithmetic" on
53 -- 'Cardinal' directions.
54 eval :: FunctionValues -> Cardinal -> Double
55 eval f F = front f
56 eval f B = back f
57 eval f L = left f
58 eval f R = right f
59 eval f T = top f
60 eval f D = down f
61 eval f FL = front_left f
62 eval f FR = front_right f
63 eval f FD = front_down f
64 eval f FT = front_top f
65 eval f BL = back_left f
66 eval f BR = back_right f
67 eval f BD = back_down f
68 eval f BT = back_top f
69 eval f LD = left_down f
70 eval f LT = left_top f
71 eval f RD = right_down f
72 eval f RT = right_top f
73 eval f FLD = front_left_down f
74 eval f FLT = front_left_top f
75 eval f FRD = front_right_down f
76 eval f FRT = front_right_top f
77 eval f BLD = back_left_down f
78 eval f BLT = back_left_top f
79 eval f BRD = back_right_down f
80 eval f BRT = back_right_top f
81 eval f I = interior f
82 eval _ (Scalar x) = x
83 eval f (Sum x y) = (eval f x) + (eval f y)
84 eval f (Difference x y) = (eval f x) - (eval f y)
85 eval f (Product x y) = (eval f x) * (eval f y)
86 eval f (Quotient x y) = (eval f x) / (eval f y)
87
88 -- | Takes a three-dimensional list of 'Double' and a set of 3D
89 -- coordinates (i,j,k), and returns the value at (i,j,k) in the
90 -- supplied list. If there is no such value, zero is returned.
91 value_at :: [[[Double]]] -> Int -> Int -> Int -> Double
92 value_at values i j k
93 | i < 0 = 0
94 | j < 0 = 0
95 | k < 0 = 0
96 | length values <= k = 0
97 | length (values !! k) <= j = 0
98 | length ((values !! k) !! j) <= i = 0
99 | otherwise = ((values !! k) !! j) !! i
100
101
102 -- | Given a three-dimensional list of 'Double' and a set of 3D
103 -- coordinates (i,j,k), constructs and returns the 'FunctionValues'
104 -- object centered at (i,j,k)
105 make_values :: [[[Double]]] -> Int -> Int -> Int -> FunctionValues
106 make_values values i j k =
107 empty_values { front = value_at values (i-1) j k,
108 back = value_at values (i+1) j k,
109 left = value_at values i (j-1) k,
110 right = value_at values i (j+1) k,
111 down = value_at values i j (k-1),
112 top = value_at values i j (k+1),
113 front_left = value_at values (i-1) (j-1) k,
114 front_right = value_at values (i-1) (j+1) k,
115 front_down =value_at values (i-1) j (k-1),
116 front_top = value_at values (i-1) j (k+1),
117 back_left = value_at values (i+1) (j-1) k,
118 back_right = value_at values (i+1) (j+1) k,
119 back_down = value_at values (i+1) j (k-1),
120 back_top = value_at values (i+1) j (k+1),
121 left_down = value_at values i (j-1) (k-1),
122 left_top = value_at values i (j-1) (k+1),
123 right_top = value_at values i (j+1) (k+1),
124 right_down = value_at values i (j+1) (k-1),
125 front_left_down = value_at values (i-1) (j-1) (k-1),
126 front_left_top = value_at values (i-1) (j-1) (k+1),
127 front_right_down = value_at values (i-1) (j+1) (k-1),
128 front_right_top = value_at values (i-1) (j+1) (k+1),
129 back_left_down = value_at values (i-1) (j-1) (k-1),
130 back_left_top = value_at values (i+1) (j-1) (k+1),
131 back_right_down = value_at values (i+1) (j+1) (k-1),
132 back_right_top = value_at values (i+1) (j+1) (k+1),
133 interior = value_at values i j k }
134
135 -- | Takes a 'FunctionValues' and a function that transforms one
136 -- 'Cardinal' to another (called a rotation). Then it applies the
137 -- rotation to each element of the 'FunctionValues' object, and
138 -- returns the result.
139 rotate :: FunctionValues -> (Cardinal -> Cardinal) -> FunctionValues
140 rotate fv rotation =
141 FunctionValues { front = eval fv (rotation F),
142 back = eval fv (rotation B),
143 left = eval fv (rotation L),
144 right = eval fv (rotation R),
145 down = eval fv (rotation D),
146 top = eval fv (rotation T),
147 front_left = eval fv (rotation FL),
148 front_right = eval fv (rotation FR),
149 front_down = eval fv (rotation FD),
150 front_top = eval fv (rotation FT),
151 back_left = eval fv (rotation BL),
152 back_right = eval fv (rotation BR),
153 back_down = eval fv (rotation BD),
154 back_top = eval fv (rotation BT),
155 left_down = eval fv (rotation LD),
156 left_top = eval fv (rotation LT),
157 right_down = eval fv (rotation RD),
158 right_top = eval fv (rotation RT),
159 front_left_down = eval fv (rotation FLD),
160 front_left_top = eval fv (rotation FLT),
161 front_right_down = eval fv (rotation FRD),
162 front_right_top = eval fv (rotation FRT),
163 back_left_down = eval fv (rotation BLD),
164 back_left_top = eval fv (rotation BLT),
165 back_right_down = eval fv (rotation BRD),
166 back_right_top = eval fv (rotation BRT),
167 interior = interior fv }