Browse Source

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.
pull/175/merge
Vladimír Vondruš 10 years ago
parent
commit
1dc1fc79b0
  1. 10
      src/Magnum/Math/Test/ComplexTest.cpp
  2. 21
      src/Magnum/Math/Test/DualComplexTest.cpp
  3. 26
      src/Magnum/Math/Test/DualQuaternionTest.cpp
  4. 10
      src/Magnum/Math/Test/QuaternionTest.cpp

10
src/Magnum/Math/Test/ComplexTest.cpp

@ -68,6 +68,7 @@ struct ComplexTest: Corrade::TestSuite::Tester {
void compare(); void compare();
void isNormalized(); void isNormalized();
template<class T> void isNormalizedEpsilon();
void addSubtract(); void addSubtract();
void negated(); void negated();
@ -103,6 +104,8 @@ ComplexTest::ComplexTest() {
&ComplexTest::compare, &ComplexTest::compare,
&ComplexTest::isNormalized, &ComplexTest::isNormalized,
&ComplexTest::isNormalizedEpsilon<Float>,
&ComplexTest::isNormalizedEpsilon<Double>,
&ComplexTest::addSubtract, &ComplexTest::addSubtract,
&ComplexTest::negated, &ComplexTest::negated,
@ -245,6 +248,13 @@ void ComplexTest::isNormalized() {
CORRADE_VERIFY(Complex::rotation(Deg(23.0f)).isNormalized()); CORRADE_VERIFY(Complex::rotation(Deg(23.0f)).isNormalized());
} }
template<class T> void ComplexTest::isNormalizedEpsilon() {
setTestCaseName(std::string{"isNormalizedEpsilon<"} + TypeTraits<T>::name() + ">");
CORRADE_VERIFY((Math::Complex<T>{T(0.801775644243754) + TypeTraits<T>::epsilon()/T(2.0), T(0.597625146975521)}.isNormalized()));
CORRADE_VERIFY(!(Math::Complex<T>{T(0.801775644243754) + TypeTraits<T>::epsilon()*T(2.0), T(0.597625146975521)}.isNormalized()));
}
void ComplexTest::addSubtract() { void ComplexTest::addSubtract() {
Complex a( 1.7f, -3.7f); Complex a( 1.7f, -3.7f);
Complex b(-3.6f, 0.2f); Complex b(-3.6f, 0.2f);

21
src/Magnum/Math/Test/DualComplexTest.cpp

@ -67,6 +67,8 @@ struct DualComplexTest: Corrade::TestSuite::Tester {
void convert(); void convert();
void isNormalized(); void isNormalized();
template<class T> void isNormalizedEpsilonRotation();
template<class T> void isNormalizedEpsilonTranslation();
void multiply(); void multiply();
@ -108,6 +110,10 @@ DualComplexTest::DualComplexTest() {
&DualComplexTest::convert, &DualComplexTest::convert,
&DualComplexTest::isNormalized, &DualComplexTest::isNormalized,
&DualComplexTest::isNormalizedEpsilonRotation<Float>,
&DualComplexTest::isNormalizedEpsilonRotation<Double>,
&DualComplexTest::isNormalizedEpsilonTranslation<Float>,
&DualComplexTest::isNormalizedEpsilonTranslation<Double>,
&DualComplexTest::multiply, &DualComplexTest::multiply,
@ -237,6 +243,21 @@ void DualComplexTest::isNormalized() {
CORRADE_VERIFY((DualComplex::rotation(Deg(23.0f))*DualComplex::translation({6.0f, 3.0f})).isNormalized()); CORRADE_VERIFY((DualComplex::rotation(Deg(23.0f))*DualComplex::translation({6.0f, 3.0f})).isNormalized());
} }
template<class T> void DualComplexTest::isNormalizedEpsilonRotation() {
setTestCaseName(std::string{"isNormalizedEpsilonRotation<"} + TypeTraits<T>::name() + ">");
CORRADE_VERIFY((Math::DualComplex<T>{{T(0.801775644243754) + TypeTraits<T>::epsilon()/T(2.0), T(0.597625146975521)}, {T(8018055.25501103), T(5975850.58193309)}}.isNormalized()));
CORRADE_VERIFY(!(Math::DualComplex<T>{{T(0.801775644243754) + TypeTraits<T>::epsilon()*T(2.0), T(0.597625146975521)}, {T(8018055.25501103), T(5975850.58193309)}}.isNormalized()));
}
template<class T> void DualComplexTest::isNormalizedEpsilonTranslation() {
setTestCaseName(std::string{"isNormalizedEpsilonTranslation<"} + TypeTraits<T>::name() + ">");
/* Translation does not affect normalization */
CORRADE_VERIFY((Math::DualComplex<T>{{T(0.801775644243754), T(0.597625146975521)}, {T(8018055.25501103), T(20.5)}}.isNormalized()));
CORRADE_VERIFY((Math::DualComplex<T>{{T(0.801775644243754), T(0.597625146975521)}, {T(8018055.25501103), T(-200000000.0)}}.isNormalized()));
}
void DualComplexTest::multiply() { void DualComplexTest::multiply() {
DualComplex a({-1.5f, 2.0f}, { 3.0f, -6.5f}); DualComplex a({-1.5f, 2.0f}, { 3.0f, -6.5f});
DualComplex b({ 2.0f, -7.5f}, {-0.5f, 1.0f});; DualComplex b({ 2.0f, -7.5f}, {-0.5f, 1.0f});;

26
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -70,6 +70,8 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester {
void convert(); void convert();
void isNormalized(); void isNormalized();
template<class T> void isNormalizedEpsilonRotation();
template<class T> void isNormalizedEpsilonTranslation();
void lengthSquared(); void lengthSquared();
void length(); void length();
@ -115,6 +117,10 @@ DualQuaternionTest::DualQuaternionTest() {
&DualQuaternionTest::convert, &DualQuaternionTest::convert,
&DualQuaternionTest::isNormalized, &DualQuaternionTest::isNormalized,
&DualQuaternionTest::isNormalizedEpsilonRotation<Float>,
&DualQuaternionTest::isNormalizedEpsilonRotation<Double>,
&DualQuaternionTest::isNormalizedEpsilonTranslation<Float>,
&DualQuaternionTest::isNormalizedEpsilonTranslation<Double>,
&DualQuaternionTest::lengthSquared, &DualQuaternionTest::lengthSquared,
&DualQuaternionTest::length, &DualQuaternionTest::length,
@ -260,7 +266,25 @@ void DualQuaternionTest::convert() {
void DualQuaternionTest::isNormalized() { void DualQuaternionTest::isNormalized() {
CORRADE_VERIFY(!DualQuaternion({{1.0f, 2.0f, 3.0f}, 4.0f}, {}).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<class T> void DualQuaternionTest::isNormalizedEpsilonRotation() {
setTestCaseName(std::string{"isNormalizedEpsilonRotation<"} + TypeTraits<T>::name() + ">");
CORRADE_VERIFY((Math::DualQuaternion<T>{{{T(0.199367934417197) + TypeTraits<T>::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>{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083) + TypeTraits<T>::epsilon()*T(2.0)}, {{T(0.440966117079373), T(-0.440120368706115), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized()));
}
template<class T> void DualQuaternionTest::isNormalizedEpsilonTranslation() {
setTestCaseName(std::string{"isNormalizedEpsilonTranslation<"} + TypeTraits<T>::name() + ">");
CORRADE_VERIFY((Math::DualQuaternion<T>{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083)}, {{T(0.440966117079373), T(-0.440120368706115) + TypeTraits<T>::epsilon()*T(2.0), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized()));
CORRADE_VERIFY(!(Math::DualQuaternion<T>{{{T(0.199367934417197), T(0.0), T(0.0)}, T(0.97992470462083)}, {{T(0.440966117079373) + TypeTraits<T>::epsilon()*T(4.0), T(-0.440120368706115), T(-0.344665143363806)}, T(-0.0897155704877387)}}.isNormalized()));
/* Large translation -- large epsilon */
CORRADE_VERIFY((Math::DualQuaternion<T>{{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128)}, {{T(5056871.9114386), T(-245303.943266211) + TypeTraits<T>::epsilon()*T(10000000.0), T(-606492.066475555)}, T(-6315.26116124973)}}.isNormalized()));
CORRADE_VERIFY(!(Math::DualQuaternion<T>{{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128)}, {{T(5056871.9114386), T(-245303.943266211) + TypeTraits<T>::epsilon()*T(20000000.0), T(-606492.066475555)}, T(-6315.26116124973)}}.isNormalized()));
} }
void DualQuaternionTest::lengthSquared() { void DualQuaternionTest::lengthSquared() {

10
src/Magnum/Math/Test/QuaternionTest.cpp

@ -68,6 +68,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester {
void compare(); void compare();
void isNormalized(); void isNormalized();
template<class T> void isNormalizedEpsilon();
void addSubtract(); void addSubtract();
void negated(); void negated();
@ -114,6 +115,8 @@ QuaternionTest::QuaternionTest() {
&QuaternionTest::compare, &QuaternionTest::compare,
&QuaternionTest::isNormalized, &QuaternionTest::isNormalized,
&QuaternionTest::isNormalizedEpsilon<Float>,
&QuaternionTest::isNormalizedEpsilon<Double>,
&QuaternionTest::addSubtract, &QuaternionTest::addSubtract,
&QuaternionTest::negated, &QuaternionTest::negated,
@ -248,6 +251,13 @@ void QuaternionTest::isNormalized() {
CORRADE_VERIFY(Quaternion::rotation(Deg(23.0f), Vector3::xAxis()).isNormalized()); CORRADE_VERIFY(Quaternion::rotation(Deg(23.0f), Vector3::xAxis()).isNormalized());
} }
template<class T> void QuaternionTest::isNormalizedEpsilon() {
setTestCaseName(std::string{"isNormalizedEpsilon<"} + TypeTraits<T>::name() + ">");
CORRADE_VERIFY((Math::Quaternion<T>{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128) + TypeTraits<T>::epsilon()/T(2.0)}.isNormalized()));
CORRADE_VERIFY(!(Math::Quaternion<T>{{T(0.0106550719778129), T(0.311128101752138), T(-0.0468823167023769)}, T(0.949151106053128) + TypeTraits<T>::epsilon()*T(2.0)}.isNormalized()));
}
void QuaternionTest::addSubtract() { void QuaternionTest::addSubtract() {
Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f); Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f);
Quaternion b({-0.5f, 1.4f, 3.0f}, 12.0f); Quaternion b({-0.5f, 1.4f, 3.0f}, 12.0f);

Loading…
Cancel
Save