openmaths/modules/
matrix3.rs

1use wasm_bindgen::prelude::*;
2use serde::{Serialize, Deserialize};
3
4#[wasm_bindgen]
5#[derive(Clone, Serialize, Deserialize)]
6pub struct Matrix3 {
7  elements: Vec<f64>,
8}
9
10/**
11 * Matrix3 Module
12 * Representation of a 3x3 Matrix
13 * It's a column-major matrix.
14 * When setting the elements, they are set in row-major order.
15 */
16#[wasm_bindgen]
17impl Matrix3 {
18  // #[wasm_bindgen(getter)]
19  // pub fn elements(&self) -> Vec<f64> {
20  //   self.elements.clone()
21  // }
22
23  // #[wasm_bindgen(setter)]
24  // pub fn set_elements(&mut self, elements: Vec<f64>) {
25  //   self.elements = elements;
26  // }
27
28  /**
29  * Create a new Matrix3 with identity elements.
30  */
31  #[wasm_bindgen(constructor)]
32  pub fn new() -> Matrix3 {
33    Matrix3 {
34      elements: vec![
35        1.0, 0.0, 0.0,
36        0.0, 1.0, 0.0,
37        0.0, 0.0, 1.0,
38      ],
39    }
40  }
41
42  pub fn set(
43    &mut self,
44    m0: f64, m1: f64, m2: f64,
45    m3: f64, m4: f64, m5: f64,
46    m6: f64, m7: f64, m8: f64,
47  ) -> Matrix3 {
48    let mut column_major_elements: Vec<f64> = vec![0.0; 9];
49
50    column_major_elements[0] = m0; column_major_elements[3] = m1; column_major_elements[6] = m2;
51    column_major_elements[1] = m3; column_major_elements[4] = m4; column_major_elements[7] = m5;
52    column_major_elements[2] = m6; column_major_elements[5] = m7; column_major_elements[8] = m8;
53
54    Matrix3 {
55      elements: column_major_elements,
56    }
57  }
58
59  /**
60  * Clone the Matrix3 instance and return a new one.
61  */
62  pub fn clone(&self) -> Matrix3 {
63    Matrix3 {
64      elements: self.elements.clone(),
65    }
66  }
67
68  /**
69  * Sets the matrix element to create an identity matrix.
70  */
71  pub fn identity(&mut self) {
72    self.elements = vec![
73      1.0, 0.0, 0.0,
74      0.0, 1.0, 0.0,
75      0.0, 0.0, 1.0,
76    ];
77  }
78
79  /**
80  * Determinant for a 3x3 matrix.
81  * https://en.wikipedia.org/wiki/Determinant
82  */
83  // TODO: Buggy, need to fix
84  pub fn determinant(&self) -> f64 {
85    self.elements[0] * (self.elements[4] * self.elements[8] - self.elements[5] * self.elements[7])
86      - self.elements[1] * (self.elements[3] * self.elements[8] - self.elements[5] * self.elements[6])
87      + self.elements[2] * (self.elements[3] * self.elements[7] - self.elements[4] * self.elements[6])
88  }
89
90  pub fn adjucate(&self) -> Matrix3 {
91    let mut adj = Matrix3::new();
92    adj.elements[0] = self.elements[4] * self.elements[8] - self.elements[5] * self.elements[7];
93    adj.elements[1] = self.elements[2] * self.elements[7] - self.elements[1] * self.elements[8];
94    adj.elements[2] = self.elements[1] * self.elements[5] - self.elements[2] * self.elements[4];
95    adj.elements[3] = self.elements[5] * self.elements[6] - self.elements[3] * self.elements[8];
96    adj.elements[4] = self.elements[0] * self.elements[8] - self.elements[2] * self.elements[6];
97    adj.elements[5] = self.elements[2] * self.elements[3] - self.elements[0] * self.elements[5];
98    adj.elements[6] = self.elements[3] * self.elements[7] - self.elements[4] * self.elements[6];
99    adj.elements[7] = self.elements[1] * self.elements[6] - self.elements[0] * self.elements[7];
100    adj.elements[8] = self.elements[0] * self.elements[4] - self.elements[1] * self.elements[3];
101    adj
102  }
103
104  pub fn inverse(&self) -> Option<Matrix3> {
105    let det = self.determinant();
106    if det == 0.0 {
107      return None; // No inverse exists
108    }
109    let adj = self.adjucate();
110    let mut inv = Matrix3::new();
111    for i in 0..9 {
112      inv.elements[i] = adj.elements[i] / det;
113    }
114    Some(inv)
115  }
116
117  pub fn transpose(&self) -> Matrix3 {
118    let mut transposed = Matrix3::new();
119    transposed.elements[0] = self.elements[0];
120    transposed.elements[1] = self.elements[3];
121    transposed.elements[2] = self.elements[6];
122    transposed.elements[3] = self.elements[1];
123    transposed.elements[4] = self.elements[4];
124    transposed.elements[5] = self.elements[7];
125    transposed.elements[6] = self.elements[2];
126    transposed.elements[7] = self.elements[5];
127    transposed.elements[8] = self.elements[8];
128    transposed
129  }
130}
131