diff --git a/src/GeometryHelper.cs b/src/GeometryHelper.cs new file mode 100644 index 0000000..c865935 --- /dev/null +++ b/src/GeometryHelper.cs @@ -0,0 +1,44 @@ +namespace Nine.Geometry +{ + using System.Numerics; + + public static class GeometryHelper + { + /// + /// Returns whether the points are in counter clockwise order. + /// + /// + /// + public static bool PointsAreCounterClockwiseOrder(Vector2[] points) + { + float signedArea = 0; + for (int i = 0; i < points.Length; i++) + { + int nextIndex = (i + 1) % points.Length; + signedArea += (points[nextIndex].X - points[i].X) + * (points[nextIndex].Y + points[i].Y); + } + + return signedArea < 0; + } + + /// + /// Returns whether the points are in counter clockwise order. + /// + /// + /// + public static bool PointsAreCounterClockwiseOrder(Vector3[] points) + { + float signedArea = 0; + for (int i = 0; i < points.Length; i++) + { + int nextIndex = (i + 1) % points.Length; + signedArea += (points[nextIndex].X - points[i].X) + * (points[nextIndex].Y + points[i].Y) + * (points[nextIndex].Z + points[i].Z); + } + + return signedArea < 0; + } + } +} diff --git a/test/GeometryHelperTest.cs b/test/GeometryHelperTest.cs new file mode 100644 index 0000000..b6c5d8b --- /dev/null +++ b/test/GeometryHelperTest.cs @@ -0,0 +1,68 @@ +namespace Nine.Geometry.Test +{ + using System.Numerics; + using Xunit; + + public class GeometryHelperTest + { + [Fact] + public void PointsAreCounterClockwiseOrder_Vector2() + { + var points = new Vector2[] + { + new Vector2(0, 0), + new Vector2(1, 0), + new Vector2(1, 1), + }; + + var counterClockwise = GeometryHelper.PointsAreCounterClockwiseOrder(points); + + Assert.True(counterClockwise); + } + + [Fact] + public void PointsAreCounterClockwiseOrder_Vector2_Clockwise() + { + var points = new Vector2[] + { + new Vector2(1, 1), + new Vector2(1, 0), + new Vector2(0, 0), + }; + + var counterClockwise = GeometryHelper.PointsAreCounterClockwiseOrder(points); + + Assert.False(counterClockwise); + } + + [Fact] + public void PointsAreCounterClockwiseOrder_Vector3() + { + var points = new Vector3[] + { + new Vector3(1, 1, 1), + new Vector3(1, 0, 1), + new Vector3(0, 0, 1), + }; + + var counterClockwise = GeometryHelper.PointsAreCounterClockwiseOrder(points); + + Assert.False(counterClockwise); + } + + [Fact] + public void PointsAreCounterClockwiseOrder_Vector3_Clockwise() + { + var points = new Vector3[] + { + new Vector3(1, 1, 1), + new Vector3(1, 0, 1), + new Vector3(0, 0, 1), + }; + + var counterClockwise = GeometryHelper.PointsAreCounterClockwiseOrder(points); + + Assert.False(counterClockwise); + } + } +}