2 (in-package :cl-tuples
)
4 (def-tuple-type matrix22
5 :tuple-element-type fast-float
10 (export-tuple-operations matrix22
)
12 (def-tuple-type matrix33
13 :tuple-element-type fast-float
14 :initial-element
0.0f0
15 :elements
(e00 e01 e02
19 (export-tuple-operations matrix33
)
21 (def-tuple-type matrix44
22 :tuple-element-type fast-float
23 :initial-element
0.0f0
24 :elements
(e00 e01 e02 e03
29 (export-tuple-operations matrix44
)
31 (def-tuple-op transpose-matrix22
*
35 "Return the transpose of the matrix"
41 (defmacro matrix-dot
(dimension row col
)
42 "Generate the symbols required for a dot product between the row and column of a matrix, assuming accessor symbol is e<row><col>"
44 ((make-matrix-element-symbol (mat row col
)
45 (intern (string-upcase (format nil
"e~A~A~A" mat row col
)) :cl-tuples
)))
48 (loop for row from
0 below dimension
49 collect
(make-matrix-element-symbol 0 row col
)))
51 (loop for col from
0 below dimension
52 collect
(make-matrix-element-symbol 1 row col
))))
55 for col-sym in col-sym-names
56 for row-sym in row-sym-names
57 collect
`(* ,col-sym
,row-sym
))))))
60 (def-tuple-op transform-vertex2d
*
61 ((mat matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
))
62 (vert vector2d
(x y w
)))
65 (+ (* x e00
) (* y e01
) (* w e02
))
66 (+ (* x e10
) (* y e11
) (* w e12
))
67 (+ (* x e20
) (* y e21
) (* w e22
)))))
70 (def-tuple-op transform-vector2d
*
71 ((mat matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
))
75 (+ (* x e00
) (* y e01
))
76 (+ (* x e10
) (* y e11
)))))
79 (def-tuple-op matrix33-product
*
80 ((m0 matrix33
(e000 e001 e002 e010 e011 e012 e020 e021 e022
))
81 (m1 matrix33
(e100 e101 e102 e110 e111 e112 e120 e121 e122
)))
97 (def-tuple-op transform-vertex3d
*
103 (vert vertex3d
(x y z w
)))
106 (+ (* x e00
) (* y e01
) (* z e02
) (* w e03
))
107 (+ (* x e10
) (* y e11
) (* z e12
) (* w e13
))
108 (+ (* x e20
) (* y e21
) (* z e22
) (* w e23
))
109 (+ (* x e30
) (* y e31
) (* z e32
) (* w e33
)))))
111 (def-tuple-op transform-vector3d
*
116 (vect vector3d
(x y z
)))
119 (+ (* x e00
) (* y e01
) (* z e02
) )
120 (+ (* x e10
) (* y e11
) (* z e12
) )
121 (+ (* x e20
) (* y e21
) (* z e12
) ))))
123 (def-tuple-op transpose-matrix33
*
124 ((mat33 matrix33
(e00 e01 e02 e10 e11 e12 e20 e21 e22
)))
125 "Return the transpose of the matrix"
132 (def-tuple-op print-matrix33
*
133 ((mat matrix44
(e00 e01 e02 e03
137 "Print a 3x3 matrix in a useful format."
139 (format t
"~A ~A ~A ~A ~%" e00 e01 e02
)
140 (format t
"~A ~A ~A ~A ~%" e10 e11 e12
)
141 (format t
"~A ~A ~A ~A ~%" e20 e21 e22
)))
143 (def-tuple-op matrix44-product
*
144 ((m0 matrix44
(e000 e001 e002 e003 e010 e011 e012 e013 e020 e021 e022 e023 e030 e031 e032 e033
))
145 (m1 matrix44
(e100 e101 e102 e103 e110 e111 e112 e113 e120 e121 e122 e123 e130 e131 e132 e133
)))
166 (matrix-dot 4 3 3))))
168 (def-tuple-op identity-matrix22
*
175 (def-tuple-op identity-matrix33
*
183 (def-tuple-op identity-matrix44
*
192 (def-tuple-op translation-matrix44
*
196 "Return a matrix that represents a translation transformation"
202 0.0f0
0.0f0
0.0f0
1.0f0
)))
204 (def-tuple-op scaling-matrix44
*
215 (def-tuple-op vertex3d-translation-matrix44
*
216 ((vert vertex3d
(tx ty tz tw
)))
217 "Return a matrix that represents a translation transformation"
223 0.0f0
0.0f0
0.0f0
1.0f0
)))
225 (def-tuple-op rotatex-matrix33
*
226 ((rotation fast-float
))
227 "Return a matrix for rotating around the x axis."
229 (let* ((sin (sin rotation
))
231 (cos (cos rotation
)))
237 (def-tuple-op rotatex-matrix44
*
238 ((rotation fast-float
))
239 "Return a matrix for rotating around the x axis."
242 (rotatex-matrix33* rotation
))))
244 (def-tuple-op rotatey-matrix33
*
245 ((rotation fast-float
))
246 "Return a matrix for rotating around the y axis."
248 (let* ((sin (sin rotation
))
250 (cos (cos rotation
)))
256 (def-tuple-op rotatey-matrix44
*
257 ((rotation fast-float
))
258 "Return a matrix for rotating around the y axis."
261 (rotatey-matrix33* rotation
))))
263 (def-tuple-op rotatez-matrix33
*
264 ((rotation fast-float
))
265 "Return a matrix for rotating around the z axis."
267 (let* ((sin (sin rotation
))
269 (cos (cos rotation
)))
275 (def-tuple-op rotatez-matrix44
*
276 ((rotation fast-float
))
277 "Return a matrix for rotating around the z axis."
280 (rotatez-matrix33* rotation
))))
282 (def-tuple-op transpose-matrix44
*
288 "Return the transpose of the matrix"
296 (def-tuple-op make-test-matrix44
*
298 "Return a matrix for testing purposes"
301 1.0f0
2.0f0
3.0f0
4.0f0
302 5.0f0
6.0f0
7.0f0
8.0f0
303 9.0f0
10.0f0
11.0f0
12.0f0
304 13.0f0
14.0f0
15.0f0
16.0f0
)))
307 (def-tuple-op print-matrix44
*
308 ((mat matrix44
(e00 e01 e02 e03
312 "Print a matrix in a useful format."
314 (format t
"~A ~A ~A ~A ~%" e00 e01 e02 e03
)
315 (format t
"~A ~A ~A ~A ~%" e10 e11 e12 e13
)
316 (format t
"~A ~A ~A ~A ~%" e20 e21 e22 e23
)
317 (format t
"~A ~A ~A ~A ~%" e30 e31 e32 e33
)))
320 (def-tuple-op matrix44-matrix33
*
326 "Convert a 4x4 matrix to a 3x3 matrix"
328 (matrix33-values* e00 e01 e02 e10 e11 e12 e20 e21 e22
)))
330 (def-tuple-op matrix33-matrix44
*
335 "Convert a 3x3 matrix to a 4x4 matrix"
337 (matrix44-values* e00 e01 e02
0.0f0
340 0.0f0
0.0f0
0.0f0
1.0f0
)))
342 (def-tuple-op vector3d-matrix3d
*
343 ((zvec vector3d
(zx zy zz
))
344 (yvec vector3d
(yx yy yz
)))
345 "Construct a rotation matrix from 2 vectors"
357 (def-tuple-op matrix22-determinant
*
358 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
363 (def-tuple-op matrix33-determinant
*
364 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
366 (- (+ (* e00 e11 e22
)
373 (def-tuple-op matrix44-determinant
*
374 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
376 (let ((t0 (* e00 e22
))
393 (def-tuple-op matrix22-scale
*
395 (mat matrix22
#1=#.
(tuple-elements 'matrix22
)))
396 (:return matrix22
(multiply-arguments matrix22-values
* x
#1#)))
398 (def-tuple-op matrix33-scale
*
400 (mat matrix33
#1=#.
(tuple-elements 'matrix33
)))
401 (:return matrix33
(multiply-arguments matrix33-values
* x
#1#)))
403 (def-tuple-op matrix44-scale
*
405 (mat matrix44
#1=#.
(tuple-elements 'matrix44
)))
406 (:return matrix44
(multiply-arguments matrix44-values
* x
#1#)))
408 (def-tuple-op cofactor-matrix22
*
409 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
415 (def-tuple-op cofactor-matrix33
*
416 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
418 (macrolet ((cofactors ()
420 ,@(matrix-cofactors 3))))
423 (def-tuple-op cofactor-matrix44
*
424 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
426 (macrolet ((cofactors ()
428 ,@(matrix-cofactors 4))))
431 (def-tuple-op inverted-matrix22
*
432 ((mat matrix22
#.
(tuple-elements 'matrix22
)))
435 (matrix22-determinant* mat
)
437 (cofactor-matrix22* mat
)))))
439 (def-tuple-op inverted-matrix33
*
440 ((mat matrix33
#.
(tuple-elements 'matrix33
)))
443 (matrix33-determinant* mat
)
445 (cofactor-matrix33* mat
)))))
447 (def-tuple-op inverted-matrix44
*
448 ((mat matrix44
#.
(tuple-elements 'matrix44
)))
451 (matrix44-determinant* mat
)
453 (cofactor-matrix44* mat
)))))