fix circle bounding box not scaling with transform

pull/2/head
thatcosmonaut 2019-09-18 17:00:43 -07:00
parent e292ad1875
commit e9eb796ede
3 changed files with 100 additions and 16 deletions

View File

@ -8,13 +8,13 @@ namespace MoonTools.Core.Bonk
{ {
public struct AABB public struct AABB
{ {
public int MinX { get; private set; } public float MinX { get; private set; }
public int MinY { get; private set; } public float MinY { get; private set; }
public int MaxX { get; private set; } public float MaxX { get; private set; }
public int MaxY { get; private set; } public float MaxY { get; private set; }
public int Width { get { return MaxX - MinX; } } public float Width { get { return MaxX - MinX; } }
public int Height { get { return MaxY - MinY; } } public float Height { get { return MaxY - MinY; } }
public static AABB FromTransformedVertices(IEnumerable<Position2D> vertices, Transform2D transform) public static AABB FromTransformedVertices(IEnumerable<Position2D> vertices, Transform2D transform)
{ {
@ -22,14 +22,14 @@ namespace MoonTools.Core.Bonk
return new AABB return new AABB
{ {
MinX = (int)Math.Round(TransformedVertices.Min(vertex => vertex.X)), MinX = TransformedVertices.Min(vertex => vertex.X),
MinY = (int)Math.Round(TransformedVertices.Min(vertex => vertex.Y)), MinY = TransformedVertices.Min(vertex => vertex.Y),
MaxX = (int)Math.Round(TransformedVertices.Max(vertex => vertex.X)), MaxX = TransformedVertices.Max(vertex => vertex.X),
MaxY = (int)Math.Round(TransformedVertices.Max(vertex => vertex.Y)) 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; MinX = minX;
MinY = minY; MinY = minY;

View File

@ -18,13 +18,13 @@ namespace MoonTools.Core.Bonk
return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix); return Vector2.Transform(Vector2.Normalize(direction) * Radius, transform.TransformMatrix);
} }
public AABB AABB(Transform2D Transform2D) public AABB AABB(Transform2D transform2D)
{ {
return new AABB( return new AABB(
Transform2D.Position.X - Radius, transform2D.Position.X - Radius * transform2D.Scale.X,
Transform2D.Position.Y - Radius, transform2D.Position.Y - Radius * transform2D.Scale.Y,
Transform2D.Position.X + Radius, transform2D.Position.X + Radius * transform2D.Scale.X,
Transform2D.Position.Y + Radius transform2D.Position.Y + Radius * transform2D.Scale.Y
); );
} }

View File

@ -16,6 +16,17 @@ namespace Tests
Assert.IsTrue(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1); 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] [Test]
public void LineLineNotOverlapping() public void LineLineNotOverlapping()
{ {
@ -25,6 +36,17 @@ namespace Tests
Assert.IsFalse(GJK2D.TestCollision(lineA, Transform2D.DefaultTransform, lineB, Transform2D.DefaultTransform).Item1); 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] [Test]
public void CircleCircleOverlapping() public void CircleCircleOverlapping()
{ {
@ -36,6 +58,17 @@ namespace Tests
Assert.IsTrue(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); 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] [Test]
public void CircleCircleNotOverlapping() public void CircleCircleNotOverlapping()
{ {
@ -47,6 +80,17 @@ namespace Tests
Assert.IsFalse(GJK2D.TestCollision(circleA, transformA, circleB, transformB).Item1); 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] [Test]
public void PolygonPolygonOverlapping() public void PolygonPolygonOverlapping()
{ {
@ -67,6 +111,26 @@ namespace Tests
Assert.IsTrue(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); 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] [Test]
public void PolygonPolygonNotOverlapping() public void PolygonPolygonNotOverlapping()
{ {
@ -87,6 +151,26 @@ namespace Tests
Assert.IsFalse(GJK2D.TestCollision(shapeA, transformA, shapeB, transformB).Item1); 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] [Test]
public void LinePolygonOverlapping() public void LinePolygonOverlapping()
{ {