From 9128820e357ed1b626e95cd4ff7da11b35f3cab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 13 Mar 2013 15:35:40 +0100 Subject: [PATCH] Math: ability to create Complex and DualComplex from matrix. --- src/Math/Complex.h | 24 +++++++++++++++++++++++- src/Math/DualComplex.h | 15 ++++++++++++++- src/Math/Test/ComplexTest.cpp | 8 ++++++++ src/Math/Test/DualComplexTest.cpp | 8 ++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/Math/Complex.h b/src/Math/Complex.h index 7f7d741bb..65c455b2e 100644 --- a/src/Math/Complex.h +++ b/src/Math/Complex.h @@ -37,6 +37,15 @@ namespace Magnum { namespace Math { +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + /* No assertions fired, for internal use */ + template inline static Complex complexFromMatrix(const Matrix<2, T>& matrix) { + return {matrix[0][0], matrix[0][1]}; + } +} +#endif + /** @brief %Complex number @tparam T Data type @@ -87,6 +96,18 @@ template class Complex { return {std::cos(T(angle)), std::sin(T(angle))}; } + /** + * @brief Create complex number from rotation matrix + * + * Expects that the matrix is orthogonal (i.e. pure rotation). + * @see toMatrix(), DualComplex::fromMatrix(), Matrix::isOrthogonal() + */ + inline static Complex fromMatrix(const Matrix<2, T>& matrix) { + CORRADE_ASSERT(matrix.isOrthogonal(), + "Math::Complex::fromMatrix(): the matrix is not orthogonal", {}); + return Implementation::complexFromMatrix(matrix); + } + /** * @brief Default constructor * @@ -164,7 +185,8 @@ template class Complex { * b & a * \end{pmatrix} * @f] - * @see DualComplex::toMatrix(), Matrix3::from(const Matrix<2, T>&, const Vector2&) + * @see fromMatrix(), DualComplex::toMatrix(), + * Matrix3::from(const Matrix<2, T>&, const Vector2&) */ Matrix<2, T> toMatrix() const { return {Vector<2, T>(_real, _imaginary), diff --git a/src/Math/DualComplex.h b/src/Math/DualComplex.h index bc2672234..f1cce6981 100644 --- a/src/Math/DualComplex.h +++ b/src/Math/DualComplex.h @@ -76,6 +76,19 @@ template class DualComplex: public Dual> { return {{}, {vector.x(), vector.y()}}; } + /** + * @brief Create dual complex number from rotation matrix + * + * Expects that the matrix represents rigid transformation. + * @see toMatrix(), Complex::fromMatrix(), + * Matrix3::isRigidTransformation() + */ + inline static DualComplex fromMatrix(const Matrix3& matrix) { + CORRADE_ASSERT(matrix.isRigidTransformation(), + "Math::DualComplex::fromMatrix(): the matrix doesn't represent rigid transformation", {}); + return {Implementation::complexFromMatrix(matrix.rotationScaling()), Complex(matrix.translation())}; + } + /** * @brief Default constructor * @@ -140,7 +153,7 @@ template class DualComplex: public Dual> { /** * @brief Convert dual complex number to transformation matrix * - * @see Complex::toMatrix() + * @see fromMatrix(), Complex::toMatrix() */ inline Matrix3 toMatrix() const { return Matrix3::from(this->real().toMatrix(), translation()); diff --git a/src/Math/Test/ComplexTest.cpp b/src/Math/Test/ComplexTest.cpp index 1cbc1d8af..75ad05df8 100644 --- a/src/Math/Test/ComplexTest.cpp +++ b/src/Math/Test/ComplexTest.cpp @@ -280,6 +280,14 @@ void ComplexTest::matrix() { Matrix2 m = Matrix3::rotation(Deg(37.0f)).rotationScaling(); CORRADE_COMPARE(a.toMatrix(), m); + + std::ostringstream o; + Error::setOutput(&o); + Complex::fromMatrix(m*2); + CORRADE_COMPARE(o.str(), "Math::Complex::fromMatrix(): the matrix is not orthogonal\n"); + + Complex b = Complex::fromMatrix(m); + CORRADE_COMPARE(b, a); } void ComplexTest::transformVector() { diff --git a/src/Math/Test/DualComplexTest.cpp b/src/Math/Test/DualComplexTest.cpp index 31ffb6385..b67f69259 100644 --- a/src/Math/Test/DualComplexTest.cpp +++ b/src/Math/Test/DualComplexTest.cpp @@ -225,6 +225,14 @@ void DualComplexTest::matrix() { Matrix3 m = Matrix3::rotation(Deg(23.0f))*Matrix3::translation({2.0f, 3.0f}); CORRADE_COMPARE(a.toMatrix(), m); + + std::ostringstream o; + Error::setOutput(&o); + DualComplex::fromMatrix(m*2); + CORRADE_COMPARE(o.str(), "Math::DualComplex::fromMatrix(): the matrix doesn't represent rigid transformation\n"); + + DualComplex b = DualComplex::fromMatrix(m); + CORRADE_COMPARE(b, a); } void DualComplexTest::transformPoint() {