gmac/core/
algebra.rs

1/// Multiply two 3x3 matrices.
2///
3/// # Arguments
4/// * `a`: The first 3x3 matrix.
5/// * `b`: The second 3x3 matrix.
6///
7/// # Returns
8/// The product of the matrices as a 3x3 matrix [[f64; 3]; 3].
9pub fn mat3_mat3_mul(a: &[[f64; 3]; 3], b: &[[f64; 3]; 3]) -> [[f64; 3]; 3] {
10    [
11        [
12            a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0],
13            a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1],
14            a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2],
15        ],
16        [
17            a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0],
18            a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1],
19            a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2],
20        ],
21        [
22            a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0],
23            a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1],
24            a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2],
25        ],
26    ]
27}
28
29/// Multiply two 4x4 matrices.
30///
31/// # Arguments
32/// * `a`: The first 4x4 matrix.
33/// * `b`: The second 4x4 matrix.
34///
35/// # Returns
36/// The product of the matrices as a 4x4 matrix `[[f64; 4]; 4]`.
37pub fn mat4_mat4_mul(a: &[[f64; 4]; 4], b: &[[f64; 4]; 4]) -> [[f64; 4]; 4] {
38    [
39        [
40            a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0],
41            a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1],
42            a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2],
43            a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3],
44        ],
45        [
46            a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0],
47            a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1],
48            a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2],
49            a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3],
50        ],
51        [
52            a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0],
53            a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1],
54            a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2],
55            a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3],
56        ],
57        [
58            a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0],
59            a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1],
60            a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2],
61            a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3],
62        ],
63    ]
64}
65
66/// Multiply a 3x3 matrix with a 3x1 vector.
67///
68/// # Arguments
69/// * `a`: The first 3x3 matrix.
70/// * `b`: The second 3x1 vector.
71///
72/// # Returns
73/// The resulting vector [f64; 3].
74pub fn mat3_vec3_mul(a: &[[f64; 3]; 3], b: &[f64; 3]) -> [f64; 3] {
75    [
76        a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2],
77        a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2],
78        a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2],
79    ]
80}
81
82/// Multiply a 4x4 matrix with a 4x1 vector.
83///
84/// # Arguments
85/// * `a`: The first 4x4 matrix.
86/// * `b`: The second 4x1 vector.
87///
88/// # Returns
89/// The resulting vector [f64; 4].
90pub fn mat4_vec4_mul(a: &[[f64; 4]; 4], b: &[f64; 4]) -> [f64; 4] {
91    [
92        a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2] + a[0][3] * b[3],
93        a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2] + a[1][3] * b[3],
94        a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2] + a[2][3] * b[3],
95        a[3][0] * b[0] + a[3][1] * b[1] + a[3][2] * b[2] + a[3][3] * b[3],
96    ]
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn test_mat3_mat3_mul() {
105        let a = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
106
107        let b = [[9.0, 8.0, 7.0], [6.0, 5.0, 4.0], [3.0, 2.0, 1.0]];
108
109        let expected = [[30.0, 24.0, 18.0], [84.0, 69.0, 54.0], [138.0, 114.0, 90.0]];
110
111        let result = mat3_mat3_mul(&a, &b);
112        assert_eq!(result, expected);
113    }
114
115    #[test]
116    fn test_mat3_vec3_mul() {
117        let a = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
118
119        let b = [1.0, 2.0, 3.0];
120
121        let expected = [14.0, 32.0, 50.0];
122
123        let result = mat3_vec3_mul(&a, &b);
124        assert_eq!(result, expected);
125    }
126}