Skip to content

Commit

Permalink
[Math/Vector] Reflected vector computation is restricted to signed types
Browse files Browse the repository at this point in the history
  • Loading branch information
Razakhel committed Sep 23, 2023
1 parent 80454bb commit 3355add
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 12 deletions.
2 changes: 1 addition & 1 deletion include/RaZ/Math/Vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class Vector {
/// \image html vector_reflect.jpg "Incident vector reflection"
/// \param normal Direction to compute the reflection over.
/// \return Vector's reflection.
constexpr Vector reflect(const Vector& normal) const noexcept { return (*this - normal * dot(normal) * 2); }
constexpr Vector reflect(const Vector& normal) const noexcept;
/// Computes the squared length of the vector.
/// The squared length is equal to the dot product of the vector with itself.
/// This calculation does not involve a square root; it is then to be preferred over computeLength() for faster operations.
Expand Down
7 changes: 7 additions & 0 deletions include/RaZ/Math/Vector.inl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ constexpr Vector<T, Size> Vector<T, Size>::cross(const Vector& vec) const noexce
return res;
}

template <typename T, std::size_t Size>
constexpr Vector<T, Size> Vector<T, Size>::reflect(const Vector& normal) const noexcept {
static_assert(std::is_signed_v<T>, "Error: The cross product can only be computed with vectors of a signed type.");

return (*this - normal * static_cast<T>(dot(normal)) * 2);
}

template <typename T, std::size_t Size>
template <typename NormedT>
constexpr Vector<NormedT, Size> Vector<T, Size>::normalize() const noexcept {
Expand Down
17 changes: 6 additions & 11 deletions tests/src/RaZ/Math/Vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,14 @@ TEST_CASE("Vector/matrix operations") {
CHECK((vec4f1 * Raz::Mat4f::identity()) == vec4f1);
}

TEST_CASE("Vector manipulations") {
CHECK_THAT(vec3f1.normalize().computeLength(), IsNearlyEqualTo(1.f));
CHECK_THAT(vec4f1.normalize().computeSquaredLength(), IsNearlyEqualTo(1.f));
CHECK_THAT(Raz::Vec3f(0.f, 1.f, 0.f).computeLength(), IsNearlyEqualTo(1.f));

// Testing Vector::reflect():
//
TEST_CASE("Vector reflection") {
// IncVec N Reflection
// \ | /
// \ | /
// \ ^ ^
// \ | /
//________\|/___________
//
// _______v|/_______

// The reflected vector cannot be computed for unsigned types

CHECK(Raz::Vec3f(1.f, -1.f, 0.f).reflect(Raz::Vec3f(0.f, 1.f, 0.f)) == Raz::Vec3f(1.f, 1.f, 0.f));
CHECK(vec3f1.reflect(Raz::Vec3f(0.f, 1.f, 0.f)) == Raz::Vec3f(3.18f, -42.f, 0.874f));
CHECK(vec3f1.reflect(vec3f2) == Raz::Vec3f(-4'019'108.859'878'28f, -350'714.439'453f, -46'922.543'011'268f));
Expand Down

0 comments on commit 3355add

Please sign in to comment.