From 1dc1fc79b09e57c7a037999f396dc4950a92aee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 1 Sep 2016 19:04:39 +0200 Subject: [PATCH] Math: better test cases for {*Complex,Quaternion}::isNormalized(). The expectation is that the values are considered normalized only if the difference is small enough. This should have been tested since the beginning, but instead this was waved away with a dumb test case testing obviously denormalized value and obviously normalized value. The test fails for DualQuaternion with large translation values (as expected). Will be fixed in following commits. --- src/Magnum/Math/Test/ComplexTest.cpp | 10 ++++++++ src/Magnum/Math/Test/DualComplexTest.cpp | 21 +++++++++++++++++ src/Magnum/Math/Test/DualQuaternionTest.cpp | 26 ++++++++++++++++++++- src/Magnum/Math/Test/QuaternionTest.cpp | 10 ++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index 70e7c5862..cb364335c 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -68,6 +68,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void compare(); void isNormalized(); + template void isNormalizedEpsilon(); void addSubtract(); void negated(); @@ -103,6 +104,8 @@ ComplexTest::ComplexTest() { &ComplexTest::compare, &ComplexTest::isNormalized, + &ComplexTest::isNormalizedEpsilon, + &ComplexTest::isNormalizedEpsilon, &ComplexTest::addSubtract, &ComplexTest::negated, @@ -245,6 +248,13 @@ void ComplexTest::isNormalized() { CORRADE_VERIFY(Complex::rotation(Deg(23.0f)).isNormalized()); } +template void ComplexTest::isNormalizedEpsilon() { + setTestCaseName(std::string{"isNormalizedEpsilon<"} + TypeTraits::name() + ">"); + + CORRADE_VERIFY((Math::Complex{T(0.801775644243754) + TypeTraits::epsilon()/T(2.0), T(0.597625146975521)}.isNormalized())); + CORRADE_VERIFY(!(Math::Complex{T(0.801775644243754) + TypeTraits::epsilon()*T(2.0), T(0.597625146975521)}.isNormalized())); +} + void ComplexTest::addSubtract() { Complex a( 1.7f, -3.7f); Complex b(-3.6f, 0.2f); diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index f077bb0e8..f4f34d5e8 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -67,6 +67,8 @@ struct DualComplexTest: Corrade::TestSuite::Tester { void convert(); void isNormalized(); + template void isNormalizedEpsilonRotation(); + template void isNormalizedEpsilonTranslation(); void multiply(); @@ -108,6 +110,10 @@ DualComplexTest::DualComplexTest() { &DualComplexTest::convert, &DualComplexTest::isNormalized, + &DualComplexTest::isNormalizedEpsilonRotation, + &DualComplexTest::isNormalizedEpsilonRotation, + &DualComplexTest::isNormalizedEpsilonTranslation, + &DualComplexTest::isNormalizedEpsilonTranslation, &DualComplexTest::multiply, @@ -237,6 +243,21 @@ void DualComplexTest::isNormalized() { CORRADE_VERIFY((DualComplex::rotation(Deg(23.0f))*DualComplex::translation({6.0f, 3.0f})).isNormalized()); } +template void DualComplexTest::isNormalizedEpsilonRotation() { + setTestCaseName(std::string{"isNormalizedEpsilonRotation<"} + TypeTraits::name() + ">"); + + CORRADE_VERIFY((Math::DualComplex{{T(0.801775644243754) + TypeTraits::epsilon()/T(2.0), T(0.597625146975521)}, {T(8018055.25501103), T(5975850.58193309)}}.isNormalized())); + CORRADE_VERIFY(!(Math::DualComplex{{T(0.801775644243754) + TypeTraits::epsilon()*T(2.0), T(0.597625146975521)}, {T(8018055.25501103), T(5975850.58193309)}}.isNormalized())); +} + +template void DualComplexTest::isNormalizedEpsilonTranslation() { + setTestCaseName(std::string{"isNormalizedEpsilonTranslation<"} + TypeTraits::name() + ">"); + + /* Translation does not affect normalization */ + CORRADE_VERIFY((Math::DualComplex{{T(0.801775644243754), T(0.597625146975521)}, {T(8018055.25501103), T(20.5)}}.isNormalized())); + CORRADE_VERIFY((Math::DualComplex{{T(0.801775644243754), T(0.597625146975521)}, {T(8018055.25501103), T(-200000000.0)}}.isNormalized())); +} + void DualComplexTest::multiply() { DualComplex a({-1.5f, 2.0f}, { 3.0f, -6.5f}); DualComplex b({ 2.0f, -7.5f}, {-0.5f, 1.0f});; diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index a83535c10..4ceb749d2 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -70,6 +70,8 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester { void convert(); void isNormalized(); + template void isNormalizedEpsilonRotation(); + template void isNormalizedEpsilonTranslation(); void lengthSquared(); void length(); @@ -115,6 +117,10 @@ DualQuaternionTest::DualQuaternionTest() { &DualQuaternionTest::convert, &DualQuaternionTest::isNormalized, + &DualQuaternionTest::isNormalizedEpsilonRotation, + &DualQuaternionTest::isNormalizedEpsilonRotation, + &DualQuaternionTest::isNormalizedEpsilonTranslation, + &DualQuaternionTest::isNormalizedEpsilonTranslation, &DualQuaternionTest::lengthSquared, &DualQuaternionTest::length, @@ -260,7 +266,25 @@ void DualQuaternionTest::convert() { void DualQuaternionTest::isNormalized() { CORRADE_VERIFY(!DualQuaternion({{1.0f, 2.0f, 3.0f}, 4.0f}, {}).isNormalized()); - CORRADE_VERIFY((DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({3.0f, 1.0f, -0.5f})).isNormalized()); + CORRADE_VERIFY((DualQuaternion::rotation(Deg(23.0f), Vector3::xAxis())*DualQuaternion::translation({0.9f, -1.0f, -0.5f})).isNormalized()); +} + +template void DualQuaternionTest::isNormalizedEpsilonRotation() { + setTestCaseName(std::string{"isNormalizedEpsilonRotation<"} + TypeTraits::name() + ">"); + + CORRADE_VERIFY((Math::DualQuaternion{{{T(0.199367934417197) + TypeTraits::epsilon()/T(2.0), T(0.0), T(0.0)}, T(0.97992470462083)}, {{T(0.440966117079373), T(-0.440120368706115), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized())); + CORRADE_VERIFY(!(Math::DualQuaternion{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083) + TypeTraits::epsilon()*T(2.0)}, {{T(0.440966117079373), T(-0.440120368706115), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized())); +} + +template void DualQuaternionTest::isNormalizedEpsilonTranslation() { + setTestCaseName(std::string{"isNormalizedEpsilonTranslation<"} + TypeTraits::name() + ">"); + + CORRADE_VERIFY((Math::DualQuaternion{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083)}, {{T(0.440966117079373), T(-0.440120368706115) + TypeTraits::epsilon()*T(2.0), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized())); + CORRADE_VERIFY(!(Math::DualQuaternion{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083)}, {{T(0.440966117079373) + TypeTraits::epsilon()*T(4.0), T(-0.440120368706115), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized())); + + /* Large translation -- large epsilon */ + CORRADE_VERIFY((Math::DualQuaternion{{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128)}, {{T(5056871.9114386), T(-245303.943266211) + TypeTraits::epsilon()*T(10000000.0), T(-606492.066475555)}, T(-6315.26116124973)}}.isNormalized())); + CORRADE_VERIFY(!(Math::DualQuaternion{{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128)}, {{T(5056871.9114386), T(-245303.943266211) + TypeTraits::epsilon()*T(20000000.0), T(-606492.066475555)}, T(-6315.26116124973)}}.isNormalized())); } void DualQuaternionTest::lengthSquared() { diff --git a/src/Magnum/Math/Test/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index 908dc7ac3..5e1174be5 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -68,6 +68,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester { void compare(); void isNormalized(); + template void isNormalizedEpsilon(); void addSubtract(); void negated(); @@ -114,6 +115,8 @@ QuaternionTest::QuaternionTest() { &QuaternionTest::compare, &QuaternionTest::isNormalized, + &QuaternionTest::isNormalizedEpsilon, + &QuaternionTest::isNormalizedEpsilon, &QuaternionTest::addSubtract, &QuaternionTest::negated, @@ -248,6 +251,13 @@ void QuaternionTest::isNormalized() { CORRADE_VERIFY(Quaternion::rotation(Deg(23.0f), Vector3::xAxis()).isNormalized()); } +template void QuaternionTest::isNormalizedEpsilon() { + setTestCaseName(std::string{"isNormalizedEpsilon<"} + TypeTraits::name() + ">"); + + CORRADE_VERIFY((Math::Quaternion{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128) + TypeTraits::epsilon()/T(2.0)}.isNormalized())); + CORRADE_VERIFY(!(Math::Quaternion{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128) + TypeTraits::epsilon()*T(2.0)}.isNormalized())); +} + void QuaternionTest::addSubtract() { Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f); Quaternion b({-0.5f, 1.4f, 3.0f}, 12.0f);