diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index cb364335c..b5ca99653 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -79,6 +79,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void dotSelf(); void length(); void normalized(); + template void normalizedIterative(); void conjugated(); void inverted(); @@ -115,9 +116,13 @@ ComplexTest::ComplexTest() { &ComplexTest::dot, &ComplexTest::dotSelf, &ComplexTest::length, - &ComplexTest::normalized, + &ComplexTest::normalized}); - &ComplexTest::conjugated, + addRepeatedTests({ + &ComplexTest::normalizedIterative, + &ComplexTest::normalizedIterative}, 1000); + + addTests({&ComplexTest::conjugated, &ComplexTest::inverted, &ComplexTest::invertedNormalized, @@ -312,6 +317,18 @@ void ComplexTest::normalized() { CORRADE_COMPARE(a.normalized().length(), 1.0f); } +template void ComplexTest::normalizedIterative() { + setTestCaseName(std::string{"normalizedIterative<"} + TypeTraits::name() + ">"); + + auto a = Math::Complex::rotation(Math::Deg{T(36.7)}); + for(std::size_t i = 0; i != testCaseRepeatId(); ++i) { + a = Math::Complex::rotation(Math::Deg{T(87.1)})*a; + a = a.normalized(); + } + + CORRADE_VERIFY(a.isNormalized()); +} + void ComplexTest::conjugated() { CORRADE_COMPARE(Complex(-3.0f, 4.5f).conjugated(), Complex(-3.0f, -4.5f)); } diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index f4f34d5e8..033f4d710 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -75,6 +75,7 @@ struct DualComplexTest: Corrade::TestSuite::Tester { void lengthSquared(); void length(); void normalized(); + template void normalizedIterative(); void complexConjugated(); void dualConjugated(); @@ -119,9 +120,13 @@ DualComplexTest::DualComplexTest() { &DualComplexTest::lengthSquared, &DualComplexTest::length, - &DualComplexTest::normalized, + &DualComplexTest::normalized}); - &DualComplexTest::complexConjugated, + addRepeatedTests({ + &DualComplexTest::normalizedIterative, + &DualComplexTest::normalizedIterative}, 1000); + + addTests({&DualComplexTest::complexConjugated, &DualComplexTest::dualConjugated, &DualComplexTest::conjugated, &DualComplexTest::inverted, @@ -281,6 +286,28 @@ void DualComplexTest::normalized() { CORRADE_COMPARE(a.normalized(), b); } +namespace { + template struct NormalizedIterativeData; + template<> struct NormalizedIterativeData { + static Math::Vector2 translation() { return {10000.0f, -50.0f}; } + }; + template<> struct NormalizedIterativeData { + static Math::Vector2 translation() { return {10000000.0, -500.0}; } + }; +} + +template void DualComplexTest::normalizedIterative() { + setTestCaseName(std::string{"normalizedIterative<"} + TypeTraits::name() + ">"); + + auto a = Math::DualComplex::rotation(Math::Deg{T(36.7)})*Math::DualComplex::translation(NormalizedIterativeData::translation()); + for(std::size_t i = 0; i != testCaseRepeatId(); ++i) { + a = Math::DualComplex::rotation(Math::Deg{T(87.1)})*a; + a = a.normalized(); + } + + CORRADE_VERIFY(a.isNormalized()); +} + void DualComplexTest::complexConjugated() { DualComplex a({-1.0f, 2.5f}, {3.0f, -7.5f}); DualComplex b({-1.0f, -2.5f}, {3.0f, 7.5f}); diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index 4ceb749d2..338ededaf 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -76,6 +76,7 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester { void lengthSquared(); void length(); void normalized(); + template void normalizedIterative(); void quaternionConjugated(); void dualConjugated(); @@ -124,9 +125,13 @@ DualQuaternionTest::DualQuaternionTest() { &DualQuaternionTest::lengthSquared, &DualQuaternionTest::length, - &DualQuaternionTest::normalized, + &DualQuaternionTest::normalized}); - &DualQuaternionTest::quaternionConjugated, + addRepeatedTests({ + &DualQuaternionTest::normalizedIterative, + &DualQuaternionTest::normalizedIterative}, 1000); + + addTests({&DualQuaternionTest::quaternionConjugated, &DualQuaternionTest::dualConjugated, &DualQuaternionTest::conjugated, &DualQuaternionTest::inverted, @@ -304,6 +309,29 @@ void DualQuaternionTest::normalized() { CORRADE_COMPARE(a.normalized(), b); } +namespace { + template struct NormalizedIterativeData; + template<> struct NormalizedIterativeData { + static Math::Vector3 translation() { return {10000.0f, -50.0f, 20000.0f}; } + }; + template<> struct NormalizedIterativeData { + static Math::Vector3 translation() { return {10000000000000.0, -500.0, 20000000000000.0}; } + }; +} + +template void DualQuaternionTest::normalizedIterative() { + setTestCaseName(std::string{"normalizedIterative<"} + TypeTraits::name() + ">"); + + const auto axis = Math::Vector3{T(0.5), T(7.9), T(0.1)}.normalized(); + auto a = Math::DualQuaternion::rotation(Math::Deg{T(36.7)}, Math::Vector3{T(0.25), T(7.3), T(-1.1)}.normalized())*Math::DualQuaternion::translation(NormalizedIterativeData::translation()); + for(std::size_t i = 0; i != testCaseRepeatId(); ++i) { + a = Math::DualQuaternion::rotation(Math::Deg{T(87.1)}, axis)*a; + a = a.normalized(); + } + + CORRADE_VERIFY(a.isNormalized()); +} + void DualQuaternionTest::quaternionConjugated() { DualQuaternion a({{ 1.0f, 2.0f, 3.0f}, -4.0f}, {{ 0.5f, -3.1f, 3.3f}, 2.0f}); DualQuaternion b({{-1.0f, -2.0f, -3.0f}, -4.0f}, {{-0.5f, 3.1f, -3.3f}, 2.0f}); diff --git a/src/Magnum/Math/Test/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index 5e1174be5..e85fd26dc 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -79,6 +79,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester { void dotSelf(); void length(); void normalized(); + template void normalizedIterative(); void conjugated(); void inverted(); @@ -126,9 +127,13 @@ QuaternionTest::QuaternionTest() { &QuaternionTest::dot, &QuaternionTest::dotSelf, &QuaternionTest::length, - &QuaternionTest::normalized, + &QuaternionTest::normalized}); - &QuaternionTest::conjugated, + addRepeatedTests({ + &QuaternionTest::normalizedIterative, + &QuaternionTest::normalizedIterative}, 1000); + + addTests({&QuaternionTest::conjugated, &QuaternionTest::inverted, &QuaternionTest::invertedNormalized, @@ -308,6 +313,19 @@ void QuaternionTest::normalized() { CORRADE_COMPARE(normalized, Quaternion({1.0f, 3.0f, -2.0f}, -4.0f)/std::sqrt(30.0f)); } +template void QuaternionTest::normalizedIterative() { + setTestCaseName(std::string{"normalizedIterative<"} + TypeTraits::name() + ">"); + + const auto axis = Math::Vector3{T(0.5), T(7.9), T(0.1)}.normalized(); + auto a = Math::Quaternion::rotation(Math::Deg{T(36.7)}, Math::Vector3{T(0.25), T(7.3), T(-1.1)}.normalized()); + for(std::size_t i = 0; i != testCaseRepeatId(); ++i) { + a = Math::Quaternion::rotation(Math::Deg{T(87.1)}, axis)*a; + a = a.normalized(); + } + + CORRADE_VERIFY(a.isNormalized()); +} + void QuaternionTest::conjugated() { CORRADE_COMPARE(Quaternion({ 1.0f, 3.0f, -2.0f}, -4.0f).conjugated(), Quaternion({-1.0f, -3.0f, 2.0f}, -4.0f));