From 12c9f092295ebbe4452ff50cdf4d7ad444638062 Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+ehemsley@users.noreply.github.com> Date: Sun, 8 Dec 2019 19:46:08 -0800 Subject: [PATCH] fix bug in Line iterator + comparison cleanup --- .gitignore | 3 +- Bonk/AABB.cs | 31 ++++++- Bonk/Bonk.csproj | 10 ++- Bonk/BroadPhase/SpatialHash.cs | 4 +- Bonk/MinkowskiDifference.cs | 41 ++++----- Bonk/NarrowPhase/EPA2D.cs | 5 +- Bonk/Shapes/Circle.cs | 31 +++---- Bonk/Shapes/Line.cs | 27 ++---- Bonk/Shapes/Point.cs | 19 ++-- Bonk/Shapes/Polygon.cs | 46 +++++----- Bonk/Shapes/Rectangle.cs | 38 ++++---- Bonk/Shapes/RectanglePolygonComparison.cs | 16 ++++ Bonk/Shapes/Simplex.cs | 47 ++++------ Test/EPA2DTest.cs | 10 +-- Test/Equality.cs | 104 +++++++++++++--------- Test/GJK2DTest.cs | 59 ++++++------ 16 files changed, 256 insertions(+), 235 deletions(-) create mode 100644 Bonk/Shapes/RectanglePolygonComparison.cs diff --git a/.gitignore b/.gitignore index 5ed3d3e..f768bd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin/ obj/ -.vscode \ No newline at end of file +.vscode +.vs diff --git a/Bonk/AABB.cs b/Bonk/AABB.cs index 246e1b1..1f47466 100644 --- a/Bonk/AABB.cs +++ b/Bonk/AABB.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Numerics; @@ -8,7 +9,7 @@ namespace MoonTools.Core.Bonk /// /// Axis-aligned bounding box. /// - public struct AABB + public struct AABB : IEquatable { public float MinX { get; private set; } public float MinY { get; private set; } @@ -31,6 +32,24 @@ namespace MoonTools.Core.Bonk }; } + public override bool Equals(object obj) + { + return obj is AABB aabb && Equals(aabb); + } + + public bool Equals(AABB other) + { + return MinX == other.MinX && + MinY == other.MinY && + MaxX == other.MaxX && + MaxY == other.MaxY; + } + + public override int GetHashCode() + { + return HashCode.Combine(MinX, MinY, MaxX, MaxY); + } + public AABB(float minX, float minY, float maxX, float maxY) { MinX = minX; @@ -38,5 +57,15 @@ namespace MoonTools.Core.Bonk MaxX = maxX; MaxY = maxY; } + + public static bool operator ==(AABB left, AABB right) + { + return left.Equals(right); + } + + public static bool operator !=(AABB left, AABB right) + { + return !(left == right); + } } } \ No newline at end of file diff --git a/Bonk/Bonk.csproj b/Bonk/Bonk.csproj index a8a2d64..17f86a7 100644 --- a/Bonk/Bonk.csproj +++ b/Bonk/Bonk.csproj @@ -15,8 +15,12 @@ https://github.com/MoonsideGames/MoonTools.Core.Bonk - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/Bonk/BroadPhase/SpatialHash.cs b/Bonk/BroadPhase/SpatialHash.cs index f29edd8..f87b53f 100644 --- a/Bonk/BroadPhase/SpatialHash.cs +++ b/Bonk/BroadPhase/SpatialHash.cs @@ -31,7 +31,7 @@ namespace MoonTools.Core.Bonk /// A unique ID for the shape-transform pair. /// /// - public void Insert(T id, IShape2D shape, Transform2D transform2D) + public void Insert(T id, TShape2D shape, Transform2D transform2D) where TShape2D : struct, IShape2D { var box = shape.AABB(transform2D); var minHash = Hash(box.MinX, box.MinY); @@ -60,7 +60,7 @@ namespace MoonTools.Core.Bonk /// /// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID. /// - public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D transform2D) + public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, TShape2D shape, Transform2D transform2D) where TShape2D : struct, IShape2D { var box = shape.AABB(transform2D); var minHash = Hash(box.MinX, box.MinY); diff --git a/Bonk/MinkowskiDifference.cs b/Bonk/MinkowskiDifference.cs index dce2e03..89d7c0d 100644 --- a/Bonk/MinkowskiDifference.cs +++ b/Bonk/MinkowskiDifference.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Numerics; using MoonTools.Core.Structs; @@ -10,51 +9,41 @@ namespace MoonTools.Core.Bonk /// public struct MinkowskiDifference : IEquatable { - private IShape2D shapeA; - private Transform2D transformA; - private IShape2D shapeB; - private Transform2D transformB; + private IShape2D ShapeA { get; } + private Transform2D TransformA { get; } + private IShape2D ShapeB { get; } + private Transform2D TransformB { get; } public MinkowskiDifference(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) { - this.shapeA = shapeA; - this.transformA = transformA; - this.shapeB = shapeB; - this.transformB = transformB; + ShapeA = shapeA; + TransformA = transformA; + ShapeB = shapeB; + TransformB = transformB; } public Vector2 Support(Vector2 direction) { - return shapeA.Support(direction, transformA) - shapeB.Support(-direction, transformB); + return ShapeA.Support(direction, TransformA) - ShapeB.Support(-direction, TransformB); } public override bool Equals(object other) { - if (other is MinkowskiDifference otherMinkowskiDifference) - { - return Equals(otherMinkowskiDifference); - } - - return false; + return other is MinkowskiDifference minkowskiDifference && Equals(minkowskiDifference); } public bool Equals(MinkowskiDifference other) { return - shapeA == other.shapeA && - transformA == other.transformA && - shapeB == other.shapeB && - transformB == other.transformB; + ShapeA == other.ShapeA && + TransformA == other.TransformA && + ShapeB == other.ShapeB && + TransformB == other.TransformB; } public override int GetHashCode() { - var hashCode = 974363698; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(shapeA); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(transformA); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(shapeB); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(transformB); - return hashCode; + return HashCode.Combine(ShapeA, TransformA, ShapeB, TransformB); } public static bool operator ==(MinkowskiDifference a, MinkowskiDifference b) diff --git a/Bonk/NarrowPhase/EPA2D.cs b/Bonk/NarrowPhase/EPA2D.cs index d14ca1b..5bb5715 100644 --- a/Bonk/NarrowPhase/EPA2D.cs +++ b/Bonk/NarrowPhase/EPA2D.cs @@ -12,7 +12,7 @@ using System.Numerics; namespace MoonTools.Core.Bonk { - enum PolygonWinding + internal enum PolygonWinding { Clockwise, CounterClockwise @@ -24,8 +24,7 @@ namespace MoonTools.Core.Bonk /// Returns a minimum separating vector in the direction from A to B. /// /// A simplex returned by the GJK algorithm. - /// - public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex2D simplex) + public static Vector2 Intersect(TShapeA shapeA, Transform2D Transform2DA, TShapeB shapeB, Transform2D Transform2DB, Simplex2D simplex) where TShapeA : struct, IShape2D where TShapeB : struct, IShape2D { var simplexVertices = simplex.Vertices.Select(vertex => vertex.ToVector2()).ToImmutableArray(); diff --git a/Bonk/Shapes/Circle.cs b/Bonk/Shapes/Circle.cs index 465a5f8..6b2a93b 100644 --- a/Bonk/Shapes/Circle.cs +++ b/Bonk/Shapes/Circle.cs @@ -7,9 +7,9 @@ namespace MoonTools.Core.Bonk /// /// A Circle is a shape defined by a radius. /// - public struct Circle : IShape2D, IEquatable + public struct Circle : IShape2D, IEquatable { - public int Radius { get; private set; } + public int Radius { get; } public Circle(int radius) { @@ -24,36 +24,31 @@ namespace MoonTools.Core.Bonk public AABB AABB(Transform2D transform2D) { return new AABB( - transform2D.Position.X - Radius * transform2D.Scale.X, - transform2D.Position.Y - Radius * transform2D.Scale.Y, - transform2D.Position.X + Radius * transform2D.Scale.X, - transform2D.Position.Y + Radius * transform2D.Scale.Y + transform2D.Position.X - (Radius * transform2D.Scale.X), + transform2D.Position.Y - (Radius * transform2D.Scale.Y), + transform2D.Position.X + (Radius * transform2D.Scale.X), + transform2D.Position.Y + (Radius * transform2D.Scale.Y) ); } public override bool Equals(object obj) { - if (obj is Circle other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Circle circle) - { - return Radius == circle.Radius; - } + return other is Circle circle && Equals(circle); + } - return false; + public bool Equals(Circle other) + { + return Radius == other.Radius; } public override int GetHashCode() { - return 598075851 + Radius.GetHashCode(); + return HashCode.Combine(Radius); } public static bool operator ==(Circle a, Circle b) diff --git a/Bonk/Shapes/Line.cs b/Bonk/Shapes/Line.cs index 8556b07..6e9f3eb 100644 --- a/Bonk/Shapes/Line.cs +++ b/Bonk/Shapes/Line.cs @@ -8,7 +8,7 @@ namespace MoonTools.Core.Bonk /// /// A line is a shape defined by exactly two points in space. /// - public struct Line : IShape2D, IEquatable + public struct Line : IShape2D, IEquatable { private Position2D v0; private Position2D v1; @@ -18,7 +18,7 @@ namespace MoonTools.Core.Bonk get { yield return v0; - yield return v0; + yield return v1; } } @@ -44,31 +44,22 @@ namespace MoonTools.Core.Bonk public override bool Equals(object obj) { - if (obj is IShape2D other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Line otherLine) - { - return (v0 == otherLine.v0 && v1 == otherLine.v1) || (v1 == otherLine.v0 && v0 == otherLine.v1); - } + return other is Line otherLine && Equals(otherLine); + } - return false; + public bool Equals(Line other) + { + return (v0 == other.v0 && v1 == other.v1) || (v1 == other.v0 && v0 == other.v1); } public override int GetHashCode() { - var hashCode = -851829407; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(v0); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(v1); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(Vertices); - return hashCode; + return HashCode.Combine(v0, v1); } public static bool operator ==(Line a, Line b) diff --git a/Bonk/Shapes/Point.cs b/Bonk/Shapes/Point.cs index 7daba13..c1fbc0b 100644 --- a/Bonk/Shapes/Point.cs +++ b/Bonk/Shapes/Point.cs @@ -5,7 +5,7 @@ using MoonTools.Core.Structs; namespace MoonTools.Core.Bonk { - public struct Point : IShape2D, IEquatable + public struct Point : IShape2D, IEquatable { private Position2D position; @@ -31,22 +31,17 @@ namespace MoonTools.Core.Bonk public override bool Equals(object obj) { - if (obj is IShape2D other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Point otherPoint) - { - return position == otherPoint.position; - } + return other is Point otherPoint && Equals(otherPoint); + } - return false; + public bool Equals(Point other) + { + return position == other.position; } public override int GetHashCode() diff --git a/Bonk/Shapes/Polygon.cs b/Bonk/Shapes/Polygon.cs index 877f8c0..504dcc1 100644 --- a/Bonk/Shapes/Polygon.cs +++ b/Bonk/Shapes/Polygon.cs @@ -12,16 +12,18 @@ namespace MoonTools.Core.Bonk /// A Shape defined by an arbitrary collection of vertices. /// NOTE: A Polygon must have more than 2 vertices, be convex, and should not have duplicate vertices. /// - public struct Polygon : IShape2D, IEquatable + public struct Polygon : IShape2D, IEquatable { private ImmutableArray vertices; - public IEnumerable Vertices { get { return vertices == null ? Enumerable.Empty() : vertices; } } + public IEnumerable Vertices { get { return vertices; } } + + public int VertexCount { get { return vertices.Length; } } // vertices are local to the origin - public Polygon(params Position2D[] vertices) // TODO: remove this, params is bad because it allocates an array + public Polygon(IEnumerable vertices) // TODO: remove this, params is bad because it allocates an array { - this.vertices = ImmutableArray.Create(vertices); + this.vertices = vertices.ToImmutableArray(); } public Polygon(ImmutableArray vertices) @@ -41,39 +43,31 @@ namespace MoonTools.Core.Bonk public override bool Equals(object obj) { - if (obj is IShape2D other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Polygon otherPolygon) - { - var q = from a in vertices - join b in otherPolygon.vertices on a equals b - select a; + return (other is Polygon otherPolygon && Equals(otherPolygon)) || (other is Rectangle rectangle && Equals(rectangle)); + } - return vertices.Length == otherPolygon.vertices.Length && q.Count() == vertices.Length; - } - else if (other is Rectangle rectangle) - { - var q = from a in vertices - join b in rectangle.Vertices on a equals b - select a; + public bool Equals(Polygon other) + { + var q = from a in vertices + join b in other.Vertices on a equals b + select a; - return vertices.Length == 4 && q.Count() == vertices.Length; - } + return vertices.Length == other.VertexCount && q.Count() == vertices.Length; + } - return false; + public bool Equals(Rectangle rectangle) + { + return RectanglePolygonComparison.Equals(this, rectangle); } public override int GetHashCode() { - return HashCode.Combine(vertices, Vertices); + return HashCode.Combine(Vertices); } public static bool operator ==(Polygon a, Polygon b) diff --git a/Bonk/Shapes/Rectangle.cs b/Bonk/Shapes/Rectangle.cs index 9e5a001..2e04491 100644 --- a/Bonk/Shapes/Rectangle.cs +++ b/Bonk/Shapes/Rectangle.cs @@ -10,7 +10,7 @@ namespace MoonTools.Core.Bonk /// /// A rectangle is a shape defined by a minimum and maximum X value and a minimum and maximum Y value. /// - public struct Rectangle : IShape2D, IEquatable + public struct Rectangle : IShape2D, IEquatable { public int MinX { get; } public int MinY { get; } @@ -48,36 +48,30 @@ namespace MoonTools.Core.Bonk public override bool Equals(object obj) { - if (obj is IShape2D other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Rectangle rectangle) - { - return MinX == rectangle.MinX && - MinY == rectangle.MinY && - MaxX == rectangle.MaxX && - MaxY == rectangle.MaxY; - } + return (other is Rectangle rectangle && Equals(rectangle)) || (other is Polygon polygon && Equals(polygon)); + } - return false; + public bool Equals(Rectangle other) + { + return MinX == other.MinX && + MinY == other.MinY && + MaxX == other.MaxX && + MaxY == other.MaxY; + } + + public bool Equals(Polygon other) + { + return RectanglePolygonComparison.Equals(other, this); } public override int GetHashCode() { - var hashCode = -1260800952; - hashCode = hashCode * -1521134295 + MinX.GetHashCode(); - hashCode = hashCode * -1521134295 + MinY.GetHashCode(); - hashCode = hashCode * -1521134295 + MaxX.GetHashCode(); - hashCode = hashCode * -1521134295 + MaxY.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(Vertices); - return hashCode; + return HashCode.Combine(MinX, MinY, MaxX, MaxY); } public static bool operator ==(Rectangle a, Rectangle b) diff --git a/Bonk/Shapes/RectanglePolygonComparison.cs b/Bonk/Shapes/RectanglePolygonComparison.cs new file mode 100644 index 0000000..34c7ef3 --- /dev/null +++ b/Bonk/Shapes/RectanglePolygonComparison.cs @@ -0,0 +1,16 @@ +using System.Linq; + +namespace MoonTools.Core.Bonk +{ + internal static class RectanglePolygonComparison + { + public static bool Equals(Polygon polygon, Rectangle rectangle) + { + var q = from a in polygon.Vertices + join b in rectangle.Vertices on a equals b + select a; + + return polygon.VertexCount == 4 && q.Count() == 4; + } + } +} diff --git a/Bonk/Shapes/Simplex.cs b/Bonk/Shapes/Simplex.cs index f8e6ad5..680f488 100644 --- a/Bonk/Shapes/Simplex.cs +++ b/Bonk/Shapes/Simplex.cs @@ -3,17 +3,18 @@ using System.Collections.Generic; using System.Numerics; using MoonTools.Core.Structs; using MoreLinq; +using System; namespace MoonTools.Core.Bonk { /// /// A simplex is a shape with up to n - 2 vertices in the nth dimension. /// - public struct Simplex2D : IShape2D + public struct Simplex2D : IShape2D, IEquatable { - Vector2 a; - Vector2? b; - Vector2? c; + private Vector2 a; + private Vector2? b; + private Vector2? c; public Vector2 A => a; public Vector2? B => b; @@ -28,15 +29,15 @@ namespace MoonTools.Core.Bonk public Simplex2D(Vector2 a) { this.a = a; - this.b = null; - this.c = null; + b = null; + c = null; } public Simplex2D(Vector2 a, Vector2 b) { this.a = a; this.b = b; - this.c = null; + c = null; } public Simplex2D(Vector2 a, Vector2 b, Vector2 c) @@ -73,36 +74,26 @@ namespace MoonTools.Core.Bonk public override bool Equals(object obj) { - if (obj is IShape2D other) - { - return Equals(other); - } - - return false; + return obj is IShape2D other && Equals(other); } public bool Equals(IShape2D other) { - if (other is Simplex2D otherSimplex) - { - if (Count != otherSimplex.Count) { return false; } - return Vertices.Intersect(otherSimplex.Vertices).Count() == Count; - } + return other is Simplex2D otherSimplex && Equals(otherSimplex); + } - return false; + public bool Equals(Simplex2D other) + { + var q = from a in Vertices + join b in other.Vertices on a equals b + select a; + + return Count == other.Count && q.Count() == Count; } public override int GetHashCode() { - var hashCode = -495772172; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(a); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(b); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(c); - hashCode = hashCode * -1521134295 + ZeroSimplex.GetHashCode(); - hashCode = hashCode * -1521134295 + OneSimplex.GetHashCode(); - hashCode = hashCode * -1521134295 + TwoSimplex.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(Vertices); - return hashCode; + return HashCode.Combine(Vertices); } public static bool operator ==(Simplex2D a, Simplex2D b) diff --git a/Test/EPA2DTest.cs b/Test/EPA2DTest.cs index cf26e71..468b057 100644 --- a/Test/EPA2DTest.cs +++ b/Test/EPA2DTest.cs @@ -27,7 +27,7 @@ namespace Tests intersection.X.Should().Be(1f); intersection.Y.Should().Be(0); - var movedTransform = new Transform2D(transformA.Position - intersection * 1.01f); // move a tiny bit past + var movedTransform = new Transform2D(transformA.Position - (intersection * 1.01f)); // move a tiny bit past GJK2D.TestCollision(squareA, movedTransform, squareB, transformB).Should().BeFalse(); } @@ -46,13 +46,13 @@ namespace Tests var intersection = EPA2D.Intersect(circleA, transformA, circleB, transformB, simplex); - var ix = circleA.Radius * (float)Math.Cos(Math.PI / 4) - (circleB.Radius * (float)Math.Cos(5 * Math.PI / 4) + transformB.Position.X); - var iy = circleA.Radius * (float)Math.Sin(Math.PI / 4) - (circleB.Radius * (float)Math.Sin(5 * Math.PI / 4) + transformB.Position.Y); + var ix = (circleA.Radius * (float)Math.Cos(Math.PI / 4)) - ((circleB.Radius * (float)Math.Cos(5 * Math.PI / 4)) + transformB.Position.X); + var iy = (circleA.Radius * (float)Math.Sin(Math.PI / 4)) - ((circleB.Radius * (float)Math.Sin(5 * Math.PI / 4)) + transformB.Position.Y); intersection.X.Should().BeApproximately(ix, 0.01f); intersection.Y.Should().BeApproximately(iy, 0.01f); - var movedTransform = new Transform2D(transformA.Position - intersection * 1.01f); // move a tiny bit past + var movedTransform = new Transform2D(transformA.Position - (intersection * 1.01f)); // move a tiny bit past GJK2D.TestCollision(circleA, movedTransform, circleB, transformB).Should().BeFalse(); } @@ -71,7 +71,7 @@ namespace Tests var intersection = EPA2D.Intersect(line, transformA, square, transformB, simplex); - var movedTransform = new Transform2D(transformA.Position - intersection * 1.01f); // move a tiny bit past + var movedTransform = new Transform2D(transformA.Position - (intersection * 1.01f)); // move a tiny bit past GJK2D.TestCollision(line, movedTransform, square, transformB).Should().BeFalse(); } diff --git a/Test/Equality.cs b/Test/Equality.cs index 07979a0..75af6ff 100644 --- a/Test/Equality.cs +++ b/Test/Equality.cs @@ -4,10 +4,11 @@ using FluentAssertions; using MoonTools.Core.Bonk; using MoonTools.Core.Structs; using System.Numerics; +using System.Collections.Immutable; namespace Tests { - public class EqualityTests + public static class EqualityTests { public class PointTests { @@ -148,8 +149,8 @@ namespace Tests [Test] public void RectangleEqual() { - var a = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); - var b = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); + var a = new Rectangle(0, 0, 3, 3); + var b = new Rectangle(0, 0, 3, 3); a.Equals(b).Should().BeTrue(); } @@ -157,8 +158,8 @@ namespace Tests [Test] public void RectangleEqualOperator() { - var a = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); - var b = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); + var a = new Rectangle(0, 0, 3, 3); + var b = new Rectangle(0, 0, 3, 3); (a == b).Should().BeTrue(); } @@ -166,8 +167,8 @@ namespace Tests [Test] public void RectangleNotEqual() { - var a = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); - var b = new MoonTools.Core.Bonk.Rectangle(-1, -1, 5, 5); + var a = new Rectangle(0, 0, 3, 3); + var b = new Rectangle(-1, -1, 5, 5); a.Equals(b).Should().BeFalse(); } @@ -175,8 +176,8 @@ namespace Tests [Test] public void RectangleNotEqualOperator() { - var a = new MoonTools.Core.Bonk.Rectangle(0, 0, 3, 3); - var b = new MoonTools.Core.Bonk.Rectangle(-1, -1, 5, 5); + var a = new Rectangle(0, 0, 3, 3); + var b = new Rectangle(-1, -1, 5, 5); (a != b).Should().BeTrue(); } @@ -187,17 +188,17 @@ namespace Tests [Test] public void PolygonEqual() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); a.Equals(b).Should().BeTrue(); } @@ -205,17 +206,17 @@ namespace Tests [Test] public void PolygonEqualOperator() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); (a == b).Should().BeTrue(); } @@ -223,17 +224,17 @@ namespace Tests [Test] public void PolygonDifferentOrderEqual() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(1, 2), new Position2D(-1, -1), new Position2D(0, 1) - ); + )); a.Equals(b).Should().BeTrue(); } @@ -241,17 +242,17 @@ namespace Tests [Test] public void PolygonDifferentOrderEqualOperator() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(1, 2), new Position2D(-1, -1), new Position2D(0, 1) - ); + )); (a == b).Should().BeTrue(); } @@ -259,17 +260,17 @@ namespace Tests [Test] public void PolygonNotEqual() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(1, 0), new Position2D(2, 1), new Position2D(-1, -1) - ); + )); a.Equals(b).Should().BeFalse(); } @@ -277,17 +278,17 @@ namespace Tests [Test] public void PolygonNotEqualOperator() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(0, 1), new Position2D(1, 2), new Position2D(-1, -1) - ); + )); - var b = new Polygon( + var b = new Polygon(ImmutableArray.Create( new Position2D(1, 0), new Position2D(2, 1), new Position2D(-1, -1) - ); + )); (a != b).Should().BeTrue(); } @@ -295,12 +296,12 @@ namespace Tests [Test] public void PolygonRectangleEqual() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(1, 1), new Position2D(1, -1), new Position2D(-1, -1), new Position2D(-1, 1) - ); + )); var b = new Rectangle(-1, -1, 1, 1); @@ -310,12 +311,12 @@ namespace Tests [Test] public void PolygonRectangleNotEqual() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(2, 1), new Position2D(1, -1), new Position2D(-1, -1), new Position2D(-2, 1) - ); + )); var b = new Rectangle(-1, -1, 1, 1); @@ -325,12 +326,12 @@ namespace Tests [Test] public void PolygonRectangleEqualOperator() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(1, 1), new Position2D(1, -1), new Position2D(-1, -1), new Position2D(-1, 1) - ); + )); var b = new Rectangle(-1, -1, 1, 1); @@ -340,12 +341,12 @@ namespace Tests [Test] public void PolygonRectangleNotEqualOperator() { - var a = new Polygon( + var a = new Polygon(ImmutableArray.Create( new Position2D(2, 1), new Position2D(1, -1), new Position2D(-1, -1), new Position2D(-2, 1) - ); + )); var b = new Rectangle(-1, -1, 1, 1); @@ -515,5 +516,26 @@ namespace Tests (simplexC == simplexD).Should().BeFalse(); } } + + public class AABBTests + { + [Test] + public void Equal() + { + var aabb = new AABB(0, 0, 3, 3); + var other = new AABB(0, 0, 3, 3); + + (aabb == other).Should().BeTrue(); + } + + [Test] + public void NotEqual() + { + var aabb = new AABB(0, 0, 3, 3); + var other = new AABB(0, 0, 6, 6); + + (aabb != other).Should().BeTrue(); + } + } } } \ No newline at end of file diff --git a/Test/GJK2DTest.cs b/Test/GJK2DTest.cs index 9fe83d5..a962495 100644 --- a/Test/GJK2DTest.cs +++ b/Test/GJK2DTest.cs @@ -3,6 +3,7 @@ using MoonTools.Core.Bonk; using MoonTools.Core.Structs; using System.Numerics; using FluentAssertions; +using System.Collections.Immutable; namespace Tests { @@ -15,7 +16,7 @@ namespace Tests var pointTransform = new Transform2D(new Position2D(4, 4)); var line = new Line(new Position2D(-2, -2), new Position2D(2, 2)); - GJK2D.TestCollision(point, Transform2D.DefaultTransform, line, Transform2D.DefaultTransform).Should().BeTrue(); + GJK2D.TestCollision(point, pointTransform, line, Transform2D.DefaultTransform).Should().BeTrue(); } [Test] @@ -71,12 +72,12 @@ namespace Tests public void PointPolygonOverlapping() { var point = new Point(1, 1); - var polygon = new Polygon( + var polygon = new Polygon(ImmutableArray.Create( new Position2D(-2, -2), new Position2D(-3, 2), new Position2D(3, 2), new Position2D(3, -2) - ); + )); GJK2D.TestCollision(point, Transform2D.DefaultTransform, polygon, Transform2D.DefaultTransform).Should().BeTrue(); } @@ -85,12 +86,12 @@ namespace Tests public void PointPolygonNotOverlapping() { var point = new Point(5, 5); - var polygon = new Polygon( + var polygon = new Polygon(ImmutableArray.Create( new Position2D(-2, -2), new Position2D(-3, 2), new Position2D(3, 2), new Position2D(3, -2) - ); + )); GJK2D.TestCollision(point, Transform2D.DefaultTransform, polygon, Transform2D.DefaultTransform).Should().BeFalse(); } @@ -182,17 +183,17 @@ namespace Tests [Test] public void PolygonPolygonOverlapping() { - var shapeA = new Polygon( + var shapeA = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformA = Transform2D.DefaultTransform; - var shapeB = new Polygon( + var shapeB = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformB = new Transform2D(new Vector2(0.5f, 0.5f)); @@ -202,17 +203,17 @@ namespace Tests [Test] public void ScaledPolygonsOverlapping() { - var shapeA = new Polygon( + var shapeA = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformA = Transform2D.DefaultTransform; - var shapeB = new Polygon( + var shapeB = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformB = new Transform2D(new Vector2(3f, 0f), 0f, new Vector2(3f, 3f)); @@ -222,17 +223,17 @@ namespace Tests [Test] public void PolygonPolygonNotOverlapping() { - var shapeA = new Polygon( + var shapeA = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformA = Transform2D.DefaultTransform; - var shapeB = new Polygon( + var shapeB = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformB = new Transform2D(new Vector2(5, 0)); @@ -242,17 +243,17 @@ namespace Tests [Test] public void ScaledPolygonsNotOverlapping() { - var shapeA = new Polygon( + var shapeA = new Polygon(ImmutableArray.Create( new Position2D(-1, 1), new Position2D(1, 1), new Position2D(-1, -1), new Position2D(1, -1) - ); + )); var transformA = Transform2D.DefaultTransform; - var shapeB = new Polygon( + var shapeB = new Polygon(ImmutableArray.Create( new Position2D(-2, 2), new Position2D(2, 2), new Position2D(-2, -2), new Position2D(2, -2) - ); + )); var transformB = new Transform2D(new Vector2(3f, 0), 0f, new Vector2(0.5f, 0.5f)); @@ -266,10 +267,10 @@ namespace Tests var transformA = Transform2D.DefaultTransform; - var polygon = new Polygon( + var polygon = new Polygon(ImmutableArray.Create( new Position2D(-1, -1), new Position2D(1, -1), new Position2D(1, 1), new Position2D(-1, 1) - ); + )); var transformB = Transform2D.DefaultTransform; @@ -283,10 +284,10 @@ namespace Tests var transformA = Transform2D.DefaultTransform; - var polygon = new Polygon( + var polygon = new Polygon(ImmutableArray.Create( new Position2D(-1, -1), new Position2D(1, -1), new Position2D(1, 1), new Position2D(-1, 1) - ); + )); var transformB = Transform2D.DefaultTransform; @@ -321,10 +322,10 @@ namespace Tests var circle = new Circle(1); var transformA = new Transform2D(new Vector2(0.25f, 0)); - var square = new Polygon( + var square = new Polygon(ImmutableArray.Create( new Position2D(-1, -1), new Position2D(1, -1), new Position2D(1, 1), new Position2D(-1, 1) - ); + )); var transformB = Transform2D.DefaultTransform; @@ -337,10 +338,10 @@ namespace Tests var circle = new Circle(1); var circleTransform = new Transform2D(new Vector2(5, 0)); - var square = new Polygon( + var square = new Polygon(ImmutableArray.Create( new Position2D(-1, -1), new Position2D(1, -1), new Position2D(1, 1), new Position2D(-1, 1) - ); + )); var squareTransform = Transform2D.DefaultTransform; GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Should().BeFalse();