From 3333dfee5133a9f145e10ff96bc44d56eefd67da Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 24 May 2024 10:44:03 -0400 Subject: [PATCH] Implement Matrix3x3::DeterminantSymmetric --- include/J3ML/LinearAlgebra/Matrix3x3.h | 11 ++++++----- src/J3ML/LinearAlgebra/Matrix3x3.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/J3ML/LinearAlgebra/Matrix3x3.h b/include/J3ML/LinearAlgebra/Matrix3x3.h index d394ab2..2be01b8 100644 --- a/include/J3ML/LinearAlgebra/Matrix3x3.h +++ b/include/J3ML/LinearAlgebra/Matrix3x3.h @@ -7,8 +7,6 @@ namespace J3ML::LinearAlgebra { - - /** Sets the top-left 3x3 area of the matrix to the rotation matrix about the X-axis. Elements outside the top-left 3x3 area are ignored. This matrix rotates counterclockwise if multiplied in the order M*v, and clockwise if rotated in the order v*M. @@ -110,9 +108,7 @@ namespace J3ML::LinearAlgebra { * * @note The member functions in this class use the convention that transforms are applied to * vectors in the form M * v. This means that "Matrix3x3 M, M1, M2; M = M1 * M2;" gives a transformation M - * that applies M2 first, followed by M1 second - */ - + * that applies M2 first, followed by M1 second. */ class Matrix3x3 { public: /// Constant Values enum { Rows = 3 }; @@ -409,6 +405,11 @@ namespace J3ML::LinearAlgebra { Matrix3x3 ScaleBy(const Vector3& rhs); Vector3 GetScale() const; + /// Scales the given row by a scalar value. + void ScaleRow(int row, float scalar); + /// Scales the given column by a scalar value. + void ScaleCol(int col, float scalar); + Vector3 operator[](int row) const; /// Transforms the given vector by this matrix (in the order M * v). diff --git a/src/J3ML/LinearAlgebra/Matrix3x3.cpp b/src/J3ML/LinearAlgebra/Matrix3x3.cpp index f55932b..e5262e2 100644 --- a/src/J3ML/LinearAlgebra/Matrix3x3.cpp +++ b/src/J3ML/LinearAlgebra/Matrix3x3.cpp @@ -615,6 +615,30 @@ namespace J3ML::LinearAlgebra { Vector3 Matrix3x3::Row(int index) const { return GetRow(index);} + float Matrix3x3::DeterminantSymmetric() const { + assert(IsSymmetric()); + + const float a = this->elems[0][0]; + const float b = this->elems[0][1]; + const float c = this->elems[0][2]; + const float d = this->elems[1][0]; + const float e = this->elems[1][1]; + const float f = this->elems[1][2]; + + // If the matrix is symmetric, it is of the following form: + // a b c + // b d e + // c e f + + // A direct cofactor expansion gives + // det = a * (df - ee) -b * (bf - ce) + c * (be-dc) + // = adf - aee - bbf + bce + bce - ccd + // = adf - aee - bbf - ccd + 2*bce + // = a(df-ee) + b(2*ce - bf) - ccd + + return a * (d*f - e*e) + b * (2.f * c * e - b * f) - c*c*d; + } + }