diff --git a/include/omath/vector2.hpp b/include/omath/vector2.hpp index 2c59b06f..8470d75e 100644 --- a/include/omath/vector2.hpp +++ b/include/omath/vector2.hpp @@ -190,6 +190,29 @@ namespace omath return x + y; } + [[nodiscard]] + bool operator<(const Vector2& other) const noexcept + { + return length() < other.length(); + } + [[nodiscard]] + bool operator>(const Vector2& other) const noexcept + { + return length() > other.length(); + } + + [[nodiscard]] + bool operator<=(const Vector2& other) const noexcept + { + return length() <= other.length(); + } + + [[nodiscard]] + bool operator>=(const Vector2& other) const noexcept + { + return length() >= other.length(); + } + [[nodiscard]] constexpr std::tuple as_tuple() const noexcept { diff --git a/include/omath/vector3.hpp b/include/omath/vector3.hpp index 662ff809..37490329 100644 --- a/include/omath/vector3.hpp +++ b/include/omath/vector3.hpp @@ -253,6 +253,30 @@ namespace omath return {angles::radians_to_degrees(std::asin(delta.z / distance)), angles::radians_to_degrees(std::atan2(delta.y, delta.x)), 0}; } + + [[nodiscard]] + bool operator<(const Vector3& other) const noexcept + { + return length() < other.length(); + } + + [[nodiscard]] + bool operator>(const Vector3& other) const noexcept + { + return length() > other.length(); + } + + [[nodiscard]] + bool operator<=(const Vector3& other) const noexcept + { + return length() <= other.length(); + } + + [[nodiscard]] + bool operator>=(const Vector3& other) const noexcept + { + return length() >= other.length(); + } }; } // namespace omath // ReSharper disable once CppRedundantNamespaceDefinition diff --git a/include/omath/vector4.hpp b/include/omath/vector4.hpp index 24d3d594..2815b454 100644 --- a/include/omath/vector4.hpp +++ b/include/omath/vector4.hpp @@ -89,7 +89,7 @@ namespace omath return Vector3::dot(other) + w * other.w; } - [[nodiscard]] Vector3 length() const noexcept + [[nodiscard]] Type length() const noexcept { return std::sqrt(length_sqr()); } @@ -158,6 +158,30 @@ namespace omath return Vector3::sum() + w; } + [[nodiscard]] + bool operator<(const Vector4& other) const noexcept + { + return length() < other.length(); + } + + [[nodiscard]] + bool operator>(const Vector4& other) const noexcept + { + return length() > other.length(); + } + + [[nodiscard]] + bool operator<=(const Vector4& other) const noexcept + { + return length() <= other.length(); + } + + [[nodiscard]] + bool operator>=(const Vector4& other) const noexcept + { + return length() >= other.length(); + } + #ifdef OMATH_IMGUI_INTEGRATION [[nodiscard]] ImVec4 to_im_vec4() const noexcept diff --git a/tests/general/unit_test_vector2.cpp b/tests/general/unit_test_vector2.cpp index 1896b152..b24bceaa 100644 --- a/tests/general/unit_test_vector2.cpp +++ b/tests/general/unit_test_vector2.cpp @@ -346,6 +346,28 @@ TEST_F(UnitTestVector2, NegationOperator_ZeroVector) EXPECT_FLOAT_EQ(result.y, -0.0f); } +TEST_F(UnitTestVector2, LessOperator) +{ + EXPECT_TRUE(v1 < v2); +} + +TEST_F(UnitTestVector2, GreaterOperator) +{ + EXPECT_TRUE(v2 > v1); +} +TEST_F(UnitTestVector2, LessEqualOperator) +{ + EXPECT_TRUE(omath::Vector2{} <= omath::Vector2{}); + EXPECT_TRUE(omath::Vector2{} <= omath::Vector2(1.f, 1.f)); +} + +TEST_F(UnitTestVector2, GreaterEqualOperator) +{ + EXPECT_TRUE(omath::Vector2{} >= omath::Vector2{}); + EXPECT_TRUE(omath::Vector2(1.f, 1.f) >= omath::Vector2{}); +} + + // Static assertions (compile-time checks) static_assert(Vector2(1.0f, 2.0f).length_sqr() == 5.0f, "LengthSqr should be 5"); static_assert(Vector2(1.0f, 2.0f).dot(Vector2(4.0f, 5.0f)) == 14.0f, "Dot product should be 14"); diff --git a/tests/general/unit_test_vector3.cpp b/tests/general/unit_test_vector3.cpp index 9cf66ef3..66e1a60f 100644 --- a/tests/general/unit_test_vector3.cpp +++ b/tests/general/unit_test_vector3.cpp @@ -402,6 +402,27 @@ TEST_F(UnitTestVector3, IsPerpendicular) EXPECT_FALSE(Vector3(0.0f, 0.0f, 0.0f).is_perpendicular({0.0f, 0.0f, 1.0f})); } +TEST_F(UnitTestVector3, LessOperator) +{ + EXPECT_TRUE(v1 < v2); +} + +TEST_F(UnitTestVector3, GreaterOperator) +{ + EXPECT_TRUE(v2 > v1); +} +TEST_F(UnitTestVector3, LessEqualOperator) +{ + EXPECT_TRUE(omath::Vector3{} <= omath::Vector3{}); + EXPECT_TRUE(omath::Vector3{} <= omath::Vector3(1.f, 1.f, 1.f)); +} + +TEST_F(UnitTestVector3, GreaterEqualOperator) +{ + EXPECT_TRUE(omath::Vector3{} >= omath::Vector3{}); + EXPECT_TRUE(omath::Vector3(1.f, 1.f, 1.f) >= omath::Vector3{}); +} + // Static assertions (compile-time checks) static_assert(Vector3(1.0f, 2.0f, 3.0f).length_sqr() == 14.0f, "LengthSqr should be 14"); static_assert(Vector3(1.0f, 2.0f, 3.0f).dot(Vector3(4.0f, 5.0f, 6.0f)) == 32.0f, "Dot product should be 32"); diff --git a/tests/general/unit_test_vector4.cpp b/tests/general/unit_test_vector4.cpp index dcdb7fea..6071a2c2 100644 --- a/tests/general/unit_test_vector4.cpp +++ b/tests/general/unit_test_vector4.cpp @@ -215,3 +215,23 @@ TEST_F(UnitTestVector4, Clamp) EXPECT_FLOAT_EQ(v3.z, 2.5f); EXPECT_FLOAT_EQ(v3.w, 4.0f); // w is not clamped in this method } +TEST_F(UnitTestVector4, LessOperator) +{ + EXPECT_TRUE(v1 < v2); +} + +TEST_F(UnitTestVector4, GreaterOperator) +{ + EXPECT_TRUE(v2 > v1); +} +TEST_F(UnitTestVector4, LessEqualOperator) +{ + EXPECT_TRUE(omath::Vector4{} <= omath::Vector4{}); + EXPECT_TRUE(omath::Vector4{} <= omath::Vector4(1.f, 1.f, 1.f, 1.f)); +} + +TEST_F(UnitTestVector4, GreaterEqualOperator) +{ + EXPECT_TRUE(omath::Vector4{} >= omath::Vector4{}); + EXPECT_TRUE(omath::Vector4(1.f, 1.f, 1.f, 1.f) >= omath::Vector4{}); +} \ No newline at end of file