From f69f3393ec467e2da4c3fb3492147cd37e35b2b1 Mon Sep 17 00:00:00 2001 From: Squareys Date: Mon, 5 Oct 2020 17:06:21 +0200 Subject: [PATCH] Math: Add DualQuaternion/DualComplex::from(rotation, translation) Signed-off-by: Squareys --- src/Magnum/Math/DualComplex.h | 16 ++++++++++++++++ src/Magnum/Math/DualQuaternion.h | 16 ++++++++++++++++ src/Magnum/Math/Matrix3.h | 5 ++++- src/Magnum/Math/Matrix4.h | 5 ++++- src/Magnum/Math/Test/DualComplexTest.cpp | 14 ++++++++++++++ src/Magnum/Math/Test/DualQuaternionTest.cpp | 15 +++++++++++++++ 6 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/Magnum/Math/DualComplex.h b/src/Magnum/Math/DualComplex.h index a35b2e58f..ecb4a9bed 100644 --- a/src/Magnum/Math/DualComplex.h +++ b/src/Magnum/Math/DualComplex.h @@ -106,6 +106,22 @@ template class DualComplex: public Dual> { return {Implementation::complexFromMatrix(matrix.rotationScaling()), Complex(matrix.translation())}; } + /** + * @brief Create dual complext from rotation complex and translation vector + * + * @f[ + * \hat c = r + \epsilon (v_x + iv_y) + * @f] + * + * @see @ref translation(), @ref rotation() + * @ref Matrix3::from(const Matrix2x2&, const Vector2&), + * @ref Matrix4::from(const Matrix3x3&, const Vector3&), + * @ref DualQuaternion::from(const Quaternion&, const Vector3&) + */ + static DualComplex from(const Complex& rotation, const Vector2& translation) { + return {rotation, Complex{translation}}; + } + /** * @brief Default constructor * diff --git a/src/Magnum/Math/DualQuaternion.h b/src/Magnum/Math/DualQuaternion.h index b10212b09..12a8a72dc 100644 --- a/src/Magnum/Math/DualQuaternion.h +++ b/src/Magnum/Math/DualQuaternion.h @@ -246,6 +246,22 @@ template class DualQuaternion: public Dual> { return {q, Quaternion(matrix.translation()/2)*q}; } + /** + * @brief Create dual quaternion from rotation quaternion and translation vector + * + * @f[ + * \hat q = r + \epsilon [\frac{\boldsymbol t}{2}, 0] r + * @f] + * + * @see @ref translation(), @ref rotation(), + * @ref Matrix3::from(const Matrix2x2&, const Vector2&), + * @ref Matrix4::from(const Matrix3x3&, const Vector3&), + * @ref DualComplex::from(const Complex&, const Vector2&) + */ + static DualQuaternion from(const Quaternion& rotation, const Vector3& translation) { + return {rotation, Quaternion{translation/T(2)}*rotation}; + } + /** * @brief Default constructor * diff --git a/src/Magnum/Math/Matrix3.h b/src/Magnum/Math/Matrix3.h index e299a4d7b..adaec6a7a 100644 --- a/src/Magnum/Math/Matrix3.h +++ b/src/Magnum/Math/Matrix3.h @@ -188,7 +188,10 @@ template class Matrix3: public Matrix3x3 { * @param translation Translation part (first two elements of * third column) * - * @see @ref rotationScaling(), @ref translation() const + * @see @ref rotationScaling(), @ref translation() const, + * @ref Matrix4::from(const Matrix3x3&, const Vector3&), + * @ref DualComplex::from(const Complex&, const Vector2&), + * @ref DualQuaternion::from(const Quaternion&, const Vector3&) */ constexpr static Matrix3 from(const Matrix2x2& rotationScaling, const Vector2& translation) { return {{rotationScaling[0], T(0)}, diff --git a/src/Magnum/Math/Matrix4.h b/src/Magnum/Math/Matrix4.h index ca3c5145e..81b7be0f3 100644 --- a/src/Magnum/Math/Matrix4.h +++ b/src/Magnum/Math/Matrix4.h @@ -421,7 +421,10 @@ template class Matrix4: public Matrix4x4 { * @param translation Translation part (first three elements of * fourth column) * - * @see @ref rotationScaling(), @ref translation() const + * @see @ref rotationScaling(), @ref translation() const, + * @ref Matrix3::from(const Matrix2x2&, const Vector2&), + * @ref DualComplex::from(const Complex&, const Vector2&), + * @ref DualQuaternion::from(const Quaternion&, const Vector3&) */ constexpr static Matrix4 from(const Matrix3x3& rotationScaling, const Vector3& translation) { return {{rotationScaling[0], T(0)}, diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index 669c66496..057fc864d 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -88,6 +88,8 @@ struct DualComplexTest: Corrade::TestSuite::Tester { void rotation(); void translation(); void combinedTransformParts(); + + void fromParts(); void matrix(); void matrixNotOrthogonal(); void transformVector(); @@ -146,6 +148,8 @@ DualComplexTest::DualComplexTest() { &DualComplexTest::rotation, &DualComplexTest::translation, &DualComplexTest::combinedTransformParts, + + &DualComplexTest::fromParts, &DualComplexTest::matrix, &DualComplexTest::matrixNotOrthogonal, &DualComplexTest::transformVector, @@ -414,6 +418,16 @@ void DualComplexTest::translation() { CORRADE_COMPARE(a.translation(), vec); } +void DualComplexTest::fromParts() { + Complex r = Complex::rotation(120.0_degf); + + Vector2 vec{1.0f, -3.5f}; + DualComplex t = DualComplex::translation(vec); + + DualComplex rt = t*DualComplex{r}; + CORRADE_COMPARE(DualComplex::from(r, vec), rt); +} + void DualComplexTest::combinedTransformParts() { Vector2 translation = Vector2(-1.5f, 2.75f); DualComplex a = DualComplex::translation(translation)*DualComplex::rotation(23.0_degf); diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index 20917423d..ad3cdd669 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -90,6 +90,8 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester { void rotationNotNormalized(); void translation(); void combinedTransformParts(); + + void fromParts(); void matrix(); void matrixNotOrthogonal(); void transformVector(); @@ -155,6 +157,8 @@ DualQuaternionTest::DualQuaternionTest() { &DualQuaternionTest::rotationNotNormalized, &DualQuaternionTest::translation, &DualQuaternionTest::combinedTransformParts, + + &DualQuaternionTest::fromParts, &DualQuaternionTest::matrix, &DualQuaternionTest::matrixNotOrthogonal, &DualQuaternionTest::transformVector, @@ -483,6 +487,17 @@ void DualQuaternionTest::combinedTransformParts() { CORRADE_COMPARE(b.translation(), Quaternion::rotation(23.0_degf, Vector3::xAxis()).transformVector(translation)); } +void DualQuaternionTest::fromParts() { + Vector3 axis(1.0f/Constants::sqrt3()); + Quaternion r = Quaternion::rotation(120.0_degf, axis); + + Vector3 vec(1.0f, -3.5f, 0.5f); + DualQuaternion t = DualQuaternion::translation(vec); + + DualQuaternion rt = t*DualQuaternion{r}; + CORRADE_COMPARE(DualQuaternion::from(r, vec), rt); +} + void DualQuaternionTest::matrix() { DualQuaternion q = DualQuaternion::rotation(23.0_degf, Vector3::xAxis())*DualQuaternion::translation({-1.0f, 2.0f, 3.0f}); Matrix4 m = Matrix4::rotationX(23.0_degf)*Matrix4::translation({-1.0f, 2.0f, 3.0f});