polygon with immutable array
							parent
							
								
									b1a3e37a9d
								
							
						
					
					
						commit
						1430047327
					
				|  | @ -17,6 +17,6 @@ | |||
|   <ItemGroup> | ||||
|     <PackageReference Include="MoonTools.Core.Structs" Version="2.0.0"/> | ||||
|     <PackageReference Include="morelinq" Version="3.2.0"/> | ||||
|     <PackageReference Include="Collections.Pooled" Version="1.0.82"/> | ||||
|     <PackageReference Include="System.Collections.Immutable" Version="1.6.0"/> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  | @ -4,9 +4,10 @@ | |||
|  * https://blog.hamaluik.ca/posts/building-a-collision-engine-part-2-2d-penetration-vectors/ | ||||
|  */ | ||||
| 
 | ||||
| using Collections.Pooled; | ||||
| using MoonTools.Core.Structs; | ||||
| using System; | ||||
| using System.Collections.Immutable; | ||||
| using System.Linq; | ||||
| using System.Numerics; | ||||
| 
 | ||||
| namespace MoonTools.Core.Bonk | ||||
|  | @ -26,12 +27,7 @@ namespace MoonTools.Core.Bonk | |||
|         /// <returns></returns> | ||||
|         public static Vector2 Intersect(IShape2D shapeA, Transform2D Transform2DA, IShape2D shapeB, Transform2D Transform2DB, Simplex2D simplex) | ||||
|         { | ||||
|             var simplexVertices = new PooledList<Vector2>(36, ClearMode.Always); | ||||
| 
 | ||||
|             foreach (var vertex in simplex.Vertices) | ||||
|             { | ||||
|                 simplexVertices.Add(vertex); | ||||
|             } | ||||
|             var simplexVertices = simplex.Vertices.Select(vertex => vertex.ToVector2()).ToImmutableArray(); | ||||
| 
 | ||||
|             var e0 = (simplexVertices[1].X - simplexVertices[0].X) * (simplexVertices[1].Y + simplexVertices[0].Y); | ||||
|             var e1 = (simplexVertices[2].X - simplexVertices[1].X) * (simplexVertices[2].Y + simplexVertices[1].Y); | ||||
|  | @ -55,25 +51,23 @@ namespace MoonTools.Core.Bonk | |||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     simplexVertices.Insert(edge.index, support); | ||||
|                     simplexVertices = simplexVertices.Insert(edge.index, support); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             simplexVertices.Dispose(); | ||||
| 
 | ||||
|             return intersection; | ||||
|         } | ||||
| 
 | ||||
|         private static Edge FindClosestEdge(PolygonWinding winding, PooledList<Vector2> simplexVertices) | ||||
|         private static Edge FindClosestEdge(PolygonWinding winding, ImmutableArray<Vector2> simplexVertices) | ||||
|         { | ||||
|             var closestDistance = float.PositiveInfinity; | ||||
|             var closestNormal = Vector2.Zero; | ||||
|             var closestIndex = 0; | ||||
| 
 | ||||
|             for (int i = 0; i < simplexVertices.Count; i++) | ||||
|             for (int i = 0; i < simplexVertices.Length; i++) | ||||
|             { | ||||
|                 var j = i + 1; | ||||
|                 if (j >= simplexVertices.Count) { j = 0; } | ||||
|                 if (j >= simplexVertices.Length) { j = 0; } | ||||
|                 Vector2 edge = simplexVertices[j] - simplexVertices[i]; | ||||
| 
 | ||||
|                 Vector2 norm; | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ namespace MoonTools.Core.Bonk | |||
|         private Position2D v0; | ||||
|         private Position2D v1; | ||||
| 
 | ||||
|         private IEnumerable<Position2D> vertices | ||||
|         private IEnumerable<Position2D> Vertices | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|  | @ -39,7 +39,7 @@ namespace MoonTools.Core.Bonk | |||
| 
 | ||||
|         public AABB AABB(Transform2D Transform2D) | ||||
|         { | ||||
|             return Bonk.AABB.FromTransformedVertices(vertices, Transform2D); | ||||
|             return Bonk.AABB.FromTransformedVertices(Vertices, Transform2D); | ||||
|         } | ||||
| 
 | ||||
|         public override bool Equals(object obj) | ||||
|  | @ -67,7 +67,7 @@ namespace MoonTools.Core.Bonk | |||
|             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); | ||||
|             hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(Vertices); | ||||
|             return hashCode; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,26 +1,32 @@ | |||
| using System.Linq; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | ||||
| using System.Numerics; | ||||
| using Collections.Pooled; | ||||
| using MoonTools.Core.Structs; | ||||
| using MoreLinq; | ||||
| 
 | ||||
| namespace MoonTools.Core.Bonk | ||||
| { | ||||
|     /// <summary> | ||||
|     /// A Shape defined by an arbitrary collection of vertices. WARNING: Polygon must use an Array internally and therefore will create GC pressure. | ||||
|     /// A Shape defined by an arbitrary collection of vertices. | ||||
|     /// NOTE: A Polygon must have more than 2 vertices and should not have duplicate vertices. | ||||
|     /// </summary> | ||||
|     public struct Polygon : IShape2D, IEquatable<IShape2D> | ||||
|     { | ||||
|         private PooledSet<Position2D> vertices; | ||||
|         private ImmutableArray<Position2D> vertices; | ||||
| 
 | ||||
|         public IEnumerable<Position2D> Vertices { get { return vertices == null ? Enumerable.Empty<Position2D>() : vertices; } } | ||||
| 
 | ||||
|         // vertices are local to the origin | ||||
|         public Polygon(params Position2D[] vertices) | ||||
|         { | ||||
|             this.vertices = new PooledSet<Position2D>(vertices, ClearMode.Always); | ||||
|             this.vertices = ImmutableArray.Create<Position2D>(vertices); | ||||
|         } | ||||
| 
 | ||||
|         public Polygon(ImmutableArray<Position2D> vertices) | ||||
|         { | ||||
|             this.vertices = vertices; | ||||
|         } | ||||
| 
 | ||||
|         public Vector2 Support(Vector2 direction, Transform2D transform) | ||||
|  | @ -47,7 +53,19 @@ namespace MoonTools.Core.Bonk | |||
|         { | ||||
|             if (other is Polygon otherPolygon) | ||||
|             { | ||||
|                 return vertices.SetEquals(otherPolygon.vertices); | ||||
|                 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; | ||||
|  | @ -55,10 +73,7 @@ namespace MoonTools.Core.Bonk | |||
| 
 | ||||
|         public override int GetHashCode() | ||||
|         { | ||||
|             var hashCode = -1404792980; | ||||
|             hashCode = hashCode * -1521134295 + EqualityComparer<PooledSet<Position2D>>.Default.GetHashCode(vertices); | ||||
|             hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(Vertices); | ||||
|             return hashCode; | ||||
|             return HashCode.Combine(vertices, Vertices); | ||||
|         } | ||||
| 
 | ||||
|         public static bool operator ==(Polygon a, Polygon b) | ||||
|  | @ -70,5 +85,15 @@ namespace MoonTools.Core.Bonk | |||
|         { | ||||
|             return !(a == b); | ||||
|         } | ||||
| 
 | ||||
|         public static bool operator ==(Polygon a, Rectangle b) | ||||
|         { | ||||
|             return a.Equals(b); | ||||
|         } | ||||
| 
 | ||||
|         public static bool operator !=(Polygon a, Rectangle b) | ||||
|         { | ||||
|             return !(a == b); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ namespace MoonTools.Core.Bonk | |||
|         public int MaxX { get; } | ||||
|         public int MaxY { get; } | ||||
| 
 | ||||
|         private IEnumerable<Position2D> vertices | ||||
|         public IEnumerable<Position2D> Vertices | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|  | @ -38,12 +38,12 @@ namespace MoonTools.Core.Bonk | |||
| 
 | ||||
|         public Vector2 Support(Vector2 direction, Transform2D transform) | ||||
|         { | ||||
|             return vertices.Select(vertex => Vector2.Transform(vertex, transform.TransformMatrix)).MaxBy(transformed => Vector2.Dot(transformed, direction)).First(); | ||||
|             return Vertices.Select(vertex => Vector2.Transform(vertex, transform.TransformMatrix)).MaxBy(transformed => Vector2.Dot(transformed, direction)).First(); | ||||
|         } | ||||
| 
 | ||||
|         public AABB AABB(Transform2D Transform2D) | ||||
|         { | ||||
|             return Bonk.AABB.FromTransformedVertices(vertices, Transform2D); | ||||
|             return Bonk.AABB.FromTransformedVertices(Vertices, Transform2D); | ||||
|         } | ||||
| 
 | ||||
|         public override bool Equals(object obj) | ||||
|  | @ -76,7 +76,7 @@ namespace MoonTools.Core.Bonk | |||
|             hashCode = hashCode * -1521134295 + MinY.GetHashCode(); | ||||
|             hashCode = hashCode * -1521134295 + MaxX.GetHashCode(); | ||||
|             hashCode = hashCode * -1521134295 + MaxY.GetHashCode(); | ||||
|             hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(vertices); | ||||
|             hashCode = hashCode * -1521134295 + EqualityComparer<IEnumerable<Position2D>>.Default.GetHashCode(Vertices); | ||||
|             return hashCode; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -253,6 +253,66 @@ namespace Tests | |||
| 
 | ||||
|                 (a != b).Should().BeTrue(); | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void PolygonRectangleEqual() | ||||
|             { | ||||
|                 var a = new Polygon( | ||||
|                     new Position2D(1, 1), | ||||
|                     new Position2D(1, -1), | ||||
|                     new Position2D(-1, -1), | ||||
|                     new Position2D(-1, 1) | ||||
|                 ); | ||||
| 
 | ||||
|                 var b = new Rectangle(-1, -1, 1, 1); | ||||
| 
 | ||||
|                 a.Should().BeEquivalentTo(b); | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void PolygonRectangleNotEqual() | ||||
|             { | ||||
|                 var a = new Polygon( | ||||
|                     new Position2D(2, 1), | ||||
|                     new Position2D(1, -1), | ||||
|                     new Position2D(-1, -1), | ||||
|                     new Position2D(-2, 1) | ||||
|                 ); | ||||
| 
 | ||||
|                 var b = new Rectangle(-1, -1, 1, 1); | ||||
| 
 | ||||
|                 a.Should().NotBeEquivalentTo(b); | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void PolygonRectangleEqualOperator() | ||||
|             { | ||||
|                 var a = new Polygon( | ||||
|                     new Position2D(1, 1), | ||||
|                     new Position2D(1, -1), | ||||
|                     new Position2D(-1, -1), | ||||
|                     new Position2D(-1, 1) | ||||
|                 ); | ||||
| 
 | ||||
|                 var b = new Rectangle(-1, -1, 1, 1); | ||||
| 
 | ||||
|                 (a == b).Should().BeTrue(); | ||||
|             } | ||||
| 
 | ||||
|             [Test] | ||||
|             public void PolygonRectangleNotEqualOperator() | ||||
|             { | ||||
|                 var a = new Polygon( | ||||
|                     new Position2D(2, 1), | ||||
|                     new Position2D(1, -1), | ||||
|                     new Position2D(-1, -1), | ||||
|                     new Position2D(-2, 1) | ||||
|                 ); | ||||
| 
 | ||||
|                 var b = new Rectangle(-1, -1, 1, 1); | ||||
| 
 | ||||
|                 (a != b).Should().BeTrue(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public class SimplexTests | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue