From a3eec5c01c2a6fc12d9d03793002be2710a4876f Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Fri, 25 Oct 2019 13:09:03 -0700 Subject: [PATCH] tasty restructuring --- Bonk/GJK2D.cs | 62 ++++++++++++++++-------------------------- Bonk/Shapes/Simplex.cs | 8 ++++++ Test/EPA2DTest.cs | 6 ++-- 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/Bonk/GJK2D.cs b/Bonk/GJK2D.cs index 1d9ae3d..417b071 100644 --- a/Bonk/GJK2D.cs +++ b/Bonk/GJK2D.cs @@ -1,75 +1,61 @@ using Microsoft.Xna.Framework; using MoonTools.Core.Structs; -using System; using MoonTools.Core.Bonk.Extensions; namespace MoonTools.Core.Bonk { - - public static class GJK2D { public static bool TestCollision(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) { var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - return OriginInside(minkowskiDifference); - } - - public static (bool, Simplex) CollisionAndSimplex(IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) - { - var minkowskiDifference = new MinkowskiDifference(shapeA, transformA, shapeB, transformB); - var (collision, a, b) = OriginInsideWithSimplex(minkowskiDifference); - var polytope = new Simplex(minkowskiDifference, a, b); - return (collision, polytope); - } - - private static Vector2 MinkowskiDifference(Vector2 direction, IShape2D shapeA, Transform2D transformA, IShape2D shapeB, Transform2D transformB) - { - return shapeA.Support(direction, transformA) - shapeB.Support(-direction, transformB); - } - - private static bool OriginInside(MinkowskiDifference minkowskiDifference) - { var a = minkowskiDifference.Support(Vector2.UnitX); var b = minkowskiDifference.Support(-a); - return Vector2.Dot(a, b) > 0 ? false : CheckSimplex(minkowskiDifference.Support, a, b); + return Vector2.Dot(a, b) > 0 ? false : CheckSimplex(new Simplex(minkowskiDifference, a, b)); } - private static (bool, Vector2, Vector2) OriginInsideWithSimplex(MinkowskiDifference minkowskiDifference) + private static bool CheckSimplex(Simplex simplex) { - var a = minkowskiDifference.Support(Vector2.UnitX); - var b = minkowskiDifference.Support(-a); + var a = simplex.DirectionA; + var b = simplex.DirectionB; - return Vector2.Dot(a, b) > 0 ? (false, a, b) : Simplex(minkowskiDifference.Support, a, b); - } - - private static bool CheckSimplex(Func support, Vector2 a, Vector2 b) - { var axb = a.Cross(b); - var c = support((b - a).Perpendicular()); + 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(support, b, c) : (axc.Y > 0 != cxb.Y > 0 ? CheckSimplex(support, a, c) : true)); + 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)); } - private static (bool, Vector2, Vector2) Simplex(Func support, Vector2 a, Vector2 b) + public static (bool, Simplex) 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)); + } + + private static (bool, Simplex) Simplex(Simplex simplex) + { + var a = simplex.DirectionA; + var b = simplex.DirectionB; + if ((b - a) == Vector2.Zero) { - return (false, a, b); + return (false, simplex.WithDirections(a, b)); } else { - var c = support((b - a).Perpendicular()); + var c = simplex.Support((b - a).Perpendicular()); var axb = a.Cross(b); var bxc = b.Cross(c); if (axb.Y > 0 != bxc.Y > 0) { - return Simplex(support, b, c); + return Simplex(simplex.WithDirections(b, c)); } else { @@ -78,11 +64,11 @@ namespace MoonTools.Core.Bonk if (axc.Y > 0 != cxb.Y > 0) { - return Simplex(support, a, b); + return Simplex(simplex.WithDirections(a, b)); } else { - return (true, a, b); + return (true, simplex.WithDirections(a, b)); } } } diff --git a/Bonk/Shapes/Simplex.cs b/Bonk/Shapes/Simplex.cs index 9e09334..3eb8dc2 100644 --- a/Bonk/Shapes/Simplex.cs +++ b/Bonk/Shapes/Simplex.cs @@ -11,6 +11,9 @@ namespace MoonTools.Core.Bonk Vector2 directionA; Vector2 directionB; + public Vector2 DirectionA { get { return directionA; } } + public Vector2 DirectionB { get { return directionB; } } + public Simplex(MinkowskiDifference minkowskiDifference, Vector2 directionA, Vector2 directionB) { this.minkowskiDifference = minkowskiDifference; @@ -18,6 +21,11 @@ namespace MoonTools.Core.Bonk this.directionB = directionB; } + public Simplex WithDirections(Vector2 a, Vector2 b) + { + return new Simplex(minkowskiDifference, a, b); + } + public IEnumerable Vertices { get diff --git a/Test/EPA2DTest.cs b/Test/EPA2DTest.cs index 4459b9c..422d78d 100644 --- a/Test/EPA2DTest.cs +++ b/Test/EPA2DTest.cs @@ -18,7 +18,7 @@ namespace Tests var squareB = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1); var transformB = new Transform2D(new Vector2(1.5f, 0)); - var (result, simplex) = GJK2D.CollisionAndSimplex(squareA, transformA, squareB, transformB); + var (result, simplex) = GJK2D.FindCollisionSimplex(squareA, transformA, squareB, transformB); result.Should().BeTrue(); @@ -36,7 +36,7 @@ namespace Tests var circleB = new Circle(1); var transformB = new Transform2D(new Vector2(1, 1)); - var (result, simplex) = GJK2D.CollisionAndSimplex(circleA, transformA, circleB, transformB); + var (result, simplex) = GJK2D.FindCollisionSimplex(circleA, transformA, circleB, transformB); result.Should().BeTrue(); @@ -57,7 +57,7 @@ namespace Tests var square = new MoonTools.Core.Bonk.Rectangle(-1, -1, 1, 1); var transformB = Transform2D.DefaultTransform; - var (result, simplex) = GJK2D.CollisionAndSimplex(line, transformA, square, transformB); + var (result, simplex) = GJK2D.FindCollisionSimplex(line, transformA, square, transformB); result.Should().BeTrue();