diff --git a/Bonk/NarrowPhase/EPA2D.cs b/Bonk/NarrowPhase/EPA2D.cs index a3b58bb..b76c98b 100644 --- a/Bonk/NarrowPhase/EPA2D.cs +++ b/Bonk/NarrowPhase/EPA2D.cs @@ -24,7 +24,7 @@ namespace MoonTools.Core.Bonk /// /// A simplex returned by the GJK algorithm. /// - public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex simplex) + public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex2D simplex) { var simplexVertices = new PooledList(36, ClearMode.Always); diff --git a/Bonk/NarrowPhase/GJK2D.cs b/Bonk/NarrowPhase/GJK2D.cs index 0176a96..9b9776f 100644 --- a/Bonk/NarrowPhase/GJK2D.cs +++ b/Bonk/NarrowPhase/GJK2D.cs @@ -11,73 +11,135 @@ namespace MoonTools.Core.Bonk /// public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) { - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - var a = minkowskiDifference.Support(Vector2.UnitX); - var b = minkowskiDifference.Support(-a); - - return Vector2.Dot(a, b) > 0 ? false : CheckSimplex(new Simplex(minkowskiDifference, a, b)); - } - - private static bool CheckSimplex(Simplex simplex) - { - var a = simplex.DirectionA; - var b = simplex.DirectionB; - - var axb = a.Cross(b); - var c = simplex.Support((b - a).Perpendicular()); - var axc = a.Cross(c); - var bxc = b.Cross(c); - var cxb = -bxc; - - return (b - a) == Vector2.Zero || (axb.Y > 0 != bxc.Y > 0 ? CheckSimplex(simplex.WithDirections(b, c)) : (axc.Y > 0 != cxb.Y > 0 ? CheckSimplex(simplex.WithDirections(a, c)) : true)); + return FindCollisionSimplex(shapeA, transformA, shapeB, transformB).Item1; } /// /// Tests if the two shape-transform pairs are overlapping, and returns a simplex that can be used by the EPA algorithm to determine a miminum separating vector. /// - public static (bool, Simplex) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) + public static (bool, Simplex2D) FindCollisionSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) { var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - var a = minkowskiDifference.Support(Vector2.UnitX); - var b = minkowskiDifference.Support(-a); - - return Vector2.Dot(a, b) > 0 ? (false, default(Simplex)) : Simplex(new Simplex(minkowskiDifference, a, b)); + var c = minkowskiDifference.Support(Vector2.UnitX); + var b = minkowskiDifference.Support(-Vector2.UnitX); + return Check(minkowskiDifference, c, b); } - private static (bool, Simplex) Simplex(Simplex simplex) + private static (bool, Simplex2D) Check(MinkowskiDifference minkowskiDifference, Vector2 c, Vector2 b) { - var a = simplex.DirectionA; - var b = simplex.DirectionB; + var cb = c - b; + var c0 = -c; + var d = Direction(cb, c0); + return DoSimplex(minkowskiDifference, new Simplex2D(b, c), d); + } - if ((b - a) == Vector2.Zero) + private static (bool, Simplex2D) DoSimplex(MinkowskiDifference minkowskiDifference, Simplex2D simplex, Vector2 direction) + { + var a = minkowskiDifference.Support(direction); + var notPastOrigin = Vector2.Dot(a, direction) < 0; + var (intersects, newSimplex, newDirection) = EnclosesOrigin(a, simplex); + + if (notPastOrigin) { - return (false, simplex.WithDirections(a, b)); + return (false, default(Simplex2D)); + } + else if (intersects) + { + return (true, new Simplex2D(simplex.A, simplex.B.Value, a)); } else { - var c = simplex.Support((b - a).Perpendicular()); - var axb = a.Cross(b); - var bxc = b.Cross(c); + return DoSimplex(minkowskiDifference, newSimplex, newDirection); + } + } - if (axb.Y > 0 != bxc.Y > 0) + private static (bool, Simplex2D, Vector2) EnclosesOrigin(Vector2 a, Simplex2D simplex) + { + if (simplex.ZeroSimplex) + { + return HandleZeroSimplex(a, simplex.A); + } + else if (simplex.OneSimplex) + { + return HandleOneSimplex(a, simplex.A, simplex.B.Value); + } + else + { + return (false, simplex, Vector2.Zero); + } + } + + private static (bool, Simplex2D, Vector2) HandleZeroSimplex(Vector2 a, Vector2 b) + { + var ab = b - a; + var a0 = -a; + var (newSimplex, newDirection) = SameDirection(ab, a0) ? (new Simplex2D(a, b), Perpendicular(ab, a0)) : (new Simplex2D(a), a0); + return (false, newSimplex, newDirection); + } + + private static (bool, Simplex2D, Vector2) HandleOneSimplex(Vector2 a, Vector2 b, Vector2 c) + { + var a0 = -a; + var ab = b - a; + var ac = c - a; + var abp = Perpendicular(ab, -ac); + var acp = Perpendicular(ac, -ab); + + if (SameDirection(abp, a0)) + { + if (SameDirection(ab, a0)) { - return Simplex(simplex.WithDirections(b, c)); + return (false, new Simplex2D(a, b), abp); } else { - var axc = a.Cross(c); - var cxb = -bxc; - - if (axc.Y > 0 != cxb.Y > 0) - { - return Simplex(simplex.WithDirections(a, b)); - } - else - { - return (true, simplex.WithDirections(a, b)); - } + return (false, new Simplex2D(a), a0); } } + else if (SameDirection(acp, a0)) + { + if (SameDirection(ac, a0)) + { + return (false, new Simplex2D(a, c), acp); + } + else + { + return (false, new Simplex2D(a), a0); + } + } + else + { + return (true, new Simplex2D(b, c), a0); + } + } + + private static Vector2 TripleProduct(Vector2 a, Vector2 b, Vector2 c) + { + var A = new Vector3(a.X, a.Y, 0); + var B = new Vector3(b.X, b.Y, 0); + var C = new Vector3(c.X, c.Y, 0); + + var first = Vector3.Cross(A, B); + var second = Vector3.Cross(first, C); + + return new Vector2(second.X, second.Y); + } + + private static Vector2 Direction(Vector2 a, Vector2 b) + { + var d = TripleProduct(a, b, a); + var collinear = d == Vector2.Zero; + return collinear ? new Vector2(a.Y, -a.X) : d; + } + + private static bool SameDirection(Vector2 a, Vector2 b) + { + return Vector2.Dot(a, b) > 0; + } + + private static Vector2 Perpendicular(Vector2 a, Vector2 b) + { + return TripleProduct(a, b, a); } } } diff --git a/Bonk/Shapes/Simplex.cs b/Bonk/Shapes/Simplex.cs index 5e8b876..bfd4dc9 100644 --- a/Bonk/Shapes/Simplex.cs +++ b/Bonk/Shapes/Simplex.cs @@ -1,41 +1,59 @@ +using System.Linq; using System.Collections.Generic; using Microsoft.Xna.Framework; using MoonTools.Core.Structs; using MoonTools.Core.Bonk.Extensions; +using MoreLinq; namespace MoonTools.Core.Bonk { /// - /// A simplex is a shape used to calculate overlap. It is defined by a Minkowski difference and two direction vectors. + /// A simplex is a shape with up to n - 2 vertices in the nth dimension. /// - public struct Simplex : IShape2D + public struct Simplex2D : IShape2D { - MinkowskiDifference minkowskiDifference; - Vector2 directionA; - Vector2 directionB; + Vector2 a; + Vector2? b; + Vector2? c; - public Vector2 DirectionA { get { return directionA; } } - public Vector2 DirectionB { get { return directionB; } } + public Vector2 A => a; + public Vector2? B => b; + public Vector2? C => c; - public Simplex(MinkowskiDifference minkowskiDifference, Vector2 directionA, Vector2 directionB) + public bool ZeroSimplex { get { return !b.HasValue && !c.HasValue; } } + public bool OneSimplex { get { return b.HasValue && !c.HasValue; } } + public bool TwoSimplex { get { return b.HasValue && c.HasValue; } } + + public int Count => TwoSimplex ? 3 : (OneSimplex ? 2 : 1); + + public Simplex2D(Vector2 a) { - this.minkowskiDifference = minkowskiDifference; - this.directionA = directionA; - this.directionB = directionB; + this.a = a; + this.b = null; + this.c = null; } - public Simplex WithDirections(Vector2 a, Vector2 b) + public Simplex2D(Vector2 a, Vector2 b) { - return new Simplex(minkowskiDifference, a, b); + this.a = a; + this.b = b; + this.c = null; + } + + public Simplex2D(Vector2 a, Vector2 b, Vector2 c) + { + this.a = a; + this.b = b; + this.c = c; } public IEnumerable Vertices { get { - yield return (Position2D)Support(directionA); - yield return (Position2D)Support(directionB); - yield return (Position2D)Support(-(directionB - directionA).Perpendicular()); + yield return (Position2D)a; + if (b.HasValue) { yield return (Position2D)b; } + if (c.HasValue) { yield return (Position2D)c; } } } @@ -46,7 +64,7 @@ namespace MoonTools.Core.Bonk public Vector2 Support(Vector2 direction) { - return minkowskiDifference.Support(direction); + return Vertices.MaxBy(vertex => Vector2.Dot(vertex, direction)).First(); } public Vector2 Support(Vector2 direction, Transform2D transform) @@ -66,11 +84,10 @@ namespace MoonTools.Core.Bonk public bool Equals(IShape2D other) { - if (other is Simplex otherSimplex) + if (other is Simplex2D otherSimplex) { - return minkowskiDifference == otherSimplex.minkowskiDifference && - ((directionA == otherSimplex.directionA && directionB == otherSimplex.directionB) || - (directionA == otherSimplex.directionB && directionB == otherSimplex.directionA)); + if (Count != otherSimplex.Count) { return false; } + return Vertices.Intersect(otherSimplex.Vertices).Count() == Count; } return false; @@ -78,22 +95,23 @@ namespace MoonTools.Core.Bonk public override int GetHashCode() { - var hashCode = 74270316; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(minkowskiDifference); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(directionA); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(directionB); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(DirectionA); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(DirectionB); + 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; } - public static bool operator ==(Simplex a, Simplex b) + public static bool operator ==(Simplex2D a, Simplex2D b) { return a.Equals(b); } - public static bool operator !=(Simplex a, Simplex b) + public static bool operator !=(Simplex2D a, Simplex2D b) { return !(a == b); } diff --git a/Bonk/Vector2Extensions.cs b/Bonk/Vector2Extensions.cs index 016a8cb..6c4920f 100644 --- a/Bonk/Vector2Extensions.cs +++ b/Bonk/Vector2Extensions.cs @@ -4,15 +4,15 @@ namespace MoonTools.Core.Bonk.Extensions { internal static class Vector2Extensions { - internal static Vector2 Cross(this Vector2 a, Vector2 b) + internal static float Cross(this Vector2 a, Vector2 b) { - var vec3 = Vector3.Cross(new Vector3(a.X, a.Y, 0), new Vector3(b.X, b.Y, 0)); - return new Vector2(vec3.X, vec3.Y); + return Vector3.Cross(new Vector3(a.X, a.Y, 0), new Vector3(b.X, b.Y, 0)).Z; } - internal static Vector2 Perpendicular(this Vector2 v) + internal static Vector2 Perpendicular(this Vector2 a, Vector2 b) { - return new Vector2(v.Y, -v.X); + var ab = b - a; + return a.Cross(b) > 0 ? Vector2.Normalize(new Vector2(ab.Y, ab.X)) : Vector2.Normalize(new Vector2(ab.Y, -ab.X)); } } } \ No newline at end of file diff --git a/Test/EPA2DTest.cs b/Test/EPA2DTest.cs index 422d78d..e53baed 100644 --- a/Test/EPA2DTest.cs +++ b/Test/EPA2DTest.cs @@ -26,6 +26,10 @@ 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 + + GJK2D.TestCollision(squareA, movedTransform, squareB, transformB).Should().BeFalse(); } [Test] @@ -47,6 +51,10 @@ namespace Tests 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 + + GJK2D.TestCollision(circleA, movedTransform, circleB, transformB).Should().BeFalse(); } [Test] @@ -63,8 +71,9 @@ namespace Tests var intersection = EPA2D.Intersect(line, transformA, square, transformB, simplex); - intersection.X.Should().Be(-1); - intersection.Y.Should().Be(1); + 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 e23bc52..2bce8b9 100644 --- a/Test/Equality.cs +++ b/Test/Equality.cs @@ -258,169 +258,163 @@ namespace Tests public class SimplexTests { [Test] - public void SimplexEquals() + public void ZeroSimplexEquals() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); - - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); - - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionA, directionB); + var simplexA = new Simplex2D(Vector2.One); + var simplexB = new Simplex2D(Vector2.One); simplexA.Equals(simplexB).Should().BeTrue(); } [Test] - public void SimplexEqualsOperator() + public void ZeroSimplexEqualsOperator() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); - - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); - - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionA, directionB); + var simplexA = new Simplex2D(Vector2.One); + var simplexB = new Simplex2D(Vector2.One); (simplexA == simplexB).Should().BeTrue(); } [Test] - public void SimplexDirectionOutOfOrderEqual() + public void ZeroSimplexNotEquals() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); + var simplexA = new Simplex2D(Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One); - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); + simplexA.Equals(simplexB).Should().BeFalse(); - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); + var simplexC = new Simplex2D(Vector2.Zero, Vector2.One); - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; + simplexA.Equals(simplexC).Should().BeFalse(); + } - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionB, directionA); + [Test] + public void ZeroSimplexNotEqualsOperator() + { + var simplexA = new Simplex2D(Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One); + + (simplexA != simplexB).Should().BeTrue(); + } + + [Test] + public void OneSimplexEquals() + { + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero); simplexA.Equals(simplexB).Should().BeTrue(); + + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.One); + + simplexC.Equals(simplexD).Should().BeTrue(); } [Test] - public void SimplexDirectionOutOfOrderEqualOperator() + public void OneSimplexEqualsOperator() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); - - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); - - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionB, directionA); + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero); (simplexA == simplexB).Should().BeTrue(); + + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.One); + + (simplexC == simplexD).Should().BeTrue(); } [Test] - public void SimplexMinkowskiNotEqual() + public void OneSimplexNotEquals() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); - - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); - - var minkowskiDifferenceA = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - var minkowskiDifferenceB = new MinkowskiDifference(shapeB, transformB, shapeA, transformA); - - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifferenceA, directionA, directionB); - var simplexB = new Simplex(minkowskiDifferenceB, directionA, directionB); + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One, Vector2.UnitX); simplexA.Equals(simplexB).Should().BeFalse(); + + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.UnitX); + + simplexC.Equals(simplexD).Should().BeFalse(); + + var simplexE = new Simplex2D(Vector2.Zero); + + simplexA.Equals(simplexE).Should().BeFalse(); } [Test] - public void SimplexMinkowskiNotEqualOperator() + public void OneSimplexNotEqualsOperator() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexB = new Simplex2D(Vector2.One, Vector2.UnitX); - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); + (simplexA == simplexB).Should().BeFalse(); - var minkowskiDifferenceA = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - var minkowskiDifferenceB = new MinkowskiDifference(shapeB, transformB, shapeA, transformA); + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.UnitX); - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifferenceA, directionA, directionB); - var simplexB = new Simplex(minkowskiDifferenceB, directionA, directionB); - - (simplexA != simplexB).Should().BeTrue(); + (simplexC == simplexD).Should().BeFalse(); } [Test] - public void SimplexDirectionsNotEqual() + public void TwoSimplexEquals() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); + simplexA.Equals(simplexB).Should().BeTrue(); - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.One, Vector2.UnitX); - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - var directionC = -Vector2.UnitX; - var directionD = -Vector2.UnitY; + simplexC.Equals(simplexD).Should().BeTrue(); + } - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionC, directionD); + [Test] + public void TwoSimplexEqualsOperator() + { + var simplexA = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + + (simplexA == simplexB).Should().BeTrue(); + + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.One, Vector2.UnitX); + + (simplexC == simplexD).Should().BeTrue(); + } + + [Test] + public void TwoSimplexNotEquals() + { + var simplexA = new Simplex2D(Vector2.One, Vector2.UnitY, Vector2.UnitX); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); simplexA.Equals(simplexB).Should().BeFalse(); + + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.UnitY, Vector2.UnitX); + + simplexC.Equals(simplexD).Should().BeFalse(); + + var simplexE = new Simplex2D(Vector2.Zero); + + simplexA.Equals(simplexE).Should().BeFalse(); } [Test] - public void SimplexDirectionsNotEqualOperator() + public void TwoSimplexNotEqualsOperator() { - var shapeA = new Circle(3); - var transformA = new Transform2D(new Position2D(1, 2)); + var simplexA = new Simplex2D(Vector2.One, Vector2.UnitY, Vector2.UnitX); + var simplexB = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); - var shapeB = new Circle(2); - var transformB = new Transform2D(new Position2D(4, 5)); + (simplexA == simplexB).Should().BeFalse(); - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); + var simplexC = new Simplex2D(Vector2.One, Vector2.Zero, Vector2.UnitX); + var simplexD = new Simplex2D(Vector2.Zero, Vector2.UnitY, Vector2.UnitX); - var directionA = Vector2.UnitX; - var directionB = Vector2.UnitY; - var directionC = -Vector2.UnitX; - var directionD = -Vector2.UnitY; - - var simplexA = new Simplex(minkowskiDifference, directionA, directionB); - var simplexB = new Simplex(minkowskiDifference, directionC, directionD); - - (simplexA != simplexB).Should().BeTrue(); + (simplexC == simplexD).Should().BeFalse(); } } } diff --git a/Test/GJK2DTest.cs b/Test/GJK2DTest.cs index 0cc7196..a663ac4 100644 --- a/Test/GJK2DTest.cs +++ b/Test/GJK2DTest.cs @@ -259,6 +259,18 @@ namespace Tests GJK2D.TestCollision(circle, circleTransform, square, squareTransform).Should().BeFalse(); } + [Test] + public void RectanglesNotOverlapping() + { + var rectangleA = new MoonTools.Core.Bonk.Rectangle(-6, -6, 6, 6); + var transformA = new Transform2D(new Position2D(39, 249)); + + var rectangleB = new MoonTools.Core.Bonk.Rectangle(0, 0, 16, 16); + var transformB = new Transform2D(new Position2D(16, 240)); + + GJK2D.TestCollision(rectangleA, transformA, rectangleB, transformB).Should().BeFalse(); + } + [Test] public void RotatedRectanglesOverlapping() {