1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use number_traits::{ApproxEq, Num, Signed}; use set::identity; #[inline] pub fn inverse<'a, 'b, T: Copy + Signed>(out: &'a mut [T; 4], a: &'b [T; 4]) -> &'a mut [T; 4] { let m11 = a[0]; let m12 = a[2]; let m21 = a[1]; let m22 = a[3]; let d = m11 * m22 - m12 * m21; if d != T::zero() { let inv_d = T::one() / d; out[0] = m22 * inv_d; out[1] = -m12 * inv_d; out[2] = -m21 * inv_d; out[3] = m11 * inv_d; out } else { identity(out) } } #[test] fn test_inverse() { let mut v = [0, 0, 0, 0]; inverse(&mut v, &[1, 0, 0, 1]); assert!(v == [1, 0, 0, 1]); } #[inline] pub fn determinant<'a, 'b, T: Copy + Num>(out: &'b [T; 4]) -> T { out[0] * out[3] - out[2] * out[1] } #[test] fn test_determinant() { assert_eq!(determinant(&[1, 0, 0, 1]), 1); } #[inline] pub fn transpose<'a, 'b, T: Copy + Num>(out: &'a mut [T; 4], a: &'b [T; 4]) -> &'a mut [T; 4] { out[0] = a[0]; out[1] = a[2]; out[2] = a[1]; out[3] = a[3]; out } #[test] fn test_transpose() { let mut v = [0, 0, 0, 0]; transpose(&mut v, &[1, 0, 0, 1]); assert_eq!(v, [1, 0, 0, 1]); } #[inline] pub fn eq<'a, T: Copy + Num + ApproxEq>(a: &'a [T; 4], b: &'a [T; 4]) -> bool { !ne(a, b) } #[inline] pub fn ne<'a, T: Copy + Num + ApproxEq>(a: &'a [T; 4], b: &'a [T; 4]) -> bool { !a[0].approx_eq(&b[0]) || !a[1].approx_eq(&b[1]) || !a[2].approx_eq(&b[2]) || !a[3].approx_eq(&b[3]) } #[test] fn test_ne() { assert_eq!( ne(&[1f32, 1f32, 1f32, 1f32], &[1f32, 1f32, 1f32, 1f32]), false ); assert_eq!( ne(&[0f32, 0f32, 0f32, 0f32], &[1f32, 1f32, 1f32, 1f32]), true ); }