fix bug in Line iterator + comparison cleanup
parent
056cc843e4
commit
12c9f09229
|
@ -1,3 +1,4 @@
|
|||
bin/
|
||||
obj/
|
||||
.vscode
|
||||
.vs
|
||||
|
|
31
Bonk/AABB.cs
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 (other is Polygon otherPolygon && Equals(otherPolygon)) || (other is Rectangle rectangle && Equals(rectangle));
|
||||
}
|
||||
|
||||
return false;
|
||||
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
return false;
|
||||
public bool Equals(Simplex2D other)
|
||||
{
|
||||
var q = from a in Vertices
|
||||
join b in other.Vertices on a equals b
|
||||
select a;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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…
Reference in New Issue