1
2use num_traits::NumCast;
3use std::ops::{Index, IndexMut, Mul, Add};
4use std::default::Default;
5use float_cmp::{Ulps, ApproxEq};
6use vector::{Vec2, Vec3, Vec4, Direction3, Point3};
7use {Angle, FullFloat};
8
9#[repr(C)]
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29#[derive(Serialize, Deserialize)]
30pub struct Mat2<F> {
31 pub x: Vec2<F>,
32 pub y: Vec2<F>
33}
34
35#[repr(C)]
42#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43#[derive(Serialize, Deserialize)]
44pub struct Mat3<F> {
45 pub x: Vec3<F>,
46 pub y: Vec3<F>,
47 pub z: Vec3<F>
48}
49
50#[repr(C)]
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58#[derive(Serialize, Deserialize)]
59pub struct Mat4<F> {
60 pub x: Vec4<F>,
61 pub y: Vec4<F>,
62 pub z: Vec4<F>,
63 pub p: Vec4<F>
64}
65
66impl<F: FullFloat> Index<(usize,usize)> for Mat2<F> {
70 type Output = F;
71
72 #[inline]
73 fn index(&self, (row,col): (usize,usize)) -> &F {
74 match col {
75 0 => &self.x[row],
76 1 => &self.y[row],
77 _ => panic!("Index out of bounds for Mat2"),
78 }
79 }
80}
81
82impl<F: FullFloat> Index<(usize,usize)> for Mat3<F> {
83 type Output = F;
84
85 #[inline]
86 fn index(&self, (row,col): (usize,usize)) -> &F {
87 match col {
88 0 => &self.x[row],
89 1 => &self.y[row],
90 2 => &self.z[row],
91 _ => panic!("Index out of bounds for Mat3"),
92 }
93 }
94}
95
96impl<F: FullFloat> Index<(usize,usize)> for Mat4<F> {
97 type Output = F;
98
99 #[inline]
100 fn index(&self, (row,col): (usize,usize)) -> &F {
101 match col {
102 0 => &self.x[row],
103 1 => &self.y[row],
104 2 => &self.z[row],
105 3 => &self.p[row],
106 _ => panic!("Index out of bounds for Mat4"),
107 }
108 }
109}
110
111impl<F: FullFloat> IndexMut<(usize,usize)> for Mat2<F> {
114 #[inline]
115 fn index_mut(&mut self, (row,col): (usize,usize)) -> &mut F {
116 match col {
117 0 => &mut self.x[row],
118 1 => &mut self.y[row],
119 _ => panic!("Index out of bounds for Mat2"),
120 }
121 }
122}
123
124impl<F: FullFloat> IndexMut<(usize,usize)> for Mat3<F> {
125 #[inline]
126 fn index_mut(&mut self, (row,col): (usize,usize)) -> &mut F {
127 match col {
128 0 => &mut self.x[row],
129 1 => &mut self.y[row],
130 2 => &mut self.z[row],
131 _ => panic!("Index out of bounds for Mat3"),
132 }
133 }
134}
135
136impl<F: FullFloat> IndexMut<(usize,usize)> for Mat4<F> {
137 #[inline]
138 fn index_mut(&mut self, (row,col): (usize,usize)) -> &mut F {
139 match col {
140 0 => &mut self.x[row],
141 1 => &mut self.y[row],
142 2 => &mut self.z[row],
143 3 => &mut self.p[row],
144 _ => panic!("Index out of bounds for Mat4"),
145 }
146 }
147}
148
149impl<F: FullFloat> Mat2<F> {
152 #[inline]
155 pub fn new(r0c0: F, r0c1: F,
156 r1c0: F, r1c1: F) -> Mat2<F>
157 {
158 Mat2 { x: Vec2::new(r0c0, r1c0),
160 y: Vec2::new(r0c1, r1c1),
161 }
162 }
163
164 #[inline]
165 pub fn from_cols(x: Vec2<F>, y: Vec2<F>) -> Mat2<F>
166 {
167 Mat2 { x: x, y: y }
168 }
169}
170
171impl<F: FullFloat> Mat3<F> {
172 #[inline]
175 pub fn new(r0c0: F, r0c1: F, r0c2: F,
176 r1c0: F, r1c1: F, r1c2: F,
177 r2c0: F, r2c1: F, r2c2: F) -> Mat3<F>
178 {
179 Mat3 { x: Vec3::new(r0c0, r1c0, r2c0),
181 y: Vec3::new(r0c1, r1c1, r2c1),
182 z: Vec3::new(r0c2, r1c2, r2c2),
183 }
184 }
185
186 #[inline]
187 pub fn from_cols(x: Vec3<F>, y: Vec3<F>, z: Vec3<F>) -> Mat3<F>
188 {
189 Mat3 { x: x, y: y, z: z }
190 }
191}
192
193impl<F: FullFloat> Mat4<F> {
194 #[inline]
197 pub fn new(r0c0: F, r0c1: F, r0c2: F, r0c3: F,
198 r1c0: F, r1c1: F, r1c2: F, r1c3: F,
199 r2c0: F, r2c1: F, r2c2: F, r2c3: F,
200 r3c0: F, r3c1: F, r3c2: F, r3c3: F) -> Mat4<F>
201 {
202 Mat4 { x: Vec4::new(r0c0, r1c0, r2c0, r3c0),
204 y: Vec4::new(r0c1, r1c1, r2c1, r3c1),
205 z: Vec4::new(r0c2, r1c2, r2c2, r3c2),
206 p: Vec4::new(r0c3, r1c3, r2c3, r3c3),
207 }
208 }
209
210 #[inline]
211 pub fn from_cols(x: Vec4<F>, y: Vec4<F>, z: Vec4<F>, p: Vec4<F>) -> Mat4<F>
212 {
213 Mat4 { x: x, y: y, z: z, p: p }
214 }
215}
216
217impl<F: FullFloat> Mat4<F> {
218 #[inline]
219 pub fn from_components(x_dir: Direction3<F>, y_dir: Direction3<F>, z_dir: Direction3<F>,
220 pos: Point3<F>) -> Mat4<F>
221 {
222 let x_dir: Vec3<F> = From::from(x_dir);
224 let y_dir: Vec3<F> = From::from(y_dir);
225 let z_dir: Vec3<F> = From::from(z_dir);
226
227 Mat4 { x: Vec4::new(x_dir.x, x_dir.y, x_dir.z, F::zero()),
229 y: Vec4::new(y_dir.x, y_dir.y, y_dir.z, F::zero()),
230 z: Vec4::new(z_dir.x, z_dir.y, z_dir.z, F::zero()),
231 p: Vec4::new(pos.0.x, pos.0.y, pos.0.z, F::one())
232 }
233 }
234
235 #[inline]
236 pub fn from_mat3(mat3: Mat3<F>, pos: Point3<F>) -> Mat4<F>
237 {
238 Mat4 { x: Vec4::new(mat3.x.x, mat3.x.y, mat3.x.z, F::zero()),
240 y: Vec4::new(mat3.y.x, mat3.y.y, mat3.y.z, F::zero()),
241 z: Vec4::new(mat3.z.x, mat3.z.y, mat3.z.z, F::zero()),
242 p: Vec4::new( pos.0.x, pos.0.y, pos.0.z, F::one())
243 }
244 }
245}
246
247impl<F: FullFloat> Default for Mat2<F> {
250 #[inline]
251 fn default() -> Mat2<F> {
252 Mat2::new( F::default(), F::default(),
253 F::default(), F::default() )
254 }
255}
256
257impl<F: FullFloat> Default for Mat3<F> {
258 #[inline]
259 fn default() -> Mat3<F> {
260 Mat3::new( F::default(), F::default(), F::default(),
261 F::default(), F::default(), F::default(),
262 F::default(), F::default(), F::default() )
263 }
264}
265
266impl<F: FullFloat> Default for Mat4<F> {
267 #[inline]
268 fn default() -> Mat4<F> {
269 Mat4::new( F::default(), F::default(), F::default(), F::default(),
270 F::default(), F::default(), F::default(), F::default(),
271 F::default(), F::default(), F::default(), F::default(),
272 F::default(), F::default(), F::default(), F::default() )
273 }
274}
275
276impl<F: FullFloat> Mat2<F> {
279 #[inline]
280 pub fn zero() -> Mat2<F>
281 {
282 Mat2::new( F::zero(), F::zero(),
283 F::zero(), F::zero() )
284 }
285}
286
287impl<F: FullFloat> Mat3<F> {
288 #[inline]
289 pub fn zero() -> Mat3<F>
290 {
291 Mat3::new( F::zero(), F::zero(), F::zero(),
292 F::zero(), F::zero(), F::zero(),
293 F::zero(), F::zero(), F::zero() )
294 }
295}
296
297impl<F: FullFloat> Mat4<F> {
298 #[inline]
299 pub fn zero() -> Mat4<F>
300 {
301 Mat4::new( F::zero(), F::zero(), F::zero(), F::zero(),
302 F::zero(), F::zero(), F::zero(), F::zero(),
303 F::zero(), F::zero(), F::zero(), F::zero(),
304 F::zero(), F::zero(), F::zero(), F::zero() )
305 }
306}
307
308impl<F: FullFloat> Mat2<F> {
311 #[inline]
312 pub fn identity() -> Mat2<F>
313 {
314 Mat2::new( F::one(), F::zero(),
315 F::zero(), F::one() )
316 }
317}
318
319impl<F: FullFloat> Mat3<F> {
320 #[inline]
321 pub fn identity() -> Mat3<F>
322 {
323 Mat3::new( F::one(), F::zero(), F::zero(),
324 F::zero(), F::one(), F::zero(),
325 F::zero(), F::zero(), F::one() )
326 }
327}
328
329impl<F: FullFloat> Mat4<F> {
330 #[inline]
331 pub fn identity() -> Mat4<F>
332 {
333 Mat4::new( F::one(), F::zero(), F::zero(), F::zero(),
334 F::zero(), F::one(), F::zero(), F::zero(),
335 F::zero(), F::zero(), F::one(), F::zero(),
336 F::zero(), F::zero(), F::zero(), F::one() )
337 }
338}
339
340impl<F: FullFloat> Mat2<F> {
343 #[inline]
344 pub fn transpose(&mut self) {
345 ::std::mem::swap(&mut self.x.y, &mut self.y.x);
346 }
347}
348
349impl<F: FullFloat> Mat3<F> {
350 #[inline]
351 pub fn transpose(&mut self) {
352 ::std::mem::swap(&mut self.x.y, &mut self.y.x);
353 ::std::mem::swap(&mut self.x.z, &mut self.z.x);
354 ::std::mem::swap(&mut self.y.z, &mut self.z.y);
355 }
356}
357
358impl<F: FullFloat> Mat4<F> {
359 #[inline]
360 pub fn transpose(&mut self) {
361 ::std::mem::swap(&mut self.x.y, &mut self.y.x);
362 ::std::mem::swap(&mut self.x.z, &mut self.z.x);
363 ::std::mem::swap(&mut self.x.w, &mut self.p.x);
364 ::std::mem::swap(&mut self.y.z, &mut self.z.y);
365 ::std::mem::swap(&mut self.y.w, &mut self.p.y);
366 ::std::mem::swap(&mut self.z.w, &mut self.p.z);
367 }
368}
369
370impl<F: FullFloat> Mat2<F> {
373 #[inline]
374 pub fn determinant(&self) -> F {
375 self.x.x * self.y.y - self.y.x * self.x.y
376 }
377
378 #[inline]
379 pub fn inverse(&self) -> Option<Mat2<F>> {
380 let d = self.determinant();
381 if d == F::zero() { return None; }
382 Some(Mat2::new( self.y.y/d, -self.y.x/d,
383 -self.x.y/d, self.x.x/d ))
384 }
385}
386
387impl<F: FullFloat> Mat3<F> {
388 #[inline]
389 pub fn determinant(&self) -> F {
390 self.x.x * (self.y.y * self.z.z - self.z.y * self.y.z)
391 - self.y.x * (self.x.y * self.z.z - self.z.y * self.x.z)
392 + self.z.x * (self.x.y * self.y.z - self.y.y * self.x.z)
393 }
394
395 #[inline]
396 pub fn inverse(&self) -> Option<Mat3<F>> {
397 let d = self.determinant();
398 if d == F::zero() { return None; }
399 let mut out = Mat3::from_cols(
400 self.y.cross(self.z) / d,
401 self.z.cross(self.x) / d,
402 self.x.cross(self.y) / d);
403 out.transpose();
404 Some(out)
405 }
406}
407
408impl<F: FullFloat> Mat4<F> {
409 #[inline]
410 pub fn determinant(&self) -> F {
411 self.x.x * Mat3::new( self.y.y, self.z.y, self.p.y,
412 self.y.z, self.z.z, self.p.z,
413 self.y.w, self.z.w, self.p.w ).determinant()
414 - self.y.x * Mat3::new( self.x.y, self.z.y, self.p.y,
415 self.x.z, self.z.z, self.p.z,
416 self.x.w, self.z.w, self.p.w ).determinant()
417 + self.z.x * Mat3::new( self.x.y, self.y.y, self.p.y,
418 self.x.z, self.y.z, self.p.z,
419 self.x.w, self.y.w, self.p.w ).determinant()
420 - self.p.x * Mat3::new( self.x.y, self.y.y, self.z.y,
421 self.x.z, self.y.z, self.z.z,
422 self.x.w, self.y.w, self.z.w ).determinant()
423 }
424
425 #[inline]
426 pub fn inverse(&self) -> Option<Mat4<F>> {
427 let d = self.determinant();
428 if d == F::zero() { return None; }
429 let id = F::one() / d;
430 let mut t = self.clone();
431 t.transpose();
432 let cf = |i, j| {
433 let mat = match i {
434 0 => Mat3::from_cols(t.y.truncate_n(j), t.z.truncate_n(j), t.p.truncate_n(j)),
435 1 => Mat3::from_cols(t.x.truncate_n(j), t.z.truncate_n(j), t.p.truncate_n(j)),
436 2 => Mat3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.p.truncate_n(j)),
437 3 => Mat3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.z.truncate_n(j)),
438 _ => panic!("out of range"),
439 };
440 let sign = if (i+j)&1 == 1 { -F::one() } else { F::one() };
441 mat.determinant() * sign *id
442 };
443
444 Some(Mat4::new( cf(0,0), cf(1,0), cf(2,0), cf(3,0),
445 cf(0,1), cf(1,1), cf(2,1), cf(3,1),
446 cf(0,2), cf(1,2), cf(2,2), cf(3,2),
447 cf(0,3), cf(1,3), cf(2,3), cf(3,3) ))
448 }
449}
450
451impl<'a, 'b, F: FullFloat> Add<&'b Mat2<F>> for &'a Mat2<F> {
454 type Output = Mat2<F>;
455
456 #[inline]
457 fn add(self, rhs: &Mat2<F>) -> Mat2<F> {
458 Mat2::new( self.x.x + rhs.x.x, self.y.x + rhs.y.x,
459 self.x.y + rhs.x.y, self.y.y + rhs.y.y )
460 }
461}
462
463impl<'a, 'b, F: FullFloat> Add<&'b Mat3<F>> for &'a Mat3<F> {
464 type Output = Mat3<F>;
465
466 #[inline]
467 fn add(self, rhs: &Mat3<F>) -> Mat3<F> {
468 Mat3::new( self.x.x + rhs.x.x, self.y.x + rhs.y.x, self.z.x + rhs.z.x,
469 self.x.y + rhs.x.y, self.y.y + rhs.y.y, self.z.y + rhs.z.y,
470 self.x.z + rhs.x.z, self.y.z + rhs.y.z, self.z.z + rhs.z.z )
471 }
472}
473
474impl<'a, 'b, F: FullFloat> Add<&'b Mat4<F>> for &'a Mat4<F> {
475 type Output = Mat4<F>;
476
477 #[inline]
478 fn add(self, rhs: &Mat4<F>) -> Mat4<F> {
479 Mat4::new(
480 self.x.x + rhs.x.x, self.y.x + rhs.y.x, self.z.x + rhs.z.x, self.p.x + rhs.p.x,
481 self.x.y + rhs.x.y, self.y.y + rhs.y.y, self.z.y + rhs.z.y, self.p.y + rhs.p.y,
482 self.x.z + rhs.x.z, self.y.z + rhs.y.z, self.z.z + rhs.z.z, self.p.z + rhs.p.z,
483 self.x.w + rhs.x.w, self.y.w + rhs.y.z, self.z.w + rhs.z.w, self.p.w + rhs.p.w )
484 }
485}
486
487impl<'a, F: FullFloat> Mul<F> for &'a Mat2<F> {
490 type Output = Mat2<F>;
491
492 #[inline]
493 fn mul(self, rhs: F) -> Mat2<F> {
494 Mat2::new( self.x.x * rhs, self.y.x * rhs,
495 self.x.y * rhs, self.y.y * rhs )
496 }
497}
498
499impl<'a, F: FullFloat> Mul<F> for &'a Mat3<F> {
500 type Output = Mat3<F>;
501
502 #[inline]
503 fn mul(self, rhs: F) -> Mat3<F> {
504 Mat3::new( self.x.x * rhs, self.y.x * rhs, self.z.x * rhs,
505 self.x.y * rhs, self.y.y * rhs, self.z.y * rhs,
506 self.x.z * rhs, self.y.z * rhs, self.z.z * rhs )
507 }
508}
509
510impl<'a, F: FullFloat> Mul<F> for &'a Mat4<F> {
511 type Output = Mat4<F>;
512
513 #[inline]
514 fn mul(self, rhs: F) -> Mat4<F> {
515 Mat4::new( self.x.x * rhs, self.y.x * rhs, self.z.x * rhs, self.p.x * rhs,
516 self.x.y * rhs, self.y.y * rhs, self.z.y * rhs, self.p.y * rhs,
517 self.x.z * rhs, self.y.z * rhs, self.z.z * rhs, self.p.z * rhs,
518 self.x.w * rhs, self.y.w * rhs, self.z.w * rhs, self.p.w * rhs )
519 }
520}
521
522impl<'a, 'b, F: FullFloat> Mul<&'b Mat2<F>> for &'a Mat2<F> {
525 type Output = Mat2<F>;
526
527 #[inline]
528 fn mul(self, rhs: &Mat2<F>) -> Mat2<F> {
529 Mat2::new(
530 self.x.x * rhs.x.x + self.y.x * rhs.x.y, self.x.x * rhs.y.x + self.y.x * rhs.y.y,
531 self.x.y * rhs.x.x + self.y.y * rhs.x.y, self.x.y * rhs.y.x + self.y.y * rhs.y.y)
532 }
533}
534
535impl<'a, 'b, F: FullFloat> Mul<&'b Mat3<F>> for &'a Mat3<F> {
536 type Output = Mat3<F>;
537
538 #[inline]
539 fn mul(self, rhs: &Mat3<F>) -> Mat3<F> {
540 Mat3::new(
541 self.x.x * rhs.x.x + self.y.x * rhs.x.y + self.z.x * rhs.x.z,
542 self.x.x * rhs.y.x + self.y.x * rhs.y.y + self.z.x * rhs.y.z,
543 self.x.x * rhs.z.x + self.y.x * rhs.z.y + self.z.x * rhs.z.z,
544
545 self.x.y * rhs.x.x + self.y.y * rhs.x.y + self.z.y * rhs.x.z,
546 self.x.y * rhs.y.x + self.y.y * rhs.y.y + self.z.y * rhs.y.z,
547 self.x.y * rhs.z.x + self.y.y * rhs.z.y + self.z.y * rhs.z.z,
548
549 self.x.z * rhs.x.x + self.y.z * rhs.x.y + self.z.z * rhs.x.z,
550 self.x.z * rhs.y.x + self.y.z * rhs.y.y + self.z.z * rhs.y.z,
551 self.x.z * rhs.z.x + self.y.z * rhs.z.y + self.z.z * rhs.z.z)
552 }
553}
554
555impl<'a, 'b, F: FullFloat> Mul<&'b Mat4<F>> for &'a Mat4<F> {
556 type Output = Mat4<F>;
557
558 #[inline]
559 fn mul(self, rhs: &Mat4<F>) -> Mat4<F> {
560 Mat4::new(
561 self.x.x * rhs.x.x + self.y.x * rhs.x.y + self.z.x * rhs.x.z + self.p.x * rhs.x.w,
562 self.x.x * rhs.y.x + self.y.x * rhs.y.y + self.z.x * rhs.y.z + self.p.x * rhs.y.w,
563 self.x.x * rhs.z.x + self.y.x * rhs.z.y + self.z.x * rhs.z.z + self.p.x * rhs.z.w,
564 self.x.x * rhs.p.x + self.y.x * rhs.p.y + self.z.x * rhs.p.z + self.p.x * rhs.p.w,
565
566 self.x.y * rhs.x.x + self.y.y * rhs.x.y + self.z.y * rhs.x.z + self.p.y * rhs.x.w,
567 self.x.y * rhs.y.x + self.y.y * rhs.y.y + self.z.y * rhs.y.z + self.p.y * rhs.y.w,
568 self.x.y * rhs.z.x + self.y.y * rhs.z.y + self.z.y * rhs.z.z + self.p.y * rhs.z.w,
569 self.x.y * rhs.p.x + self.y.y * rhs.p.y + self.z.y * rhs.p.z + self.p.y * rhs.p.w,
570
571 self.x.z * rhs.x.x + self.y.z * rhs.x.y + self.z.z * rhs.x.z + self.p.z * rhs.x.w,
572 self.x.z * rhs.y.x + self.y.z * rhs.y.y + self.z.z * rhs.y.z + self.p.z * rhs.y.w,
573 self.x.z * rhs.z.x + self.y.z * rhs.z.y + self.z.z * rhs.z.z + self.p.z * rhs.z.w,
574 self.x.z * rhs.p.x + self.y.z * rhs.p.y + self.z.z * rhs.p.z + self.p.z * rhs.p.w,
575
576 self.x.w * rhs.x.x + self.y.w * rhs.x.y + self.z.w * rhs.x.z + self.p.w * rhs.x.w,
577 self.x.w * rhs.y.x + self.y.w * rhs.y.y + self.z.w * rhs.y.z + self.p.w * rhs.y.w,
578 self.x.w * rhs.z.x + self.y.w * rhs.z.y + self.z.w * rhs.z.z + self.p.w * rhs.z.w,
579 self.x.w * rhs.p.x + self.y.w * rhs.p.y + self.z.w * rhs.p.z + self.p.w * rhs.p.w )
580 }
581}
582
583impl<'a, 'b, F: FullFloat> Mul<&'a Vec2<F>> for &'b Mat2<F> {
586 type Output = Vec2<F>;
587
588 #[inline]
589 fn mul(self, rhs: &Vec2<F>) -> Vec2<F> {
590 Vec2::new( self.x.x * rhs.x + self.y.x * rhs.y,
591 self.x.y * rhs.x + self.y.y * rhs.y )
592 }
593}
594
595impl<'a, 'b, F: FullFloat> Mul<&'a Vec3<F>> for &'b Mat3<F> {
596 type Output = Vec3<F>;
597
598 #[inline]
599 fn mul(self, rhs: &Vec3<F>) -> Vec3<F> {
600 Vec3::new( self.x.x * rhs.x + self.y.x * rhs.y + self.z.x * rhs.z,
601 self.x.y * rhs.x + self.y.y * rhs.y + self.z.y * rhs.z,
602 self.x.z * rhs.x + self.y.z * rhs.y + self.z.z * rhs.z)
603 }
604}
605
606impl<'a, 'b, F: FullFloat> Mul<&'a Vec4<F>> for &'b Mat4<F> {
607 type Output = Vec4<F>;
608
609 #[inline]
610 fn mul(self, rhs: &Vec4<F>) -> Vec4<F> {
611 Vec4::new( self.x.x * rhs.x + self.y.x * rhs.y + self.z.x * rhs.z + self.p.x * rhs.w,
612 self.x.y * rhs.x + self.y.y * rhs.y + self.z.y * rhs.z + self.p.y * rhs.w,
613 self.x.z * rhs.x + self.y.z * rhs.y + self.z.z * rhs.z + self.p.z * rhs.w,
614 self.x.w * rhs.x + self.y.w * rhs.y + self.z.w * rhs.z + self.p.w * rhs.w)
615 }
616}
617
618impl<'a, 'b, F: FullFloat> Mul<&'a Mat2<F>> for &'a Vec2<F> {
621 type Output = Vec2<F>;
622
623 #[inline]
624 fn mul(self, rhs: &Mat2<F>) -> Vec2<F> {
625 Vec2::new( self.x * rhs.x.x + self.y * rhs.x.y,
626 self.x * rhs.y.x + self.y * rhs.y.y )
627 }
628}
629
630impl<'a, 'b, F: FullFloat> Mul<&'a Mat3<F>> for &'a Vec3<F> {
631 type Output = Vec3<F>;
632
633 #[inline]
634 fn mul(self, rhs: &Mat3<F>) -> Vec3<F> {
635 Vec3::new( self.x * rhs.x.x + self.y * rhs.x.y + self.z * rhs.x.z,
636 self.x * rhs.y.x + self.y * rhs.y.y + self.z * rhs.y.z,
637 self.x * rhs.z.x + self.y * rhs.z.y + self.z * rhs.z.z)
638 }
639}
640
641impl<'a, 'b, F: FullFloat> Mul<&'a Mat4<F>> for &'a Vec4<F> {
642 type Output = Vec4<F>;
643
644 #[inline]
645 fn mul(self, rhs: &Mat4<F>) -> Vec4<F> {
646 Vec4::new( self.x * rhs.x.x + self.y * rhs.x.y + self.z * rhs.x.z + self.w * rhs.x.w,
647 self.x * rhs.y.x + self.y * rhs.y.y + self.z * rhs.y.z + self.w * rhs.y.w,
648 self.x * rhs.z.x + self.y * rhs.z.y + self.z * rhs.z.z + self.w * rhs.z.w,
649 self.x * rhs.p.x + self.y * rhs.p.y + self.z * rhs.p.z + self.w * rhs.p.w)
650 }
651}
652
653impl<F: FullFloat> Mat2<F> {
656 #[inline]
657 pub fn is_diagonal(&self) -> bool {
658 self.x.y == F::zero() && self.y.x == F::zero()
659 }
660}
661
662impl<F: FullFloat> Mat3<F> {
663 #[inline]
664 pub fn is_diagonal(&self) -> bool {
665 self.x.y == F::zero() && self.x.z == F::zero() &&
666 self.y.x == F::zero() && self.y.z == F::zero() &&
667 self.z.x == F::zero() && self.z.y == F::zero()
668 }
669}
670
671impl<F: FullFloat> Mat4<F> {
672 #[inline]
673 pub fn is_diagonal(&self) -> bool {
674 self.x.y == F::zero() && self.x.z == F::zero() && self.x.w == F::zero() &&
675 self.y.x == F::zero() && self.y.z == F::zero() && self.y.w == F::zero() &&
676 self.z.x == F::zero() && self.z.y == F::zero() && self.p.w == F::zero() &&
677 self.p.x == F::zero() && self.p.y == F::zero() && self.z.z == F::zero()
678 }
679}
680
681impl<F: FullFloat> Mat2<F> {
682 #[inline]
683 pub fn is_symmetric(&self) -> bool {
684 self.x.y == self.y.x
685 }
686}
687
688
689impl<F: FullFloat> Mat3<F> {
690 #[inline]
691 pub fn is_symmetric(&self) -> bool {
692 self.x.y == self.y.x &&
693 self.x.z == self.z.x &&
694 self.y.z == self.z.y
695 }
696}
697
698impl<F: FullFloat> Mat4<F> {
699 #[inline]
700 pub fn is_symmetric(&self) -> bool {
701 self.x.y == self.y.x &&
702 self.x.z == self.z.x &&
703 self.x.w == self.p.x &&
704 self.y.z == self.z.y &&
705 self.y.w == self.p.y &&
706 self.z.w == self.p.z
707 }
708}
709
710impl<F: FullFloat> Mat2<F> {
711 #[inline]
712 pub fn is_skew_symmetric(&self) -> bool {
713 self.x.y == -self.y.x
714 }
715}
716
717impl<F: FullFloat> Mat3<F> {
718 #[inline]
719 pub fn is_skew_symmetric(&self) -> bool {
720 self.x.y == -self.y.x &&
721 self.x.z == -self.z.x &&
722 self.y.z == -self.z.y
723 }
724}
725
726impl<F: FullFloat> Mat4<F> {
727 #[inline]
728 pub fn is_skew_symmetric(&self) -> bool {
729 self.x.y == -self.y.x &&
730 self.x.z == -self.z.x &&
731 self.x.w == -self.p.x &&
732 self.y.z == -self.z.y &&
733 self.y.w == -self.p.y &&
734 self.z.w == -self.p.z
735 }
736}
737
738impl<F: FullFloat> Mat4<F> {
741 pub fn get_translation(&self) -> Point3<F>
742 {
743 Point3(self.p.truncate_w())
744 }
745}
746
747impl<F: FullFloat> Mat4<F> {
748 pub fn set_translation(&mut self, p: Point3<F>)
749 {
750 self.p = From::from(p);
751 }
752}
753
754impl<F: FullFloat> Mat2<F> {
757 #[inline]
758 pub fn from_angle(theta: Angle<F>) -> Mat2<F> {
759 let (s, c) = theta.as_radians().sin_cos();
760 Mat2 {
761 x: Vec2::new(c, s),
762 y: Vec2::new(-s, c),
763 }
764 }
765}
766
767impl<F: FullFloat> Mat3<F> {
768 #[inline]
769 pub fn from_angle_x(theta: Angle<F>) -> Mat3<F> {
770 let (s, c) = theta.as_radians().sin_cos();
771 Mat3::new( F::one(), F::zero(), F::zero(),
772 F::zero(), c, -s,
773 F::zero(), s, c )
774 }
775
776 #[inline]
777 pub fn from_angle_y(theta: Angle<F>) -> Mat3<F> {
778 let (s, c) = theta.as_radians().sin_cos();
779 Mat3::new( c, F::zero(), s,
780 F::zero(), F::one(), F::zero(),
781 -s, F::zero(), c )
782 }
783
784 #[inline]
785 pub fn from_angle_z(theta: Angle<F>) -> Mat3<F> {
786 let (s, c) = theta.as_radians().sin_cos();
787 Mat3::new( c, -s, F::zero(),
788 s, c, F::zero(),
789 F::zero(), F::zero(), F::one() )
790 }
791}
792
793impl<F: FullFloat> Mat3<F> {
794 pub fn rotate_axis_angle(axis: Direction3<F>, theta: Angle<F>) -> Mat3<F> {
797 let axis: Vec3<F> = From::from(axis);
798 let x = axis.x;
799 let y = axis.y;
800 let z = axis.z;
801 let (s, c) = theta.as_radians().sin_cos();
802 let ic = F::one() - c;
803 Mat3::new( x*x*ic + c , x*y*ic - z*s , x*z*ic + y*s,
804 y*x*ic + z*s , y*y*ic + c , y*z*ic - x*s,
805 z*x*ic - y*s , z*y*ic + x*s , z*z*ic + c )
806 }
807}
808
809impl<F: FullFloat> Mat4<F> {
810 #[inline]
811 pub fn from_angle_x(theta: Angle<F>) -> Mat4<F> {
812 let (s, c) = theta.as_radians().sin_cos();
813 Mat4::new( F::one(), F::zero(), F::zero(), F::zero(),
814 F::zero(), c, -s, F::zero(),
815 F::zero(), s, c, F::zero(),
816 F::zero(), F::zero(), F::zero(), F::one() )
817 }
818
819 #[inline]
820 pub fn from_angle_y(theta: Angle<F>) -> Mat4<F> {
821 let (s, c) = theta.as_radians().sin_cos();
822 Mat4::new( c , F::zero(), s, F::zero(),
823 F::zero(), F::one(), F::zero(), F::zero(),
824 -s , F::zero(), c, F::zero(),
825 F::zero(), F::zero(), F::zero(), F::one() )
826 }
827
828 #[inline]
829 pub fn from_angle_z(theta: Angle<F>) -> Mat4<F> {
830 let (s, c) = theta.as_radians().sin_cos();
831 Mat4::new( c , s, F::zero(), F::zero(),
832 -s , c, F::zero(), F::zero(),
833 F::zero(), F::zero(), F::one(), F::zero(),
834 F::zero(), F::zero(), F::zero(), F::one() )
835 }
836}
837
838impl<F: FullFloat> Mat4<F> {
839 pub fn rotate_axis_angle(axis: Direction3<F>, theta: Angle<F>) -> Mat4<F> {
842 let axis: Vec3<F> = From::from(axis);
843 let x = axis.x;
844 let y = axis.y;
845 let z = axis.z;
846 let (s, c) = theta.as_radians().sin_cos();
847 let ic = F::one() - c;
848 Mat4::new( x*x*ic + c , x*y*ic - z*s, x*z*ic + y*s, F::zero(),
849 y*x*ic + z*s, y*y*ic + c , y*z*ic - x*s, F::zero(),
850 z*x*ic - y*s, z*y*ic + x*s, z*z*ic + c , F::zero(),
851 F::zero(), F::zero(), F::zero(), F::one() )
852 }
853}
854
855impl<F: FullFloat> Mat3<F> {
858 #[inline]
859 pub fn reflect_origin_plane(a: Direction3<F>) -> Mat3<F> {
861 let a: Vec3<F> = From::from(a);
862 let minus_two: F = NumCast::from(-2.0_f32).unwrap();
863 let x: F = a.x * minus_two;
864 let y: F = a.y * minus_two;
865 let z: F = a.z * minus_two;
866 let axay = x * a.y;
867 let axaz = x * a.z;
868 let ayaz = y * a.z;
869 Mat3::new( x * a.x + F::one(), axay, axaz,
870 axay, y * a.y + F::one(), ayaz,
871 axaz, ayaz, z * a.z + F::one() )
872 }
873}
874
875impl<F: FullFloat> Mat3<F> {
876 #[inline]
877 pub fn involve_origin_plane(a: Direction3<F>) -> Mat3<F> {
879 let a: Vec3<F> = From::from(a);
880 let two: F = NumCast::from(2.0_f32).unwrap();
881 let x: F = a.x * two;
882 let y: F = a.y * two;
883 let z: F = a.z * two;
884 let axay = x * a.y;
885 let axaz = x * a.z;
886 let ayaz = y * a.z;
887 Mat3::new( x * a.x - F::one(), axay, axaz,
888 axay, y * a.y - F::one(), ayaz,
889 axaz, ayaz, z * a.z - F::one() )
890 }
891}
892
893impl<F: FullFloat> Mat3<F> {
896 #[inline]
897 pub fn scale(a: &Vec3<F>) -> Mat3<F> {
899 Mat3::new(a.x, F::zero(), F::zero(),
900 F::zero(), a.y, F::zero(),
901 F::zero(), F::zero(), a.z)
902 }
903}
904
905impl<F: FullFloat> Mat4<F> {
906 #[inline]
907 pub fn scale(a: &Vec4<F>) -> Mat4<F> {
909 Mat4::new(a.x, F::zero(), F::zero(), F::zero(),
910 F::zero(), a.y, F::zero(), F::zero(),
911 F::zero(), F::zero(), a.z, F::zero(),
912 F::zero(), F::zero(), F::zero(), a.w)
913 }
914}
915
916
917impl<F: FullFloat> Mat3<F> {
918 pub fn scale_in_direction(mut s: F, a: Direction3<F>) -> Mat3<F> {
920 let a: Vec3<F> = From::from(a);
921 s -= F::one();
922 let x = a.x * s;
923 let y = a.y * s;
924 let z = a.z * s;
925 let axay = x * a.y;
926 let axaz = x * a.z;
927 let ayaz = y * a.z;
928 Mat3::new(x * a.x + F::one(), axay, axaz,
929 axay, y * a.y + F::one(), ayaz,
930 axaz, ayaz, z * a.z + F::one())
931 }
932}
933
934impl<F: FullFloat> Mat4<F> {
935 pub fn get_x_scale(&self) -> F {
936 let scale = (self.x.x * self.x.x
937 + self.y.x * self.y.x
938 + self.z.x * self.z.x).sqrt();
939 if self.x.x < F::zero() { -scale } else { scale }
940 }
941
942 pub fn get_y_scale(&self) -> F {
943 let scale = (self.x.y * self.x.y
944 + self.y.y * self.y.y
945 + self.z.y * self.z.y).sqrt();
946 if self.y.y < F::zero() { -scale } else { scale }
947 }
948
949 pub fn get_z_scale(&self) -> F {
950 let scale = (self.x.z * self.x.z
951 + self.y.z * self.y.z
952 + self.z.z * self.z.z).sqrt();
953 if self.z.z < F::zero() { -scale } else { scale }
954 }
955}
956
957impl<F: FullFloat> Mat3<F> {
960 pub fn skew(angle: Angle<F>, a: Direction3<F>, proj: Direction3<F>) -> Mat3<F> {
964 let a: Vec3<F> = From::from(a);
965 let b: Vec3<F> = From::from(proj);
966 let t = angle.as_radians().tan();
967 let x: F = a.x * t;
968 let y: F = a.y * t;
969 let z: F = a.z * t;
970 Mat3::new(x * b.x + F::one(), x * b.y, x * b.z,
971 y * b.x, y * b.y + F::one(), y * b.z,
972 z * b.x, z * b.y, z * b.z + F::one())
973 }
974}
975
976impl From<Mat3<f32>> for Mat3<f64> {
980 fn from(m: Mat3<f32>) -> Mat3<f64> {
981 Mat3 {
982 x: Vec3 { x: m.x.x as f64, y: m.x.y as f64, z: m.x.z as f64 },
983 y: Vec3 { x: m.y.x as f64, y: m.y.y as f64, z: m.y.z as f64 },
984 z: Vec3 { x: m.z.x as f64, y: m.z.y as f64, z: m.z.z as f64 },
985 }
986 }
987}
988
989impl From<Mat3<f64>> for Mat3<f32> {
990 fn from(m: Mat3<f64>) -> Mat3<f32> {
991 Mat3 {
992 x: Vec3 { x: m.x.x as f32, y: m.x.y as f32, z: m.x.z as f32 },
993 y: Vec3 { x: m.y.x as f32, y: m.y.y as f32, z: m.y.z as f32 },
994 z: Vec3 { x: m.z.x as f32, y: m.z.y as f32, z: m.z.z as f32 },
995 }
996 }
997}
998
999impl From<Mat4<f32>> for Mat4<f64> {
1000 fn from(m: Mat4<f32>) -> Mat4<f64> {
1001 Mat4 {
1002 x: Vec4 { x: m.x.x as f64, y: m.x.y as f64, z: m.x.z as f64, w: m.x.w as f64 },
1003 y: Vec4 { x: m.y.x as f64, y: m.y.y as f64, z: m.y.z as f64, w: m.y.w as f64 },
1004 z: Vec4 { x: m.z.x as f64, y: m.z.y as f64, z: m.z.z as f64, w: m.z.w as f64 },
1005 p: Vec4 { x: m.p.x as f64, y: m.p.y as f64, z: m.p.z as f64, w: m.p.w as f64 },
1006 }
1007 }
1008}
1009
1010impl From<Mat4<f64>> for Mat4<f32> {
1011 fn from(m: Mat4<f64>) -> Mat4<f32> {
1012 Mat4 {
1013 x: Vec4 { x: m.x.x as f32, y: m.x.y as f32, z: m.x.z as f32, w: m.x.w as f32 },
1014 y: Vec4 { x: m.y.x as f32, y: m.y.y as f32, z: m.y.z as f32, w: m.y.w as f32 },
1015 z: Vec4 { x: m.z.x as f32, y: m.z.y as f32, z: m.z.z as f32, w: m.z.w as f32 },
1016 p: Vec4 { x: m.p.x as f32, y: m.p.y as f32, z: m.p.z as f32, w: m.p.w as f32 },
1017 }
1018 }
1019}
1020
1021impl<F: FullFloat> Mat4<F> {
1025 pub fn as_mat3(&self) -> Mat3<F> {
1026 Mat3 {
1027 x: Vec3::new(self.x.x, self.x.y, self.x.z),
1028 y: Vec3::new(self.y.x, self.y.y, self.y.z),
1029 z: Vec3::new(self.z.x, self.z.y, self.z.z),
1030 }
1031 }
1032}
1033
1034impl<F: FullFloat> Mat3<F> {
1035 pub fn as_mat4(&self) -> Mat4<F> {
1036 Mat4 {
1037 x: Vec4::new(self.x.x, self.x.y, self.x.z, F::zero()),
1038 y: Vec4::new(self.y.x, self.y.y, self.y.z, F::zero()),
1039 z: Vec4::new(self.z.x, self.z.y, self.z.z, F::zero()),
1040 p: Vec4::new(F::zero(), F::zero(), F::zero(), F::one()),
1041 }
1042 }
1043}
1044
1045impl<F: FullFloat> ApproxEq for Mat2<F> {
1049 type Flt = F;
1050
1051 fn approx_eq(&self, other: &Self,
1052 epsilon: <F as ApproxEq>::Flt,
1053 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
1054 {
1055 self.x.approx_eq(&other.x, epsilon, ulps) &&
1056 self.y.approx_eq(&other.y, epsilon, ulps)
1057 }
1058}
1059
1060impl<F: FullFloat> ApproxEq for Mat3<F> {
1061 type Flt = F;
1062
1063 fn approx_eq(&self, other: &Self,
1064 epsilon: <F as ApproxEq>::Flt,
1065 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
1066 {
1067 self.x.approx_eq(&other.x, epsilon, ulps) &&
1068 self.y.approx_eq(&other.y, epsilon, ulps) &&
1069 self.z.approx_eq(&other.z, epsilon, ulps)
1070 }
1071}
1072
1073impl<F: FullFloat> ApproxEq for Mat4<F> {
1074 type Flt = F;
1075
1076 fn approx_eq(&self, other: &Self,
1077 epsilon: <F as ApproxEq>::Flt,
1078 ulps: <<F as ApproxEq>::Flt as Ulps>::U) -> bool
1079 {
1080 self.x.approx_eq(&other.x, epsilon, ulps) &&
1081 self.y.approx_eq(&other.y, epsilon, ulps) &&
1082 self.z.approx_eq(&other.z, epsilon, ulps) &&
1083 self.p.approx_eq(&other.p, epsilon, ulps)
1084 }
1085}
1086
1087#[cfg(test)]
1090mod tests {
1091 use super::{Mat2, Mat3, Mat4, Angle};
1092 use super::super::vector::{Vec2, Vec3, Vec4, Direction3};
1093
1094 #[test]
1095 fn test_index() {
1096 let m: Mat2<f32> = Mat2::new(1.0, 2.0, 3.0, 4.0);
1097 assert_eq!(m[(0,0)], 1.0);
1098 assert_eq!(m[(0,1)], 2.0);
1099 assert_eq!(m[(1,0)], 3.0);
1100 assert_eq!(m[(1,1)], 4.0);
1101 }
1102
1103 #[test]
1104 fn test_transpose() {
1105 let mut m: Mat2<f32> = Mat2::new(1.0, 2.0,
1106 3.0, 4.0);
1107 m.transpose();
1108 assert_eq!(m, Mat2::new(1.0, 3.0,
1109 2.0, 4.0));
1110
1111 let mut m: Mat3<f32> = Mat3::new(1.0, 2.0, 3.0,
1112 4.0, 5.0, 6.0,
1113 7.0, 8.0, 9.0);
1114 m.transpose();
1115 assert_eq!(m, Mat3::new(1.0, 4.0, 7.0,
1116 2.0, 5.0, 8.0,
1117 3.0, 6.0, 9.0));
1118
1119 let mut m: Mat4<f32> = Mat4::new(1.0, 2.0, 3.0, 4.0,
1120 5.0, 6.0, 7.0, 8.0,
1121 9.0, 10.0, 11.0, 12.0,
1122 13.0, 14.0, 15.0, 16.0);
1123 m.transpose();
1124 assert_eq!(m, Mat4::new(1.0, 5.0, 9.0, 13.0,
1125 2.0, 6.0, 10.0, 14.0,
1126 3.0, 7.0, 11.0, 15.0,
1127 4.0, 8.0, 12.0, 16.0));
1128 }
1129
1130 #[test]
1131 fn test_mul_mat() {
1132 let left: Mat2<f32> = Mat2::new(1.0, 2.0, 3.0, 4.0);
1133 let right: Mat2<f32> = Mat2::new(6.0, 7.0, 8.0, 9.0);
1134 let product = &left * &right;
1135 assert_eq!(product, Mat2::new(22.0, 25.0,
1136 50.0, 57.0));
1137
1138 let left: Mat3<f32> = Mat3::new(1.0, 2.0, 3.0,
1139 4.0, 5.0, 6.0,
1140 7.0, 8.0, 9.0);
1141 let right: Mat3<f32> = Mat3::new(10.0, 11.0, 12.0,
1142 13.0, 14.0, 15.0,
1143 16.0, 17.0, 18.0);
1144 let product = &left * &right;
1145 assert_eq!(product[(0,0)], 84.0);
1146 assert_eq!(product[(0,1)], 90.0);
1147 assert_eq!(product[(0,2)], 96.0);
1148 assert_eq!(product[(1,0)], 201.0);
1149 assert_eq!(product[(1,1)], 216.0);
1150 assert_eq!(product[(1,2)], 231.0);
1151 assert_eq!(product[(2,0)], 318.0);
1152 assert_eq!(product[(2,1)], 342.0);
1153 assert_eq!(product[(2,2)], 366.0);
1154
1155 let left: Mat4<f32> = Mat4::new(1.0, 2.0, 3.0, 4.0,
1156 4.0, 3.0, 2.0, 1.0,
1157 5.0, 6.0, 2.0, 4.0,
1158 7.0, 1.0, 0.0, 3.0);
1159 let right: Mat4<f32> = Mat4::new(1.0, 6.0, 5.0, 2.0,
1160 3.0, 3.0, 3.0, 3.0,
1161 7.0, 8.0, 4.0, 1.0,
1162 9.0, 2.0, 0.0, 5.0);
1163 let product = &left * &right;
1164 assert_eq!(product[(0,0)], 64.0);
1165 assert_eq!(product[(0,1)], 44.0);
1166 assert_eq!(product[(0,2)], 23.0);
1167 assert_eq!(product[(0,3)], 31.0);
1168 assert_eq!(product[(1,0)], 36.0);
1169 assert_eq!(product[(1,1)], 51.0);
1170 assert_eq!(product[(1,2)], 37.0);
1171 assert_eq!(product[(1,3)], 24.0);
1172 assert_eq!(product[(2,0)], 73.0);
1173 assert_eq!(product[(2,1)], 72.0);
1174 assert_eq!(product[(2,2)], 51.0);
1175 assert_eq!(product[(2,3)], 50.0);
1176 assert_eq!(product[(3,0)], 37.0);
1177 assert_eq!(product[(3,1)], 51.0);
1178 assert_eq!(product[(3,2)], 38.0);
1179 assert_eq!(product[(3,3)], 32.0);
1180 }
1181
1182 #[test]
1183 fn test_mul_vec() {
1184 let left: Mat2<f32> = Mat2::new(1.0, 2.0,
1185 3.0, 4.0);
1186 let right: Vec2<f32> = Vec2::new(10.0, 20.0);
1187 let product = &left * &right;
1188 assert_eq!(product[0], 50.0);
1189 assert_eq!(product[1], 110.0);
1190 let product = &right * &left;
1191 assert_eq!(product[0], 70.0);
1192 assert_eq!(product[1], 100.0);
1193
1194 let left: Mat3<f32> = Mat3::new(1.0, 2.0, 3.0,
1195 4.0, 5.0, 6.0,
1196 7.0, 8.0, 9.0);
1197 let right: Vec3<f32> = Vec3::new(10.0, 20.0, 30.0);
1198 let product = &left * &right;
1199 assert_eq!(product[0], 140.0);
1200 assert_eq!(product[1], 320.0);
1201 assert_eq!(product[2], 500.0);
1202 let product = &right * &left;
1203 assert_eq!(product[0], 300.0);
1204 assert_eq!(product[1], 360.0);
1205 assert_eq!(product[2], 420.0);
1206
1207 let left: Mat4<f32> = Mat4::new(1.0, 2.0, 3.0, 4.0,
1208 5.0, 6.0, 7.0, 8.0,
1209 9.0, 10.0, 11.0, 12.0,
1210 13.0, 14.0, 15.0, 16.0);
1211 let right: Vec4<f32> = Vec4::new(1.0, 2.0, 3.0, 4.0);
1212 let product = &left * &right;
1213 assert_eq!(product[0], 30.0);
1214 assert_eq!(product[1], 70.0);
1215 assert_eq!(product[2], 110.0);
1216 assert_eq!(product[3], 150.0);
1217 let product = &right * &left;
1218 assert_eq!(product[0], 90.0);
1219 assert_eq!(product[1], 100.0);
1220 assert_eq!(product[2], 110.0);
1221 assert_eq!(product[3], 120.0);
1222 }
1223
1224 #[test]
1225 fn test_inverse() {
1226 assert_eq!(Mat2::<f64>::identity().inverse().unwrap(), Mat2::<f64>::identity());
1227 assert_eq!(Mat3::<f64>::identity().inverse().unwrap(), Mat3::<f64>::identity());
1228 assert_eq!(Mat4::<f64>::identity().inverse().unwrap(), Mat4::<f64>::identity());
1229
1230 let m = Mat3::new( 7.0, 2.0, 1.0,
1233 0.0, 3.0, -1.0,
1234 -3.0, 4.0, -2.0 );
1235 let inv = m.inverse().unwrap();
1236 assert_eq!(inv, Mat3::new( -2.0, 8.0, -5.0,
1237 3.0, -11.0, 7.0,
1238 9.0, -34.0, 21.0 ));
1239
1240 let m = Mat4::new( 1.0, 1.0, 1.0, 0.0,
1243 0.0, 3.0, 1.0, 2.0,
1244 2.0, 3.0, 1.0, 0.0,
1245 1.0, 0.0, 2.0, 1.0 );
1246 let inv = m.inverse().unwrap();
1247 assert_eq!(inv, Mat4::new( -3.0, -0.5, 1.5, 1.0,
1248 1.0, 0.25, -0.25, -0.5,
1249 3.0, 0.25, -1.25, -0.5,
1250 -3.0, 0.0, 1.0, 1.0 ));
1251 }
1252
1253 #[test]
1254 fn test_axis_angle() {
1255 let axis: Direction3<f32> = From::from(Vec3::new(1.0, 0.0, 0.0));
1256 let angle = Angle::new_radians(::std::f32::consts::FRAC_PI_4);
1257
1258 let start: Mat4<f32> = Mat4::new(
1259 1.0, 0.0, 0.0, 5.0,
1260 0.0, 1.0, 0.0, 5.0,
1261 0.0, 0.0, 1.0, 5.0,
1262 0.0, 0.0, 0.0, 1.0 );
1263
1264 let rot = Mat4::<f32>::rotate_axis_angle(axis, angle);
1265
1266 let end = &rot * &start;
1267
1268 let (s, c) = angle.as_radians().sin_cos();
1269 assert_eq!(end, Mat4::new(
1272 1.0, 0.0, 0.0, 5.0,
1273 0.0, c, -s, 0.0,
1274 0.0, s, c, c*10.0,
1275 0.0, 0.0, 0.0, 1.0));
1276 }
1277}