diff --git a/Library/include/playrho/d2/UnitVec.hpp b/Library/include/playrho/d2/UnitVec.hpp index 3bcdd08a97..0deae24aa3 100644 --- a/Library/include/playrho/d2/UnitVec.hpp +++ b/Library/include/playrho/d2/UnitVec.hpp @@ -24,15 +24,15 @@ /// @file /// @brief Declarations of the UnitVec class and free functions associated with it. -#include -#include -#include - #include #include #include #include +#include +#include +#include + namespace playrho { // Explicitly import needed functions into this namespace to avoid including the math @@ -128,13 +128,16 @@ class UnitVec { // Try the fastest way first... static constexpr auto t0 = T{}; - enum { None = 0x0, Left = 0x1, Right = 0x2, Up = 0x4, Down = 0x8 }; - switch (((x > t0)? Right: (x < t0) ? Left: None) | ((y > t0)? Up: (y < t0)? Down: None)) { + enum: unsigned { None = 0x0, Left = 0x1, Right = 0x2, Up = 0x4, Down = 0x8, NaN = 0xF }; + const auto xBits = (x > t0)? Right: (x < t0)? Left: (x == t0)? None: NaN; + const auto yBits = (y > t0)? Up: (y < t0)? Down: (y == t0)? None: NaN; + switch (xBits | yBits) { case Right: return std::make_pair(GetRight(), x); case Left: return std::make_pair(GetLeft(), -x); case Up: return std::make_pair(GetTop(), y); case Down: return std::make_pair(GetBottom(), -y); case None: return std::make_pair(fallback, T{}); + case NaN: return std::make_pair(fallback, T{}); default: break; } @@ -148,15 +151,9 @@ class UnitVec return {UnitVec{value_type{x * invMagnitude}, value_type{y * invMagnitude}}, magnitude}; } - // Failed the faster way, try the more accurate and robust way... + // Finally, try the more accurate and robust way... const auto magnitude = hypot(x, y); - if (isnormal(magnitude)) - { - return std::make_pair(UnitVec{x / magnitude, y / magnitude}, magnitude); - } - - // Give up and return the fallback value. - return std::make_pair(fallback, T{}); + return std::make_pair(UnitVec{x / magnitude, y / magnitude}, magnitude); } /// @brief Gets the given angled unit vector. diff --git a/UnitTests/UnitVec.cpp b/UnitTests/UnitVec.cpp index 5c93539e45..c4ebed9b55 100644 --- a/UnitTests/UnitVec.cpp +++ b/UnitTests/UnitVec.cpp @@ -207,6 +207,7 @@ TEST(UnitVec, Get) const auto value = std::numeric_limits::min(); const auto valueSquared = Square(value); ASSERT_EQ(valueSquared, 0.0f); + ASSERT_FALSE(isnormal(valueSquared)); const auto magnitude = hypot(value, value); ASSERT_NE(magnitude, 0.0f); ASSERT_TRUE(isnormal(magnitude));