From 5ff1020dcd4369ca701a666fb6bdc9c14be11969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 1 Sep 2013 17:14:12 +0200 Subject: [PATCH] Math: added Vector::isZero(). --- src/Math/Test/VectorTest.cpp | 7 +++++++ src/Math/TypeTraits.h | 16 ++++++++++++---- src/Math/Vector.h | 12 ++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 3b45e58da..c6aa1474c 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -62,6 +62,7 @@ class VectorTest: public Corrade::TestSuite::Tester { void constructConversion(); void constructCopy(); + void isZero(); void isNormalized(); void convert(); @@ -109,6 +110,7 @@ VectorTest::VectorTest() { &VectorTest::constructConversion, &VectorTest::constructCopy, + &VectorTest::isZero, &VectorTest::isNormalized, &VectorTest::convert, @@ -198,6 +200,11 @@ void VectorTest::constructCopy() { CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f)); } +void VectorTest::isZero() { + CORRADE_VERIFY(!Vector3(0.01f, 0.0f, 0.0f).isZero()); + CORRADE_VERIFY(Vector3(0.0f, 0.0f, 0.0f).isZero()); +} + void VectorTest::isNormalized() { CORRADE_VERIFY(!Vector3(1.0f, 2.0f, -1.0f).isNormalized()); CORRADE_VERIFY(Vector3(0.0f, 1.0f, 0.0f).isNormalized()); diff --git a/src/Math/TypeTraits.h b/src/Math/TypeTraits.h index 217e2275d..ce5708808 100644 --- a/src/Math/TypeTraits.h +++ b/src/Math/TypeTraits.h @@ -183,6 +183,14 @@ template<> struct TypeTraits: Implementation::TypeTraitsFloatingPoi constexpr static long double epsilon() { return LONG_DOUBLE_EQUALITY_PRECISION; } }; +namespace Implementation { + +/* Proper comparison should be with epsilon^2, but the value is not + representable in given precision. Comparing to epsilon instead. */ +template inline bool isZeroSquared(T lengthSquared) { + return std::abs(lengthSquared) < TypeTraits::epsilon(); +} + /* Comparing squared length to 1 is not sufficient to compare within range [1 - epsilon, 1 + epsilon], as e.g. Quaternion with dot() = 1 + 1e-7 when converted to matrix has column vectors with dot() = 1 + 1e-6, which is just @@ -190,10 +198,10 @@ template<> struct TypeTraits: Implementation::TypeTraitsFloatingPoi [1 - epsilon, 1 + epsilon] or dot() in range [1 - 2*epsilon + epsilon^2, 1 + 2*epsilon + epsilon^2]. Because epsilon^2 is way off machine precision, it's omitted. */ -namespace Implementation { - template inline bool isNormalizedSquared(T lengthSquared) { - return std::abs(lengthSquared - T(1)) < T(2)*TypeTraits::epsilon(); - } +template inline bool isNormalizedSquared(T lengthSquared) { + return std::abs(lengthSquared - T(1)) < T(2)*TypeTraits::epsilon(); +} + } #endif diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 42aaac41c..b90923b92 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -220,6 +220,18 @@ template class Vector { /** @brief Component-wise greater than */ BoolVector operator>(const Vector& other) const; + /** + * @brief Whether the vector is zero + * + * @f[ + * |\boldsymbol a \cdot \boldsymbol a - 0| < \epsilon^2 \cong \epsilon + * @f] + * @see dot(), normalized() + */ + bool isZero() const { + return Implementation::isZeroSquared(dot()); + } + /** * @brief Whether the vector is normalized *