From e9eb796ede6bb39da536b6251baf9311e6beb2d1 Mon Sep 17 00:00:00 2001 From: thatcosmonaut Date: Wed, 18 Sep 2019 17:00:43 -0700 Subject: [PATCH] fix circle bounding box not scaling with transform --- Bonk/AABB.cs | 22 ++++++------ Bonk/Shapes/Circle.cs | 10 +++--- Test/GJK2DTest.cs | 84 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 16 deletions(-) diff --git a/Bonk/AABB.cs b/Bonk/AABB.cs index 5386117..0074d01 100644 --- a/Bonk/AABB.cs +++ b/Bonk/AABB.cs @@ -8,13 +8,13 @@ namespace MoonTools.Core.Bonk { public struct AABB { - public int MinX { get; private set; } - public int MinY { get; private set; } - public int MaxX { get; private set; } - public int MaxY { get; private set; } + public float MinX { get; private set; } + public float MinY { get; private set; } + public float MaxX { get; private set; } + public float MaxY { get; private set; } - public int Width { get { return MaxX - MinX; } } - public int Height { get { return MaxY - MinY; } } + public float Width { get { return MaxX - MinX; } } + public float Height { get { return MaxY - MinY; } } public static AABB FromTransformedVertices(IEnumerable vertices, Transform2D transform) { @@ -22,14 +22,14 @@ namespace MoonTools.Core.Bonk return new AABB { - MinX = (int)Math.Round(TransformedVertices.Min(vertex => vertex.X)), - MinY = (int)Math.Round(TransformedVertices.Min(vertex => vertex.Y)), - MaxX = (int)Math.Round(TransformedVertices.Max(vertex => vertex.X)), - MaxY = (int)Math.Round(TransformedVertices.Max(vertex => vertex.Y)) + MinX = TransformedVertices.Min(vertex => vertex.X), + MinY = TransformedVertices.Min(vertex => vertex.Y), + MaxX = TransformedVertices.Max(vertex => vertex.X), + MaxY = TransformedVertices.Max(vertex => vertex.Y) }; } - public AABB(int minX, int minY, int maxX, int maxY) + public AABB(float minX, float minY, float maxX, float maxY) { MinX = minX; MinY = minY; diff --git a/Bonk/Shapes/Circle.cs b/Bonk/Shapes/Circle.cs index 26d43dd..334e504 100644 --- a/Bonk/Shapes/Circle.cs +++ b/Bonk/Shapes/Circle.cs @@ -18,13 +18,13 @@ namespace MoonTools.Core.Bonk return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix); } - public AABB AABB(Transform2D Transform2D) + public AABB AABB(Transform2D transform2D) { return new AABB( - Transform2D.Position.X - Radius, - Transform2D.Position.Y - Radius, - Transform2D.Position.X + Radius, - Transform2D.Position.Y + Radius + 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 ); } diff --git a/Test/GJK2DTest.cs b/Test/GJK2DTest.cs index 81a868a..b2743bf 100644 --- a/Test/GJK2DTest.cs +++ b/Test/GJK2DTest.cs @@ -16,6 +16,17 @@ namespace Tests Assert.IsTrue(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1); } + [Test] + public void ScaledLinesOverlapping() + { + var lineA = new Line(new Position2D(-1, -1), new Position2D(1, 1)); + var lineB = new Line(new Position2D(-1, 1), new Position2D(1, -1)); + + var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2)); + + Assert.IsTrue(GJK2D.TestCollision(lineA, transform, lineB, transform).Item1); + } + [Test] public void LineLineNotOverlapping() { @@ -25,6 +36,17 @@ namespace Tests Assert.IsFalse(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1); } + [Test] + public void ScaledLinesNotOverlapping() + { + var lineA = new Line(new Position2D(0, 1), new Position2D(1, 0)); + var lineB = new Line(new Position2D(-1, -1), new Position2D(-2, -2)); + + var transform = new Transform2D(new Position2D(0, 0), 0f, new Vector2(2, 2)); + + Assert.IsFalse(GJK2D.TestCollision(lineA, transform, lineB, transform).Item1); + } + [Test] public void CircleCircleOverlapping() { @@ -36,6 +58,17 @@ namespace Tests Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); } + [Test] + public void ScaledCirclesOverlapping() + { + var circleA = new Circle(2); + var transformA = new Transform2D(new Vector2(-3, 0), 0f, new Vector2(2, 2)); + var circleB = new Circle(2); + var transformB = new Transform2D(new Vector2(3, 0), 0f, new Vector2(2, 2)); + + Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); + } + [Test] public void CircleCircleNotOverlapping() { @@ -47,6 +80,17 @@ namespace Tests Assert.IsFalse(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); } + [Test] + public void ScaledCirclesNotOverlapping() + { + var circleA = new Circle(2); + var transformA = new Transform2D(new Vector2(-5, -5), 0, new Vector2(0.2f, 0.2f)); + var circleB = new Circle(2); + var transformB = new Transform2D(new Vector2(5, 5), 0, new Vector2(0.2f, 0.2f)); + + Assert.IsFalse(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); + } + [Test] public void PolygonPolygonOverlapping() { @@ -67,6 +111,26 @@ namespace Tests Assert.IsTrue(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); } + [Test] + public void ScaledPolygonsOverlapping() + { + var shapeA = new Polygon( + new Position2D(-1, 1), new Position2D(1, 1), + new Position2D(-1, -1), new Position2D(1, -1) + ); + + var transformA = Transform2D.DefaultTransform; + + var shapeB = new Polygon( + 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)); + + Assert.IsTrue(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); + } + [Test] public void PolygonPolygonNotOverlapping() { @@ -87,6 +151,26 @@ namespace Tests Assert.IsFalse(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); } + [Test] + public void ScaledPolygonsNotOverlapping() + { + var shapeA = new Polygon( + new Position2D(-1, 1), new Position2D(1, 1), + new Position2D(-1, -1), new Position2D(1, -1) + ); + + var transformA = Transform2D.DefaultTransform; + + var shapeB = new Polygon( + new Position2D(-1, 1), new Position2D(1, 1), + new Position2D(-1, -1), new Position2D(1, -1) + ); + + var transformB = new Transform2D(new Vector2(2f, 0), 0f, new Vector2(0.2f, 0.2f)); + + Assert.IsFalse(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); + } + [Test] public void LinePolygonOverlapping() {