Browse Source

fix bug in Line iterator + comparison cleanup

pull/10/head
Evan Hemsley 2 years ago
parent
commit
12c9f09229
  1. 3
      .gitignore
  2. 31
      Bonk/AABB.cs
  3. 10
      Bonk/Bonk.csproj
  4. 4
      Bonk/BroadPhase/SpatialHash.cs
  5. 41
      Bonk/MinkowskiDifference.cs
  6. 5
      Bonk/NarrowPhase/EPA2D.cs
  7. 31
      Bonk/Shapes/Circle.cs
  8. 27
      Bonk/Shapes/Line.cs
  9. 19
      Bonk/Shapes/Point.cs
  10. 52
      Bonk/Shapes/Polygon.cs
  11. 38
      Bonk/Shapes/Rectangle.cs
  12. 16
      Bonk/Shapes/RectanglePolygonComparison.cs
  13. 47
      Bonk/Shapes/Simplex.cs
  14. 10
      Test/EPA2DTest.cs
  15. 104
      Test/Equality.cs
  16. 59
      Test/GJK2DTest.cs

3
.gitignore

@ -1,3 +1,4 @@
bin/
obj/
.vscode
.vscode
.vs

31
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
/// <summary>
/// Axis-aligned bounding box.
/// </summary>
public struct AABB
public struct AABB : IEquatable<AABB>
{
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);
}
}
}

10
Bonk/Bonk.csproj

@ -15,8 +15,12 @@
<PackageProjectUrl>https://github.com/MoonsideGames/MoonTools.Core.Bonk</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MoonTools.Core.Structs" Version="2.0.0"/>
<PackageReference Include="morelinq" Version="3.2.0"/>
<PackageReference Include="System.Collections.Immutable" Version="1.6.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MoonTools.Core.Structs" Version="2.0.0" />
<PackageReference Include="morelinq" Version="3.2.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.6.0" />
</ItemGroup>
</Project>

4
Bonk/BroadPhase/SpatialHash.cs

@ -31,7 +31,7 @@ namespace MoonTools.Core.Bonk
/// <param name="id">A unique ID for the shape-transform pair.</param>
/// <param name="shape"></param>
/// <param name="transform2D"></param>
public void Insert(T id, IShape2D shape, Transform2D transform2D)
public void Insert<TShape2D>(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
/// <summary>
/// Retrieves all the potential collisions of a shape-transform pair. Excludes any shape-transforms with the given ID.
/// </summary>
public IEnumerable<(T, IShape2D, Transform2D)> Retrieve(T id, IShape2D shape, Transform2D transform2D)
public IEnumerable<(T, IShape2D, Transform2D)> Retrieve<TShape2D>(T id, TShape2D shape, Transform2D transform2D) where TShape2D : struct, IShape2D
{
var box = shape.AABB(transform2D);
var minHash = Hash(box.MinX, box.MinY);

41
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
/// </summary>
public struct MinkowskiDifference : IEquatable<MinkowskiDifference>
{
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<IShape2D>.Default.GetHashCode(shapeA);
hashCode = hashCode * -1521134295 + EqualityComparer<Transform2D>.Default.GetHashCode(transformA);
hashCode = hashCode * -1521134295 + EqualityComparer<IShape2D>.Default.GetHashCode(shapeB);
hashCode = hashCode * -1521134295 + EqualityComparer<Transform2D>.Default.GetHashCode(transformB);
return hashCode;
return HashCode.Combine(ShapeA, TransformA, ShapeB, TransformB);
}
public static bool operator ==(MinkowskiDifference a, MinkowskiDifference b)

5
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.
/// </summary>
/// <param name="simplex">A simplex returned by the GJK algorithm.</param>
/// <returns></returns>
public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex2D simplex)
public static Vector2 Intersect<TShapeA, TShapeB>(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();

31
Bonk/Shapes/Circle.cs

@ -7,9 +7,9 @@ namespace MoonTools.Core.Bonk
/// <summary>
/// A Circle is a shape defined by a radius.
/// </summary>
public struct Circle : IShape2D, IEquatable<IShape2D>
public struct Circle : IShape2D, IEquatable<Circle>
{
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)

27
Bonk/Shapes/Line.cs

@ -8,7 +8,7 @@ namespace MoonTools.Core.Bonk
/// <summary>
/// A line is a shape defined by exactly two points in space.
/// </summary>
public struct Line : IShape2D, IEquatable<IShape2D>
public struct Line : IShape2D, IEquatable<Line>
{
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<Position2D>.Default.GetHashCode(v0);
hashCode = hashCode * -1521134295 + EqualityComparer<Position2D>.Default.GetHashCode(v1);
hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(Vertices);
return hashCode;
return HashCode.Combine(v0, v1);
}
public static bool operator ==(Line a, Line b)

19
Bonk/Shapes/Point.cs

@ -5,7 +5,7 @@ using MoonTools.Core.Structs;
namespace MoonTools.Core.Bonk
{
public struct Point : IShape2D, IEquatable<IShape2D>
public struct Point : IShape2D, IEquatable<Point>
{
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()

52
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.
/// </summary>
public struct Polygon : IShape2D, IEquatable<IShape2D>
public struct Polygon : IShape2D, IEquatable<Polygon>
{
private ImmutableArray<Position2D> vertices;
public IEnumerable<Position2D> Vertices { get { return vertices == null ? Enumerable.Empty<Position2D>() : vertices; } }
public IEnumerable<Position2D> 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<Position2D> vertices) // TODO: remove this, params is bad because it allocates an array
{
this.vertices = ImmutableArray.Create<Position2D>(vertices);
this.vertices = vertices.ToImmutableArray();
}
public Polygon(ImmutableArray<Position2D> 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 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;
return vertices.Length == 4 && q.Count() == vertices.Length;
}
return false;
return (other is Polygon otherPolygon && Equals(otherPolygon)) || (other is Rectangle rectangle && Equals(rectangle));
}
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 == other.VertexCount && q.Count() == vertices.Length;
}
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)

38
Bonk/Shapes/Rectangle.cs

@ -10,7 +10,7 @@ namespace MoonTools.Core.Bonk
/// <summary>
/// A rectangle is a shape defined by a minimum and maximum X value and a minimum and maximum Y value.
/// </summary>
public struct Rectangle : IShape2D, IEquatable<IShape2D>
public struct Rectangle : IShape2D, IEquatable<Rectangle>
{
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<IEnumerable<Position2D>>.Default.GetHashCode(Vertices);
return hashCode;
return HashCode.Combine(MinX, MinY, MaxX, MaxY);
}
public static bool operator ==(Rectangle a, Rectangle b)

16
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;
}
}
}

47
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
{
/// <summary>
/// A simplex is a shape with up to n - 2 vertices in the nth dimension.
/// </summary>
public struct Simplex2D : IShape2D
public struct Simplex2D : IShape2D, IEquatable<Simplex2D>
{
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);
}
public bool Equals(Simplex2D other)
{
var q = from a in Vertices
join b in other.Vertices on a equals b
select a;
return false;
return Count == other.Count && q.Count() == Count;
}
public override int GetHashCode()
{
var hashCode = -495772172;
hashCode = hashCode * -1521134295 + EqualityComparer<Vector2>.Default.GetHashCode(a);
hashCode = hashCode * -1521134295 + EqualityComparer<Vector2?>.Default.GetHashCode(b);
hashCode = hashCode * -1521134295 + EqualityComparer<Vector2?>.Default.GetHashCode(c);
hashCode = hashCode * -1521134295 + ZeroSimplex.GetHashCode();
hashCode = hashCode * -1521134295 + OneSimplex.GetHashCode();
hashCode = hashCode * -1521134295 + TwoSimplex.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(Vertices);
return hashCode;
return HashCode.Combine(Vertices);
}
public static bool operator ==(Simplex2D a, Simplex2D b)

10
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();
}

104
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();
}
}
}
}

59
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();

Loading…
Cancel
Save