87 lines
2.1 KiB
Rust

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<V3> 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;
}
}