Skip to content

Commit

Permalink
Adds more unit test coverage for UnitVec
Browse files Browse the repository at this point in the history
  • Loading branch information
louis-langholtz committed Oct 6, 2023
1 parent b229a06 commit 529a038
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 14 deletions.
25 changes: 11 additions & 14 deletions Library/include/playrho/d2/UnitVec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
/// @file
/// @brief Declarations of the UnitVec class and free functions associated with it.

#include <playrho/Settings.hpp>
#include <playrho/Units.hpp>
#include <playrho/InvalidArgument.hpp>

#include <cstdlib>
#include <iostream>
#include <utility>
#include <type_traits>

#include <playrho/InvalidArgument.hpp>
#include <playrho/Settings.hpp>
#include <playrho/Units.hpp>

namespace playrho {

// Explicitly import needed functions into this namespace to avoid including the math
Expand Down Expand Up @@ -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;
}

Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions UnitTests/UnitVec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ TEST(UnitVec, Get)
const auto value = std::numeric_limits<float>::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));
Expand Down

0 comments on commit 529a038

Please sign in to comment.