diff options
-rw-r--r-- | Spear/Math/Matrix3.hs | 187 |
1 files changed, 90 insertions, 97 deletions
diff --git a/Spear/Math/Matrix3.hs b/Spear/Math/Matrix3.hs index 1e56ceb..fe3162e 100644 --- a/Spear/Math/Matrix3.hs +++ b/Spear/Math/Matrix3.hs | |||
@@ -6,17 +6,19 @@ module Spear.Math.Matrix3 | |||
6 | , m10, m11, m12 | 6 | , m10, m11, m12 |
7 | , m20, m21, m22 | 7 | , m20, m21, m22 |
8 | , col0, col1, col2 | 8 | , col0, col1, col2 |
9 | , row0, row1, row2 | 9 | , row0, row1, row2 |
10 | , right, forward, position | ||
10 | -- * Construction | 11 | -- * Construction |
11 | , mat3 | 12 | , mat3 |
12 | , mat3fromVec | 13 | , mat3fromVec |
14 | , transform | ||
13 | , Spear.Math.Matrix3.id | 15 | , Spear.Math.Matrix3.id |
14 | -- * Transformations | 16 | -- * Transformations |
17 | -- ** Translation | ||
18 | , transl | ||
19 | , translv | ||
15 | -- ** Rotation | 20 | -- ** Rotation |
16 | , rotX | 21 | , rot |
17 | , rotY | ||
18 | , rotZ | ||
19 | , axisAngle | ||
20 | -- ** Scale | 22 | -- ** Scale |
21 | , Spear.Math.Matrix3.scale | 23 | , Spear.Math.Matrix3.scale |
22 | , scalev | 24 | , scalev |
@@ -25,17 +27,17 @@ module Spear.Math.Matrix3 | |||
25 | , reflectY | 27 | , reflectY |
26 | , reflectZ | 28 | , reflectZ |
27 | -- * Operations | 29 | -- * Operations |
28 | , transpose | 30 | , transpose |
31 | , mul | ||
29 | , Spear.Math.Matrix3.zipWith | 32 | , Spear.Math.Matrix3.zipWith |
30 | , Spear.Math.Matrix3.map | 33 | , Spear.Math.Matrix3.map |
31 | , mul | ||
32 | --, inverse | 34 | --, inverse |
33 | ) | 35 | ) |
34 | where | 36 | where |
35 | 37 | ||
36 | 38 | ||
37 | import Spear.Math.Vector3 as Vector3 | 39 | import Spear.Math.Vector2 as V2 |
38 | import Spear.Math.Vector4 as Vector4 | 40 | import Spear.Math.Vector3 as V3 |
39 | 41 | ||
40 | import Foreign.Storable | 42 | import Foreign.Storable |
41 | 43 | ||
@@ -113,14 +115,19 @@ instance Storable Matrix3 where | |||
113 | pokeByteOff ptr 24 a20; pokeByteOff ptr 28 a21; pokeByteOff ptr 32 a22; | 115 | pokeByteOff ptr 24 a20; pokeByteOff ptr 28 a21; pokeByteOff ptr 32 a22; |
114 | 116 | ||
115 | 117 | ||
116 | col0 (Matrix3 a00 _ _ a10 _ _ a20 _ _ ) = vec3 a00 a10 a20 | 118 | col0 (Matrix3 a00 _ _ a01 _ _ a02 _ _ ) = vec3 a00 a01 a02 |
117 | col1 (Matrix3 _ a01 _ _ a11 _ _ a21 _ ) = vec3 a01 a11 a21 | 119 | col1 (Matrix3 _ a10 _ _ a11 _ _ a12 _ ) = vec3 a10 a11 a12 |
118 | col2 (Matrix3 _ _ a02 _ _ a12 _ _ a22) = vec3 a02 a12 a22 | 120 | col2 (Matrix3 _ _ a20 _ _ a21 _ _ a22) = vec3 a20 a21 a22 |
119 | 121 | ||
120 | 122 | ||
121 | row0 (Matrix3 a00 a01 a02 _ _ _ _ _ _ ) = vec3 a00 a01 a02 | 123 | row0 (Matrix3 a00 a10 a20 _ _ _ _ _ _ ) = vec3 a00 a10 a20 |
122 | row1 (Matrix3 _ _ _ a10 a11 a12 _ _ _ ) = vec3 a10 a11 a12 | 124 | row1 (Matrix3 _ _ _ a01 a11 a21 _ _ _ ) = vec3 a01 a11 a21 |
123 | row2 (Matrix3 _ _ _ _ _ _ a20 a21 a22) = vec3 a20 a21 a22 | 125 | row2 (Matrix3 _ _ _ _ _ _ a02 a12 a22) = vec3 a02 a12 a22 |
126 | |||
127 | |||
128 | right (Matrix3 a00 _ _ a01 _ _ _ _ _) = vec2 a00 a01 | ||
129 | forward (Matrix3 _ a10 _ _ a11 _ _ _ _) = vec2 a10 a11 | ||
130 | position (Matrix3 _ _ a20 _ _ a21 _ _ _) = vec2 a20 a21 | ||
124 | 131 | ||
125 | 132 | ||
126 | -- | Build a 'Matrix3' from the specified values. | 133 | -- | Build a 'Matrix3' from the specified values. |
@@ -136,25 +143,21 @@ mat3 m00 m01 m02 m10 m11 m12 m20 m21 m22 = Matrix3 | |||
136 | -- | Build a 'Matrix3' from three vectors in 3D. | 143 | -- | Build a 'Matrix3' from three vectors in 3D. |
137 | mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 | 144 | mat3fromVec :: Vector3 -> Vector3 -> Vector3 -> Matrix3 |
138 | mat3fromVec v0 v1 v2 = Matrix3 | 145 | mat3fromVec v0 v1 v2 = Matrix3 |
139 | (Vector3.x v0) (Vector3.x v1) (Vector3.x v2) | 146 | (V3.x v0) (V3.x v1) (V3.x v2) |
140 | (Vector3.y v0) (Vector3.y v1) (Vector3.y v2) | 147 | (V3.y v0) (V3.y v1) (V3.y v2) |
141 | (Vector3.z v0) (Vector3.z v1) (Vector3.z v2) | 148 | (V3.z v0) (V3.z v1) (V3.z v2) |
142 | 149 | ||
143 | 150 | ||
144 | -- | Zip two 'Matrix3' together with the specified function. | 151 | -- | Build a transformation matrix. |
145 | zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3 | 152 | transform :: Vector2 -- ^ Right vector |
146 | zipWith f a b = Matrix3 | 153 | -> Vector2 -- ^ Forward vector |
147 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) | 154 | -> Vector2 -- ^ Position |
148 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) | 155 | -> Matrix3 -- ^ Transform |
149 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) | 156 | |
150 | 157 | transform r f p = mat3 | |
151 | 158 | (V2.x r) (V2.x f) (V2.x p) | |
152 | -- | Map the specified function to the specified 'Matrix3'. | 159 | (V2.y r) (V2.y f) (V2.y p) |
153 | map :: (Float -> Float) -> Matrix3 -> Matrix3 | 160 | 0 0 1 |
154 | map f m = Matrix3 | ||
155 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) | ||
156 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) | ||
157 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) | ||
158 | 161 | ||
159 | 162 | ||
160 | -- | Return the identity matrix. | 163 | -- | Return the identity matrix. |
@@ -163,66 +166,40 @@ id = mat3 | |||
163 | 1 0 0 | 166 | 1 0 0 |
164 | 0 1 0 | 167 | 0 1 0 |
165 | 0 0 1 | 168 | 0 0 1 |
166 | 169 | ||
167 | 170 | ||
168 | -- | Create a rotation matrix rotating about the X axis. | 171 | -- | Create a translation matrix. |
169 | -- The given angle must be in degrees. | 172 | transl :: Float -- ^ Translation on the x axis |
170 | rotX :: Float -> Matrix3 | 173 | -> Float -- ^ Translation on the y axis |
171 | rotX angle = mat3 | 174 | -> Matrix3 |
172 | 1 0 0 | 175 | |
173 | 0 c (-s) | 176 | transl tx ty = mat3 |
174 | 0 s c | 177 | 1 0 tx |
175 | where | 178 | 0 1 ty |
176 | s = sin . fromDeg $ angle | 179 | 0 0 1 |
177 | c = cos . fromDeg $ angle | 180 | |
178 | 181 | ||
179 | 182 | -- | Create a translation matrix. | |
180 | -- | Create a rotation matrix rotating about the Y axis. | 183 | translv :: Vector2 -> Matrix3 |
181 | -- The given angle must be in degrees. | 184 | translv v = mat3 |
182 | rotY :: Float -> Matrix3 | 185 | 1 0 (V2.x v) |
183 | rotY angle = mat3 | 186 | 0 1 (V2.y v) |
184 | c 0 s | 187 | 0 0 1 |
185 | 0 1 0 | 188 | |
186 | (-s) 0 c | 189 | |
187 | where | 190 | -- | Create a rotation matrix rotating counter-clockwise about the Z axis. |
188 | s = sin . fromDeg $ angle | 191 | -- |
189 | c = cos . fromDeg $ angle | ||
190 | |||
191 | |||
192 | -- | Create a rotation matrix rotating about the Z axis. | ||
193 | -- The given angle must be in degrees. | 192 | -- The given angle must be in degrees. |
194 | rotZ :: Float -> Matrix3 | 193 | rot :: Float -> Matrix3 |
195 | rotZ angle = mat3 | 194 | rot angle = mat3 |
196 | c (-s) 0 | 195 | c (-s) 0 |
197 | s c 0 | 196 | s c 0 |
198 | 0 0 1 | 197 | 0 0 1 |
199 | where | 198 | where |
200 | s = sin . fromDeg $ angle | 199 | s = sin . fromDeg $ angle |
201 | c = cos . fromDeg $ angle | 200 | c = cos . fromDeg $ angle |
202 | 201 | ||
203 | 202 | ||
204 | -- | Create a rotation matrix rotating about the specified axis. | ||
205 | -- The given angle must be in degrees. | ||
206 | axisAngle :: Vector3 -> Float -> Matrix3 | ||
207 | axisAngle v angle = mat3 | ||
208 | (c + omc*x^2) (omc*xy-sz) (omc*xz+sy) | ||
209 | (omc*xy+sz) (c+omc*y^2) (omc*yz-sx) | ||
210 | (omc*xz-sy) (omc*yz+sx) (c+omc*z^2) | ||
211 | where | ||
212 | x = Vector3.x v | ||
213 | y = Vector3.y v | ||
214 | z = Vector3.z v | ||
215 | s = sin . fromDeg $ angle | ||
216 | c = cos . fromDeg $ angle | ||
217 | xy = x*y | ||
218 | xz = x*z | ||
219 | yz = y*z | ||
220 | sx = s*x | ||
221 | sy = s*y | ||
222 | sz = s*z | ||
223 | omc = 1 - c | ||
224 | |||
225 | |||
226 | -- | Create a scale matrix. | 203 | -- | Create a scale matrix. |
227 | scale :: Float -> Float -> Float -> Matrix3 | 204 | scale :: Float -> Float -> Float -> Matrix3 |
228 | scale sx sy sz = mat3 | 205 | scale sx sy sz = mat3 |
@@ -238,9 +215,9 @@ scalev v = mat3 | |||
238 | 0 sy 0 | 215 | 0 sy 0 |
239 | 0 0 sz | 216 | 0 0 sz |
240 | where | 217 | where |
241 | sx = Vector3.x v | 218 | sx = V3.x v |
242 | sy = Vector3.y v | 219 | sy = V3.y v |
243 | sz = Vector3.z v | 220 | sz = V3.z v |
244 | 221 | ||
245 | 222 | ||
246 | -- | Create an X reflection matrix. | 223 | -- | Create an X reflection matrix. |
@@ -279,10 +256,26 @@ transpose m = mat3 | |||
279 | mul :: Matrix3 -> Vector3 -> Vector3 | 256 | mul :: Matrix3 -> Vector3 -> Vector3 |
280 | mul m v = vec3 x' y' z' | 257 | mul m v = vec3 x' y' z' |
281 | where | 258 | where |
282 | v' = vec3 (Vector3.x v) (Vector3.y v) (Vector3.z v) | 259 | v' = vec3 (V3.x v) (V3.y v) (V3.z v) |
283 | x' = row0 m `Vector3.dot` v' | 260 | x' = row0 m `V3.dot` v' |
284 | y' = row1 m `Vector3.dot` v' | 261 | y' = row1 m `V3.dot` v' |
285 | z' = row2 m `Vector3.dot` v' | 262 | z' = row2 m `V3.dot` v' |
263 | |||
264 | |||
265 | -- | Zip two 'Matrix3' together with the specified function. | ||
266 | zipWith :: (Float -> Float -> Float) -> Matrix3 -> Matrix3 -> Matrix3 | ||
267 | zipWith f a b = Matrix3 | ||
268 | (f (m00 a) (m00 b)) (f (m10 a) (m10 b)) (f (m20 a) (m20 b)) | ||
269 | (f (m01 a) (m01 b)) (f (m11 a) (m11 b)) (f (m21 a) (m21 b)) | ||
270 | (f (m02 a) (m02 b)) (f (m12 a) (m12 b)) (f (m22 a) (m22 b)) | ||
271 | |||
272 | |||
273 | -- | Map the specified function to the specified 'Matrix3'. | ||
274 | map :: (Float -> Float) -> Matrix3 -> Matrix3 | ||
275 | map f m = Matrix3 | ||
276 | (f . m00 $ m) (f . m10 $ m) (f . m20 $ m) | ||
277 | (f . m01 $ m) (f . m11 $ m) (f . m21 $ m) | ||
278 | (f . m02 $ m) (f . m12 $ m) (f . m22 $ m) | ||
286 | 279 | ||
287 | 280 | ||
288 | -- | Invert the given 'Matrix3'. | 281 | -- | Invert the given 'Matrix3'. |