diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index 68ac147..5201392 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -6,7 +6,7 @@ namespace Hypercube.Mathematics.Vectors; [PublicAPI, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2 : IEquatable +public readonly partial struct Vector2 : IEquatable, IComparable { public static readonly Vector2 NaN = new(float.NaN, float.NaN); public static readonly Vector2 Zero = new(0, 0); @@ -279,4 +279,16 @@ public static float Cross(Vector2 a, Vector2 b) { return a.X * b.Y - a.Y * b.X; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Vector2 other) + { + return LengthSquared.CompareTo(other.LengthSquared); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Vector2 other, Func selector) + { + return selector(this).CompareTo(selector(other)); + } } \ No newline at end of file diff --git a/Hypercube.UnitTests/Math/CompareToTest.cs b/Hypercube.UnitTests/Math/CompareToTest.cs new file mode 100644 index 0000000..6f716ee --- /dev/null +++ b/Hypercube.UnitTests/Math/CompareToTest.cs @@ -0,0 +1,96 @@ +using System; +using Hypercube.Math.Vectors; +using NUnit.Framework; + +namespace Hypercube.UnitTests.Math; + +[TestFixture] +public sealed class CompareToTest +{ + [Test] + public void CompareTo_LengthComparison_ReturnsExpectedResult() + { + // Arrange + var vector1 = new Vector2(3, 4); // Length = 5 + var vector2 = new Vector2(6, 8); // Length = 10 + + // Act + var result = vector1.CompareTo(vector2); + + // Assert + Assert.Less(result, 0); + } + + [Test] + public void CompareTo_XComponentComparison_ReturnsExpectedResult() + { + // Arrange + var vector1 = new Vector2(3, 4); + var vector2 = new Vector2(6, 4); + + // Act + var result = vector1.CompareTo(vector2, v => v.X); + + // Assert + Assert.Less(result, 0); // Expecting vector1 to be "less than" vector2 based on X component + } + + [Test] + public void CompareTo_YComponentComparison_ReturnsExpectedResult() + { + // Arrange + var vector1 = new Vector2(3, 4); + var vector2 = new Vector2(3, 2); + + // Act + var result = vector1.CompareTo(vector2, v => v.Y); + + // Assert + Assert.Greater(result, 0); // Expecting vector1 to be "greater than" vector2 based on Y component + } + + [Test] + public void CompareTo_AngleComparison_ReturnsExpectedResult() + { + // Arrange + var vector1 = new Vector2(0, 1); // Angle = π/2 (90 degrees) + var vector2 = new Vector2(1, 0); // Angle = 0 degrees + + // Act + var result = vector1.CompareTo(vector2, v => v.Angle); + + // Assert + Assert.Greater(result, 0); // Expecting vector1 to be "greater than" vector2 based on Angle + } + + [Test] + public void CompareTo_SameVectors_ReturnsZero() + { + // Arrange + var vector1 = new Vector2(3, 4); + var vector2 = new Vector2(3, 4); + + // Act & Assert + Assert.AreEqual(0, vector1.CompareTo(vector2)); + Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.X)); + Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.Y)); + Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.Angle)); + } + + [Test] + public void CompareTo_DifferentComparisons_ReturnDifferentResults() + { + // Arrange + var vector1 = new Vector2(1, 2); + var vector2 = new Vector2(2, 1); + + // Act + var lengthComparison = vector1.CompareTo(vector2); + var xComponentComparison = vector1.CompareTo(vector2, v => v.X); + var yComponentComparison = vector1.CompareTo(vector2, v => v.Y); + + // Assert + Assert.AreNotEqual(lengthComparison, xComponentComparison); + Assert.AreNotEqual(xComponentComparison, yComponentComparison); + } +} \ No newline at end of file