From f277b1038c37fdb11f48146c5f82a0c9dc96fbff Mon Sep 17 00:00:00 2001 From: Orange Date: Tue, 12 Aug 2025 08:54:33 +0300 Subject: [PATCH] Adds comparison operators to Vector types Adds less than, greater than, less than or equal, and greater than or equal operators to the Vector2, Vector3 and Vector4 classes. The comparison is based on the lengths of the vectors. Adds corresponding unit tests. --- include/omath/vector2.hpp | 23 +++++++++++++++++++++++ include/omath/vector3.hpp | 24 ++++++++++++++++++++++++ include/omath/vector4.hpp | 26 +++++++++++++++++++++++++- tests/general/unit_test_vector2.cpp | 22 ++++++++++++++++++++++ tests/general/unit_test_vector3.cpp | 21 +++++++++++++++++++++ tests/general/unit_test_vector4.cpp | 20 ++++++++++++++++++++ 6 files changed, 135 insertions(+), 1 deletion(-) 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