diff options
Diffstat (limited to 'mons_math/src/mat3.c')
-rw-r--r-- | mons_math/src/mat3.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/mons_math/src/mat3.c b/mons_math/src/mat3.c new file mode 100644 index 0000000..f806375 --- /dev/null +++ b/mons_math/src/mat3.c @@ -0,0 +1,237 @@ +#include "mons_math/mat3.h" +#include "mons_math/mat2.h" +#include "mons_math/vec3.h" + +const mons_mat3 MONS_MAT3_ZERO = { + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, +}; + +const mons_mat3 MONS_MAT3_IDENTITY = { + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, +}; + +mons_mat3 mons_mat3_add(mons_mat3 a, mons_mat3 b) { + mons_mat3 result = { + mons_vec3_add(a.m1, b.m1), + mons_vec3_add(a.m2, b.m2), + mons_vec3_add(a.m3, b.m3), + }; + return result; +} + +void mons_mat3_add_inplace(mons_mat3 *a, mons_mat3 b) { + mons_vec3_add_inplace(&a->m1, b.m1); + mons_vec3_add_inplace(&a->m2, b.m2); + mons_vec3_add_inplace(&a->m3, b.m3); +} + +mons_mat3 mons_mat3_mul_f(mons_mat3 a, float b) { + mons_mat3 result = { + mons_vec3_mul_f(a.m1, b), + mons_vec3_mul_f(a.m2, b), + mons_vec3_mul_f(a.m3, b), + }; + return result; +} + +mons_mat3 mons_mat3_mul_i(mons_mat3 a, int b) { + mons_mat3 result = { + mons_vec3_mul_i(a.m1, b), + mons_vec3_mul_i(a.m2, b), + mons_vec3_mul_i(a.m3, b), + }; + return result; +} + +mons_mat3 mons_mat3_mul(mons_mat3 a, mons_mat3 b) { + mons_vec3 b_n1 = mons_mat3_n1(b); + mons_vec3 b_n2 = mons_mat3_n2(b); + mons_vec3 b_n3 = mons_mat3_n3(b); + + mons_mat3 result = { + { + mons_vec3_dot(a.m1, b_n1), + mons_vec3_dot(a.m1, b_n2), + mons_vec3_dot(a.m1, b_n3), + }, + { + mons_vec3_dot(a.m2, b_n1), + mons_vec3_dot(a.m2, b_n2), + mons_vec3_dot(a.m2, b_n3), + }, + { + mons_vec3_dot(a.m3, b_n1), + mons_vec3_dot(a.m3, b_n2), + mons_vec3_dot(a.m3, b_n3), + }, + }; + return result; +} + +void mons_mat3_mul_f_inplace(mons_mat3 *a, float b) { + mons_vec3_mul_f_inplace(&a->m1, b); + mons_vec3_mul_f_inplace(&a->m2, b); + mons_vec3_mul_f_inplace(&a->m3, b); +} + +void mons_mat3_mul_i_inplace(mons_mat3 *a, int b) { + mons_vec3_mul_i_inplace(&a->m1, b); + mons_vec3_mul_i_inplace(&a->m2, b); + mons_vec3_mul_i_inplace(&a->m3, b); +} + +mons_mat3 mons_mat3_transpose(mons_mat3 a) { + mons_mat3 result = { + mons_mat3_n1(a), + mons_mat3_n2(a), + mons_mat3_n3(a), + }; +} + +void mons_mat3_transpose_inplace(mons_mat3 *a) { *a = mons_mat3_transpose(*a); } + +mons_vec3 mons_mat3_n1(mons_mat3 a) { + mons_vec3 result = { + a.m1.x, + a.m2.x, + a.m3.x, + }; + return result; +} + +mons_vec3 mons_mat3_n2(mons_mat3 a) { + mons_vec3 result = { + a.m1.y, + a.m2.y, + a.m3.y, + }; + return result; +} + +mons_vec3 mons_mat3_n3(mons_mat3 a) { + mons_vec3 result = { + a.m1.z, + a.m2.z, + a.m3.z, + }; + return result; +} + +float mons_mat3_determinant(mons_mat3 a) { + /* + * a * det( + * e f + * h i + * ) + * - b * det( + * d f + * g i + * ) + * + c * det( + * d e + * g h + * ) + */ + mons_mat2 efhi = { + {a.m2.y, a.m2.z}, + {a.m3.y, a.m3.z}, + }; + mons_mat2 dfgi = { + {a.m2.x, a.m2.z}, + {a.m3.x, a.m3.z}, + }; + mons_mat2 degh = { + {a.m2.x, a.m2.y}, + {a.m3.x, a.m3.y}, + }; + + return (a.m1.x * mons_mat2_determinant(efhi)) - + (a.m1.y * mons_mat2_determinant(dfgi)) + + (a.m1.z * mons_mat2_determinant(degh)); +} + +mons_mat3 mons_mat3_minor(mons_mat3 a) { + // Get determinants of minors + // First row elements + mons_mat2 minor_1_1 = { + {a.m2.y, a.m2.z}, + {a.m3.y, a.m3.z}, + }; + float det_1_1 = mons_mat2_determinant(minor_1_1); + mons_mat2 minor_1_2 = { + {a.m2.x, a.m2.z}, + {a.m3.x, a.m3.z}, + }; + float det_1_2 = mons_mat2_determinant(minor_1_2); + mons_mat2 minor_1_3 = { + {a.m2.x, a.m2.y}, + {a.m3.x, a.m3.y}, + }; + float det_1_3 = mons_mat2_determinant(minor_1_3); + // Second row elements + mons_mat2 minor_2_1 = { + {a.m1.y, a.m1.z}, + {a.m3.y, a.m3.z}, + }; + float det_2_1 = mons_mat2_determinant(minor_2_1); + mons_mat2 minor_2_2 = { + {a.m1.x, a.m1.z}, + {a.m3.x, a.m3.z}, + }; + float det_2_2 = mons_mat2_determinant(minor_2_2); + mons_mat2 minor_2_3 = { + {a.m1.x, a.m1.y}, + {a.m3.x, a.m3.y}, + }; + float det_2_3 = mons_mat2_determinant(minor_2_3); + // Third row elements + mons_mat2 minor_3_1 = { + {a.m1.y, a.m1.z}, + {a.m2.y, a.m2.z}, + }; + float det_3_1 = mons_mat2_determinant(minor_3_1); + mons_mat2 minor_3_2 = { + {a.m1.x, a.m1.z}, + {a.m2.x, a.m2.z}, + }; + float det_3_2 = mons_mat2_determinant(minor_3_2); + mons_mat2 minor_3_3 = { + {a.m1.x, a.m1.y}, + {a.m2.x, a.m2.y}, + }; + float det_3_3 = mons_mat2_determinant(minor_3_3); + + mons_mat3 result = { + {det_1_1, det_1_2, det_1_3}, + {det_2_1, det_2_2, det_2_3}, + {det_3_1, det_3_2, det_3_3}, + }; + return result; +} + +mons_mat3 mons_mat3_cofactor(mons_mat3 a) { + mons_mat3 result = mons_mat3_minor(a); + result.m1.y *= -1; + result.m2.x *= -1; + result.m2.z *= -1; + result.m3.y *= -1; + return result; +} + +mons_mat3 mons_mat3_adjoint(mons_mat3 a) { + return mons_mat3_transpose(mons_mat3_cofactor(a)); +} + +mons_mat3 mons_mat3_inverse(mons_mat3 a) { + return mons_mat3_mul_f(mons_mat3_adjoint(a), + 1.0 / mons_mat3_determinant(a)); +} + +int mons_mat3_equal(mons_mat3 a, mons_mat3 b) { + return mons_vec3_equal(a.m1, b.m1) && mons_vec3_equal(a.m2, b.m2) && + mons_vec3_equal(a.m3, b.m3); +} |