diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index 1fe7c40d0..f639cd96a 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -102,6 +102,29 @@ template class Matrix: public RectangularMatrix& other): RectangularMatrix(other) {} + /** + * @brief Whether the matrix is orthogonal + * + * The matrix is orthogonal if its transpose is equal to its inverse: @f[ + * Q^T = Q^{-1} + * @f] + * @see transposed(), inverted() + */ + bool isOrthogonal() const { + /* Normality */ + for(std::size_t i = 0; i != size; ++i) + if(!TypeTraits::equals((*this)[i].dot(), T(1))) + return false; + + /* Orthogonality */ + for(std::size_t i = 0; i != size-1; ++i) + for(std::size_t j = i+1; j != size; ++j) + if(!TypeTraits::equals(Vector::dot((*this)[i], (*this)[j]), T(0))) + return false; + + return true; + } + /** * @brief Trace of the matrix * diff --git a/src/Math/Test/MatrixTest.cpp b/src/Math/Test/MatrixTest.cpp index 207580b65..bd7dca4c3 100644 --- a/src/Math/Test/MatrixTest.cpp +++ b/src/Math/Test/MatrixTest.cpp @@ -40,6 +40,8 @@ class MatrixTest: public Corrade::TestSuite::Tester { void constructConversion(); void constructCopy(); + void isOrthogonal(); + void trace(); void ij(); void determinant(); @@ -63,6 +65,8 @@ MatrixTest::MatrixTest() { &MatrixTest::constructConversion, &MatrixTest::constructCopy, + &MatrixTest::isOrthogonal, + &MatrixTest::trace, &MatrixTest::ij, &MatrixTest::determinant, @@ -139,6 +143,18 @@ void MatrixTest::constructCopy() { Vector4(7.9f, -1.0f, 8.0f, -1.5f))); } +void MatrixTest::isOrthogonal() { + CORRADE_VERIFY(!Matrix3(Vector3(1.0f, 0.0f, 0.0f), + Vector3(0.0f, 1.0f, 0.0f), + Vector3(0.0f, 0.1f, 1.0f)).isOrthogonal()); + CORRADE_VERIFY(!Matrix3(Vector3(1.0f, 0.0f, 0.0f), + Vector3(0.0f, 1.0f, 0.0f), + Vector3(0.0f, 1.0f, 0.0f)).isOrthogonal()); + CORRADE_VERIFY(Matrix3(Vector3(1.0f, 0.0f, 0.0f), + Vector3(0.0f, 1.0f, 0.0f), + Vector3(0.0f, 0.0f, 1.0f)).isOrthogonal()); +} + void MatrixTest::trace() { Matrix<5, Int> m( Vector<5, Int>(1, 2, 3, 0, 0),