use std::ops::{Mul, MulAssign}; use crate::v3::V3; #[derive(Clone, Copy, Debug)] pub struct M3x3([[f64; 3]; 3]); impl M3x3 { pub fn init(v: f64) -> Self { Self([[v; 3]; 3]) } pub fn identity() -> Self { Self([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) } pub fn new(v: [[f64; 3]; 3]) -> Self { Self(v) } pub fn from_v3_rot(rot: V3) -> Self { M3x3::new_rotate_x(rot.0) * M3x3::new_rotate_y(rot.1) * M3x3::new_rotate_z(rot.2) } #[rustfmt::skip] pub fn new_rotate_x(angle: f64) -> Self { Self([ [1.0, 0.0, 0.0], [0.0, f64::cos(angle), -f64::sin(angle)], [0.0, f64::sin(angle), f64::cos(angle)], ]) } #[rustfmt::skip] pub fn new_rotate_y(angle: f64) -> Self { Self([ [ f64::cos(angle), 0.0, f64::sin(angle)], [ 0.0, 1.0, 0.0], [-f64::sin(angle), 0.0, f64::cos(angle)], ]) } #[rustfmt::skip] pub fn new_rotate_z(angle: f64) -> Self { Self([ [f64::cos(angle), -f64::sin(angle), 0.0], [f64::sin(angle), f64::cos(angle), 0.0], [ 0.0, 0.0, 1.0], ]) } } impl Mul for M3x3 { type Output = M3x3; fn mul(self, rhs: M3x3) -> Self::Output { let mut output = M3x3([[0.0; 3]; 3]); for i in 0..3 { for j in 0..3 { let v = &mut output.0[i][j]; for k in 0..3 { *v += self.0[i][k] * rhs.0[k][j]; } } } output } } impl Mul for M3x3 { type Output = V3; fn mul(self, rhs: V3) -> Self::Output { let V3(x, y, z) = rhs; let [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]] = self.0; V3( x * xx + y * xy + z * xz, x * yx + y * yy + z * yz, x * zx + y * zy + z * zz, ) } } impl MulAssign for M3x3 { fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } }