static private Slice2D SliceWithTwoHoles(Polygon2D polygon, Pair2D slice, Polygon2D holeA, Polygon2D holeB) { Slice2D result = Slice2D.Create(null, slice); if (holeA == holeB) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Incorrect Split 2: Cannot Split Into Same Hole"); } return(result); } Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(polygon.pointsList); polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(holeA.pointsList, slice)); polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(holeB.pointsList, slice)); foreach (Polygon2D poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); return(result); }
static private Slice2D SliceWithTwoHoles(Polygon2D polygon, List <Vector2D> slice, List <Vector2D> collisionSlice) { Slice2D result = Slice2D.Create(slice); Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(polygon.pointsList); Polygon2D holeA = polygon.PointInHole(slice.First()); Polygon2D holeB = polygon.PointInHole(slice.Last()); if (holeA == null || holeB == null) { Slicer2D.Debug.LogError("ERROR Split"); // Shouldn't really happen return(result); } List <Vector2D> pointsA = Vector2DList.GetListStartingIntersectSlice(holeA.pointsList, slice); List <Vector2D> pointsB = Vector2DList.GetListStartingIntersectSlice(holeB.pointsList, slice); polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { if (Vector2D.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2D.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon2D poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); result.AddSlice(collisionSlice); return(result); }
static public List <Polygon2D> CreateFromPolygonColliderToLocalSpace(PolygonCollider2D collider) { List <Polygon2D> result = new List <Polygon2D>(); if (collider != null && collider.pathCount > 0) { Polygon2D newPolygon = new Polygon2D(); foreach (Vector2 p in collider.GetPath(0)) { newPolygon.AddPoint(p + collider.offset); } result.Add(newPolygon); for (int i = 1; i < collider.pathCount; i++) { Polygon2D hole = new Polygon2D(); foreach (Vector2 p in collider.GetPath(i)) { hole.AddPoint(p + collider.offset); } if (newPolygon.PolyInPoly(hole) == true) { newPolygon.AddHole(hole); } else { result.Add(hole); } } } return(result); }
static private Polygon2D CreateFromPolygonCollider(PolygonCollider2D polygonCollider) { Polygon2D newPolygon = new Polygon2D(); if (polygonCollider != null) { foreach (Vector2 p in polygonCollider.GetPath(0)) { newPolygon.AddPoint(p + polygonCollider.offset); } for (int i = 1; i < polygonCollider.pathCount; i++) { Polygon2D hole = new Polygon2D(); foreach (Vector2 p in polygonCollider.GetPath(i)) { hole.AddPoint(p + polygonCollider.offset); } if (newPolygon.PolyInPoly(hole) == true) { newPolygon.AddHole(hole); } else { Slicer2D.Debug.LogError("Path is not a hole"); } } } return(newPolygon); }
static public Slice2D ExplodeByPoint(Polygon2D polygon, Vector2D point) { Slice2D result = Slice2D.Create(point); if (polygon.PointInPoly(point) == false) { return(result); } float sliceRot = UnityEngine.Random.Range(0, 360); Polygon2D hole = Polygon2D.Create(Polygon2D.PolygonType.Rectangle, 0.1f); hole = hole.ToOffset(point); polygon.AddHole(hole); result.AddPolygon(polygon); int tries = 0; while (result.polygons.Count < Slicer2D.explosionPieces) { foreach (Polygon2D p in new List <Polygon2D>(result.polygons)) { sliceRot += UnityEngine.Random.Range(15, 45) * Mathf.Deg2Rad; Vector2D v = new Vector2D(point); v.Push(sliceRot, 0.4f); Slice2D newResult = SliceFromPoint(p, v, sliceRot); if (newResult.slices.Count > 0) { foreach (List <Vector2D> i in newResult.slices) { result.AddSlice(i); } } if (newResult.polygons.Count > 0) { foreach (Polygon2D poly in newResult.polygons) { result.AddPolygon(poly); } result.RemovePolygon(p); } } tries += 1; if (tries > 20) { return(result); } } return(result); }
public static Mesh Triangulate(Polygon2D polygon, Vector2 UVScale, Vector2 UVOffset, Triangulation triangulation) { polygon.Normalize(); Mesh result = null; switch (triangulation) { case Triangulation.Advanced: Slicer2DProfiler.IncAdvancedTriangulation(); float GC = Slicer2DSettings.GetGarbageCollector(); if (GC > 0 & polygon.GetArea() < GC) { Debug.LogWarning("SmartUtilities2D: Garbage Collector Removed Object Because it was too small"); return(null); } Polygon2D newPolygon = new Polygon2D(PreparePolygon.Get(polygon)); if (newPolygon.pointsList.Count < 3) { Debug.LogWarning("SmartUtilities2D: Mesh is too small for advanced triangulation, using simplified triangulations instead (size: " + polygon.GetArea() + ")"); result = PerformTriangulation(polygon, UVScale, UVOffset); return(result); } foreach (Polygon2D hole in polygon.holesList) { newPolygon.AddHole(new Polygon2D(PreparePolygon.Get(hole, -1))); } result = PerformTriangulation(newPolygon, UVScale, UVOffset); break; case Triangulation.Legacy: Slicer2DProfiler.IncLegacyTriangulation(); List <Vector2> list = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { list.Add(p.ToVector2()); } result = Triangulator.Create(list.ToArray(), UVScale, UVOffset); return(result); } return(result); }
static public Slice2D SliceFromOutsideToHole(Polygon2D polygon, Polygon2D holePoly, List <Vector2D> slice, ComplexCollision collisionSlice) { Slice2D result = Slice2D.Create(null, slice); Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(holePoly.pointsList); polyB.pointsList.Reverse(); List <Vector2D> pointsA = Vector2DList.GetListStartingIntersectSlice(polygon.pointsList, slice); List <Vector2D> pointsB = Vector2DList.GetListStartingIntersectSlice(polyB.pointsList, slice); if (pointsA.Count < 1) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Not enough of slice intersections with polygon (SliceWithOneHole)"); } } polyA.AddPoints(pointsA); // pointsA empty if (collisionSlice.GetPointsInside().Count > 0) { if (Vector2D.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2D.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice.GetPointsInside()); } polyA.AddPoints(pointsB); if (collisionSlice.GetPointsInside().Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice.GetPointsInside()); } foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polyA.PolyInPoly(poly) == true) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); }
public Polygon2D ToOffset(Vector2D pos) { Polygon2D newPolygon = new Polygon2D(pointsList); foreach (Vector2D p in newPolygon.pointsList) { p.Inc(pos); } foreach (Polygon2D p in holesList) { newPolygon.AddHole(p.ToOffset(pos)); } return(newPolygon); }
public Polygon2D ToOffset(Vector2D pos) { Polygon2D newPolygon = new Polygon2D(pointsList); for (int id = 0; id < newPolygon.pointsList.Count; id++) { newPolygon.pointsList[id].Inc(pos); } for (int id = 0; id < holesList.Count; id++) { newPolygon.AddHole(holesList[id].ToOffset(pos)); } return(newPolygon); }
public Polygon2D ToWorldSpace(Transform transform) { Polygon2D newPolygon = new Polygon2D(); for (int id = 0; id < pointsList.Count; id++) { newPolygon.AddPoint(transform.TransformPoint(pointsList[id].ToVector2())); } for (int id = 0; id < holesList.Count; id++) { newPolygon.AddHole(holesList[id].ToWorldSpace(transform)); } return(newPolygon); }
public Polygon2D Copy() { Polygon2D newPolygon = new Polygon2D(); foreach (Vector2D id in pointsList) { newPolygon.AddPoint(id.ToVector2()); } foreach (Polygon2D p in holesList) { newPolygon.AddHole(p.Copy()); } return(newPolygon); }
public Polygon2D ToLocalSpace(Transform transform) { Polygon2D newPolygon = new Polygon2D(); foreach (Vector2D id in pointsList) { newPolygon.AddPoint(transform.InverseTransformPoint(id.ToVector2())); } foreach (Polygon2D p in holesList) { newPolygon.AddHole(p.ToLocalSpace(transform)); } return(newPolygon); }
public Polygon2D ToWorldSpace(Transform transform) { Polygon2D newPolygon = new Polygon2D(); foreach (Vector2D id in pointsList) { newPolygon.AddPoint(transform.TransformPoint(id.vector)); } foreach (Polygon2D p in holesList) { newPolygon.AddHole(p.ToWorldSpace(transform)); } return(newPolygon); }
public static Mesh Triangulate(Polygon2D polygon, Vector2 UVScale, Vector2 UVOffset, Triangulation triangulation) { Mesh result = null; switch (triangulation) { case Triangulation.Advanced: if (garbageCollector == true & polygon.GetArea() < 0.005f) { Debug.LogWarning("SmartUtilities2D: Garbage Collector Removed Object Because it was too small"); return(null); } Polygon2D newPolygon = new Polygon2D(PreparePolygon(polygon)); if (newPolygon.pointsList.Count < 3) { Debug.LogWarning("SmartUtilities2D: Mesh is too small for advanced triangulation, using simplified triangulations instead (size: " + polygon.GetArea() + ")"); result = TriangulateAdvanced(polygon, UVScale, UVOffset); return(result); } foreach (Polygon2D hole in polygon.holesList) { newPolygon.AddHole(new Polygon2D(PreparePolygon(hole, -1))); } result = TriangulateAdvanced(newPolygon, UVScale, UVOffset); break; case Triangulation.Legacy: List <Vector2> list = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { list.Add(p.ToVector2()); } result = Triangulator.Create(list.ToArray()); return(result); } return(result); }
static public Slice2D ComplexCutSlice(Polygon2D polygon, ComplexCut complexCut) { List <Vector2D> slice = complexCut.GetPointsList(); Slice2D result = Slice2D.Create(complexCut); if (slice.Count < 1) { return(result); } if (Math2D.SliceIntersectItself(slice)) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Complex Cut Slicer intersected with itself!"); } return(result); } Vector2D startPoint = null; foreach (Vector2D id in slice) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } Polygon2D newPolygon = new Polygon2D(slice); slice = Vector2DList.GetListStartingPoint(slice, startPoint); slice.Add(startPoint); if (polygon.PolyInPoly(newPolygon)) { polygon.AddHole(newPolygon); result.AddPolygon(polygon); return(result); } result = ComplexSlicer.Slice(polygon, slice); return(result); }
public static Mesh Triangulate(Polygon2D polygon, Vector2 UVScale, Vector2 UVOffset, Triangulation triangulation) { Mesh result = null; switch (triangulation) { case Triangulation.Advanced: Polygon2D newPolygon = new Polygon2D(PreparePolygon(polygon)); foreach (Polygon2D hole in polygon.holesList) { newPolygon.AddHole(new Polygon2D(PreparePolygon(hole))); } if (newPolygon.pointsList.Count < 3) { if ((int)polygon.GetArea() == 0) { Slicer2D.Debug.LogError("mesh is too small for advanced triangulation, using Legacy triangulation instead"); List <Vector2> listA = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { listA.Add(p.vector); } result = Triangulator.Create(listA.ToArray()); return(result); } } result = TriangulateAdvanced(newPolygon, UVScale, UVOffset); break; case Triangulation.Legacy: List <Vector2> list = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { list.Add(p.vector); } result = Triangulator.Create(list.ToArray()); break; } return(result); }
public static Mesh Triangulate(Polygon2D polygon, Vector2 UVScale, Vector2 UVOffset, Triangulation triangulation) { Mesh result = null; switch (triangulation) { case Triangulation.Advanced: Polygon2D newPolygon = new Polygon2D(PreparePolygon(polygon)); if (newPolygon.pointsList.Count < 3) { Debug.LogWarning("mesh is too small for advanced triangulation, using simplified triangulations instead (size: " + polygon.GetArea() + ")"); result = TriangulateAdvanced(polygon, UVScale, UVOffset); return(result); } foreach (Polygon2D hole in polygon.holesList) { newPolygon.AddHole(new Polygon2D(PreparePolygon(hole))); } result = TriangulateAdvanced(newPolygon, UVScale, UVOffset); break; case Triangulation.Legacy: List <Vector2> list = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { list.Add(p.ToVector2()); } result = UnityDefaultTriangulator.Create(list.ToArray()); return(result); } return(result); }
static public Slice2D LinearCutSlice(Polygon2D polygon, LinearCut linearCut) { List <Vector2D> slice = linearCut.GetPointsList(); Slice2D result = Slice2D.Create(linearCut); if (slice.Count < 1) { return(result); } Vector2D startPoint = null; foreach (Vector2D id in slice) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } Polygon2D newPolygon = new Polygon2D(slice); slice = Vector2DList.GetListStartingPoint(slice, startPoint); slice.Add(startPoint); if (polygon.PolyInPoly(newPolygon)) { polygon.AddHole(newPolygon); result.AddPolygon(polygon); return(result); } result = ComplexSlicer.Slice(polygon, slice); return(result); }
static private Slice2D SliceWithOneHole(Polygon2D polygon, List <Vector2D> slice, List <Vector2D> collisionSlice) { Slice2D result = Slice2D.Create(slice); Polygon2D holeA = polygon.PointInHole(slice.First()); Polygon2D holeB = polygon.PointInHole(slice.Last()); Polygon2D holePoly = (holeA != null) ? holeA : holeB; if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false) { if (holeA == holeB) { if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular) { return(result); } if (holeA == null) { Slicer2D.Debug.LogError("This happened when collider had a lot of paths but they were not holes"); return(result); } List <Vector2D> slice2 = new List <Vector2D> (slice); Polygon2D polyA = new Polygon2D(polygon.pointsList); Polygon2D polyB = new Polygon2D(slice); Polygon2D polyC = new Polygon2D(slice2); // Get First Point - NOT FINISHED WITH INTERSECTION int Add; List <Vector2D> list; List <Pair2D> iterateList = Pair2D.GetList(holeA.pointsList); Add = 0; list = new List <Vector2D> (); foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 1) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2D.Distance(list.First(), slice.First()) < Vector2D.Distance(list.First(), slice.Last())) { slice.Reverse(); } polyB.AddPoints(list); } Add = 0; list = new List <Vector2D> (); foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2D.Distance(list.First(), slice2.First()) < Vector2D.Distance(list.First(), slice2.Last())) { slice2.Reverse(); } polyC.AddPoints(list); } if (polyB.GetArea() > polyC.GetArea()) { Polygon2D swap = polyB; polyB = polyC; polyC = swap; } // Add holes to new created polygon foreach (Polygon2D poly in polygon.holesList) { if (poly != holeA && polyB.PolyInPoly(poly) == true) { polyB.AddHole(poly); } } if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(polyB); } polyA.AddHole(polyC); // Adds polygons if they are not in the hole foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holeA && polyC.PolyInPoly(poly) == false) { polyA.AddHole(poly); } } result.AddPolygon(polyA); result.AddSlice(collisionSlice); return(result); } else if (holePoly != null) { Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(holePoly.pointsList); polyB.pointsList.Reverse(); List <Vector2D> pointsA = Vector2DList.GetListStartingIntersectSlice(polygon.pointsList, slice); List <Vector2D> pointsB = Vector2DList.GetListStartingIntersectSlice(polyB.pointsList, slice); if (pointsA.Count < 1) { Slicer2D.Debug.LogError(pointsA.Count + " " + polygon.pointsList.Count); } polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { // pointsA empty if (Vector2D.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2D.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly) { polyA.AddHole(poly); } } result.AddPolygon(polyA); result.AddSlice(collisionSlice); return(result); } } return(result); }
public static Mesh Triangulate3D(Polygon2D polygon, float z, Vector2 UVScale, Vector2 UVOffset, Triangulation triangulation) { Mesh result = null; switch (triangulation) { case Triangulation.Advanced: Polygon2D newPolygon = new Polygon2D(PreparePolygon(polygon)); foreach (Polygon2D hole in polygon.holesList) { newPolygon.AddHole(new Polygon2D(PreparePolygon(hole))); } if (newPolygon.pointsList.Count < 3) { if ((int)polygon.GetArea() == 0) { List <Vector2> l = new List <Vector2>(); foreach (Vector2D p in polygon.pointsList) { l.Add(p.ToVector2()); } result = UnityDefaultTriangulator.Create(l.ToArray());; return(result); } } List <Vector3> sideVertices = new List <Vector3>(); List <int> sideTriangles = new List <int>(); int vCount = 0; foreach (Pair2D pair in Pair2D.GetList(polygon.pointsList)) { Vector3 pointA = new Vector3((float)pair.A.x, (float)pair.A.y, 0); Vector3 pointB = new Vector3((float)pair.B.x, (float)pair.B.y, 0); Vector3 pointC = new Vector3((float)pair.B.x, (float)pair.B.y, 1); Vector3 pointD = new Vector3((float)pair.A.x, (float)pair.A.y, 1); sideVertices.Add(pointA); sideVertices.Add(pointB); sideVertices.Add(pointC); sideVertices.Add(pointD); sideTriangles.Add(vCount + 2); sideTriangles.Add(vCount + 1); sideTriangles.Add(vCount + 0); sideTriangles.Add(vCount + 0); sideTriangles.Add(vCount + 3); sideTriangles.Add(vCount + 2); vCount += 4; } Mesh meshA = TriangulateAdvanced(newPolygon, UVScale, UVOffset); Mesh meshB = new Mesh(); List <Vector3> verticesB = new List <Vector3>(); foreach (Vector3 v in meshA.vertices) { verticesB.Add(new Vector3(v.x, v.y, v.z + z)); } meshB.vertices = verticesB.ToArray(); meshB.triangles = meshA.triangles.Reverse().ToArray(); Mesh mesh = new Mesh(); mesh.vertices = sideVertices.ToArray(); mesh.triangles = sideTriangles.ToArray(); List <Vector3> vertices = new List <Vector3>(); foreach (Vector3 v in meshA.vertices) { vertices.Add(v); } foreach (Vector3 v in meshB.vertices) { vertices.Add(v); } foreach (Vector3 v in sideVertices) { vertices.Add(v); } mesh.vertices = vertices.ToArray(); List <int> triangles = new List <int>(); foreach (int p in meshA.triangles) { triangles.Add(p); } int count = meshA.vertices.Count(); foreach (int p in meshB.triangles) { triangles.Add(p + count); } count = meshA.vertices.Count() + meshB.vertices.Count(); foreach (int p in sideTriangles) { triangles.Add(p + count); } mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); mesh.RecalculateBounds(); result = mesh; break; } return(result); }
// Create Polygon Inside? Extended Method? static private Slice2D SlicePolygonInside(Polygon2D polygon, List <Vector2D> slice) { Slice2D result = Slice2D.Create(slice); if (Slicer2D.complexSliceType != Slicer2D.SliceType.SliceHole) { return(result); } Polygon2D newPoly = new Polygon2D(); bool createPoly = false; foreach (Pair2D pairA in Pair2D.GetList(slice, false)) { foreach (Pair2D pairB in Pair2D.GetList(slice, false)) { Vector2D intersection = Math2D.GetPointLineIntersectLine(pairA, pairB); if (intersection != null && (pairA.A != pairB.A && pairA.B != pairB.B && pairA.A != pairB.B && pairA.B != pairB.A)) { createPoly = !createPoly; newPoly.AddPoint(intersection); } } if (createPoly == true) { newPoly.AddPoint(pairA.B); } } bool inHoles = false; foreach (Polygon2D hole in polygon.holesList) { if (hole.PolyInPoly(newPoly) == true) { inHoles = true; } } if (inHoles == false && newPoly.pointsList.Count > 2 && polygon.PolyInPoly(newPoly) == true) { polygon.AddHole(newPoly); List <Polygon2D> polys = new List <Polygon2D> (polygon.holesList); foreach (Polygon2D hole in polys) { if (newPoly.PolyInPoly(hole) == true) { polygon.holesList.Remove(hole); newPoly.AddHole(hole); } } result.AddPolygon(polygon); return(result); } return(result); }
static private Merge2D SliceWithoutHoles(Polygon2D polygon, List <Vector2D> slice, MergeCollision mergeCollision) { Merge2D result = Merge2D.Create(slice); // Simple non-hole slice Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(); Polygon2D currentPoly = polyA; List <Vector2D> slices = new List <Vector2D>(mergeCollision.GetPoints()); foreach (Pair2D p in Pair2D.GetList(polygon.pointsList)) { List <Vector2D> intersections = Math2D.GetListLineIntersectSlice(p, slice); if (intersections.Count() > 0) { if (intersections.Count == 2) { Vector2D first = intersections.First(); Vector2D last = intersections.Last(); if (Vector2D.Distance(last, p.A) < Vector2D.Distance(first, p.A)) { first = intersections.Last(); last = intersections.First(); } // Add Inside Points if (mergeCollision.GetPoints().Count > 0) // InsidePlus { if (Vector2D.Distance(first, mergeCollision.Last()) < Vector2D.Distance(first, mergeCollision.First())) { mergeCollision.Reverse(); } currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } ///// currentPoly = polyB; if (mergeCollision.GetPoints().Count > 0) // InsidePlus( { currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } currentPoly = polyA; } if (intersections.Count == 1) { Vector2D intersection = intersections.First(); ///// Add Inside Points if (mergeCollision.GetPoints().Count > 0) //InsidePlus { if (Vector2D.Distance(intersection, mergeCollision.Last()) < Vector2D.Distance(intersection, mergeCollision.First())) { mergeCollision.Reverse(); } currentPoly.AddPoints(mergeCollision.GetPoints()); // InsidePlus } ///// currentPoly = (currentPoly == polyA) ? polyB : polyA; } } currentPoly.AddPoint(p.B); } Polygon2D mainPoly = polyA; if (polyB != null && polyB.GetArea() > polyA.GetArea()) { mainPoly = polyB; } result.AddPolygon(mainPoly); foreach (Polygon2D hole in polygon.holesList) { mainPoly.AddHole(hole); } result.AddSlice(slices); return(result); }
static private Slice2D SliceWithOneHole(Polygon2D polygon, Pair2D slice, Polygon2D holeA, Polygon2D holeB) { Slice2D result = Slice2D.Create(null, slice); if (holeA == holeB) { Polygon2D polyA = new Polygon2D(polygon.pointsList); Polygon2D polyB = new Polygon2D(); Polygon2D polyC = new Polygon2D(); Polygon2D currentPoly = polyB; foreach (Pair2D pair in Pair2D.GetList(holeA.pointsList)) { Vector2D point = Math2D.GetPointLineIntersectLine(slice, pair); if (point != null) { polyB.AddPoint(point); polyC.AddPoint(point); currentPoly = (currentPoly == polyB) ? polyC : polyB; } currentPoly.AddPoint(pair.B); } if (polyB.pointsList.Count > 2 && polyC.pointsList.Count > 2) { if (polyB.GetArea() > polyC.GetArea()) { polyA.AddHole(polyB); result.AddPolygon(polyC); } else { result.AddPolygon(polyB); polyA.AddHole(polyC); } result.AddPolygon(polyA); } return(result); // Cross From Side To Polygon } else if (polygon.PointInPoly(slice.A) == false || polygon.PointInPoly(slice.B) == false) { Polygon2D holePoly = (holeA != null) ? holeA : holeB; if (holePoly != null) { Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(holePoly.pointsList); polyB.pointsList.Reverse(); polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(polygon.pointsList, slice)); polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(polyB.pointsList, slice)); foreach (Polygon2D poly in polygon.holesList) { if (poly != holePoly) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } } return(result); }
static public Slice2D SliceIntoSameHole(Polygon2D polygon, Polygon2D holePoly, List <Vector2D> slice, ComplexCollision collisionSlice) { Slice2D result = Slice2D.Create(null, slice); // Slice Into Same Pair if (collisionSlice.polygonCollisionPairs.Count == 1) { Polygon2D slicePoly = new Polygon2D(collisionSlice.GetPointsInsidePlus()); Polygon2D newHole = new Polygon2D(); if (slicePoly.PolyInPoly(holePoly)) { newHole = slicePoly; } else { foreach (Pair2D pair in Pair2D.GetList(holePoly.pointsList)) { newHole.AddPoint(pair.A); if (Vector2D.Distance(pair.A, collisionSlice.Last()) < Vector2D.Distance(pair.A, collisionSlice.First())) { collisionSlice.Reverse(); } if (Math2D.LineIntersectSlice(pair, slice)) { newHole.AddPoints(collisionSlice.GetPoints()); } } } Polygon2D polygonA = new Polygon2D(polygon.pointsList); polygonA.AddHole(newHole); // Adds polygons if they are not in the hole foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polygonA.PolyInPoly(poly) == true) { polygonA.AddHole(poly); } } if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(slicePoly); } result.AddPolygon(polygonA); return(result); // Slice Into Different Pair } else { Polygon2D polyA = new Polygon2D(polygon.pointsList); Polygon2D newHoleA = new Polygon2D(); Polygon2D newHoleB = new Polygon2D(); List <Pair2D> iterateList = Pair2D.GetList(holePoly.pointsList); bool addPoints = false; foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice); switch (addPoints) { case false: if (intersect.Count > 0) { addPoints = true; } break; case true: newHoleA.AddPoint(pair.A); if (intersect.Count > 0) { addPoints = false; if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First())) { collisionSlice.Reverse(); } newHoleA.AddPoints(collisionSlice.GetPointsInsidePlus()); } break; } } addPoints = true; foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice); switch (addPoints) { case false: if (intersect.Count > 0) { addPoints = true; } break; case true: newHoleB.AddPoint(pair.A); if (intersect.Count > 0) { addPoints = false; if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First())) { collisionSlice.Reverse(); } newHoleB.AddPoints(collisionSlice.GetPointsInsidePlus()); } break; } } if (newHoleB.GetArea() > newHoleA.GetArea()) { Polygon2D tempPolygon = newHoleA; newHoleA = newHoleB; newHoleB = tempPolygon; } polyA.AddHole(newHoleA); if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(newHoleB); } // Adds polygons if they are not in the hole foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polyA.PolyInPoly(poly) == true) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } }
// Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice static public Slice2D PolygonSlice(Polygon2D polygon, Polygon2D slicePolygon) { List <Polygon2D> holes = polygon.holesList; polygon = new Polygon2D(new List <Vector2D>(polygon.pointsList)); polygon.holesList = holes; slicePolygon = new Polygon2D(new List <Vector2D>(slicePolygon.pointsList)); Slice2D result = Slice2D.Create(null, polygon); Slicer2D.SliceType tempSliceType = Slicer2D.complexSliceType; Slicer2D.complexSliceType = Slicer2D.SliceType.SliceHole; slicePolygon.Normalize(); polygon.Normalize(); // Eat a polygon completely // Complex Slicer does not register slice in this case if (slicePolygon.PolyInPoly(polygon) == true) { result.AddPolygon(polygon); return(result); } // Cut a hole inside (how does this work if it collides with other hole?) if (polygon.PolyInPoly(slicePolygon) == true) { polygon.AddHole(slicePolygon); result.AddPolygon(polygon); Math2D.Distance distance = Math2D.Distance.PolygonToPolygon(polygon, slicePolygon); if (distance != null && distance.value < precision) { return(SlicePolygonFromEdge(polygon, slicePolygon)); } return(result); } // Act as Regular Slice Vector2D startPoint = null; foreach (Vector2D id in slicePolygon.pointsList) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } if (startPoint == null) { if (Math2D.PolyIntersectPoly(polygon, slicePolygon)) { return(SlicePolygonFromEdge(polygon, slicePolygon)); } if (Slicer2D.Debug.enabled) { Debug.LogWarning("Starting Point Error In PolygonSlice"); } return(result); } slicePolygon.pointsList = Vector2DList.GetListStartingPoint(slicePolygon.pointsList, startPoint); /* * List<Vector2D> s = new List<Vector2D> (); * foreach (Pair2D pair in Pair2D.GetList(polygonSlice.pointsList, false)) { * List<Vector2D> stackList = polygon.GetListSliceIntersectPoly(pair); * stackList = Vector2DList.GetListSortedToPoint (stackList, pair.A); * Vector2D old = pair.A; * s.Add (old); * * foreach (Vector2D id in stackList) { * s.Add (new Vector2D((old.GetX() + id.GetX()) / 2, (old.GetY() + id.GetY()) / 2)); * old = id; * } * } * * polygonSlice.pointsList = s; */ slicePolygon.AddPoint(startPoint); // Not Necessary if (polygon.SliceIntersectPoly(slicePolygon.pointsList) == false) { return(result); } // Slice More Times? result = ComplexSlicer.Slice(polygon, new List <Vector2D> (slicePolygon.pointsList)); if (result.GetPolygons().Count < 1) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Returns Empty Polygon Slice"); } } Slicer2D.complexSliceType = tempSliceType; return(result); }
// Create Polygon Inside? Extended Method? public static Slice2D SlicePolygonInside(Polygon2D polygon, List <Vector2D> slice) { Slice2D result = Slice2D.Create(null, slice); if (Slicer2D.complexSliceType != Slicer2D.SliceType.SliceHole) { return(result); } List <List <Vector2D> > checkSlices = new List <List <Vector2D> >(); List <Vector2D> curSlice = null; foreach (Vector2D p in slice) { if (polygon.PointInPoly(p)) { if (curSlice == null) { curSlice = new List <Vector2D>(); checkSlices.Add(curSlice); } curSlice.Add(p); } else { curSlice = null; } } //bool createPoly = false; List <Polygon2D> newPolygons = new List <Polygon2D>(); Polygon2D newPoly = null; foreach (List <Vector2D> checkSlice in checkSlices) { foreach (Pair2D pairA in Pair2D.GetList(checkSlice, false)) { foreach (Pair2D pairB in Pair2D.GetList(checkSlice, false)) { Vector2D intersection = Math2D.GetPointLineIntersectLine(pairA, pairB); if (intersection != null && (pairA.A != pairB.A && pairA.B != pairB.B && pairA.A != pairB.B && pairA.B != pairB.A)) { if (newPoly == null) { newPoly = new Polygon2D(); newPolygons.Add(newPoly); newPoly.AddPoint(intersection); } else { //newPoly.AddPoint (intersection); newPoly = null; } } } if (newPoly != null) { newPoly.AddPoint(pairA.B); } } } foreach (Polygon2D poly in new List <Polygon2D>(newPolygons)) { if (poly.pointsList.Count < 3) { newPolygons.Remove(poly); continue; } } if (newPolygons.Count > 0) { result.AddPolygon(polygon); foreach (Polygon2D poly in newPolygons) { List <Polygon2D> polys = new List <Polygon2D> (polygon.holesList); foreach (Polygon2D hole in polys) { if (poly.PolyInPoly(hole) == true) { polygon.holesList.Remove(hole); poly.AddHole(hole); } } polygon.AddHole(poly); } return(result); } return(result); }
static private Slice2D SliceWithTwoHoles(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice) { Slice2D result = Slice2D.Create(null, slice); if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular) { return(result); } Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(polygon.pointsList); Polygon2D holeA = polygon.PointInHole(slice.First()); Polygon2D holeB = polygon.PointInHole(slice.Last()); if (holeA == null || holeB == null) { // Shouldn't really happen no more if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer: ERROR Split"); } return(result); } List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus()); List <Vector2D> pointsA = Vector2DList.GetListStartingIntersectSlice(holeA.pointsList, slice); List <Vector2D> pointsB = Vector2DList.GetListStartingIntersectSlice(holeB.pointsList, slice); polyA.AddPoints(pointsA); if (collisionSlice.GetPointsInside().Count > 0) { if (Vector2D.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2D.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice.GetPointsInside()); } polyA.AddPoints(pointsB); if (collisionSlice.GetPointsInside().Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice.GetPointsInside()); } foreach (Polygon2D poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); result.AddSlice(slices); return(result); }
// Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice static public Slice2D Slice(Polygon2D polygon, Polygon2D polygonSlice) { Slice2D result = Slice2D.Create(polygon); Slicer2D.SliceType tempSliceType = Slicer2D.complexSliceType; Slicer2D.complexSliceType = Slicer2D.SliceType.SliceHole; polygonSlice.Normalize(); polygon.Normalize(); // Eat a polygon completely // Complex Slicer does not register slice in this case if (polygonSlice.PolyInPoly(polygon) == true) { result.AddPolygon(polygon); return(result); } if (polygon.PolyInPoly(polygonSlice) == true) { polygon.AddHole(polygonSlice); result.AddPolygon(polygon); return(result); } // Act as Regular Slice Vector2D startPoint = null; foreach (Vector2D id in polygonSlice.pointsList) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } if (startPoint == null) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Starting Point Error In PolygonSlice"); } return(result); } polygonSlice.pointsList = Vector2DList.GetListStartingPoint(polygonSlice.pointsList, startPoint); /* * List<Vector2D> s = new List<Vector2D> (); * foreach (Pair2D pair in Pair2D.GetList(polygonSlice.pointsList, false)) { * List<Vector2D> stackList = polygon.GetListSliceIntersectPoly(pair); * stackList = Vector2DList.GetListSortedToPoint (stackList, pair.A); * Vector2D old = pair.A; * s.Add (old); * * foreach (Vector2D id in stackList) { * s.Add (new Vector2D((old.GetX() + id.GetX()) / 2, (old.GetY() + id.GetY()) / 2)); * old = id; * } * } * * polygonSlice.pointsList = s; */ polygonSlice.AddPoint(startPoint); // Not Necessary if (polygon.SliceIntersectPoly(polygonSlice.pointsList) == false) { return(result); } // Slice More Times? result = ComplexSlicer.Slice(polygon, new List <Vector2D> (polygonSlice.pointsList)); if (result.polygons.Count < 1) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Returns Empty Polygon Slice"); } } Slicer2D.complexSliceType = tempSliceType; return(result); }
static private Slice2D SliceWithOneHole(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice) { Slice2D result = Slice2D.Create(null, slice); Polygon2D holeA = polygon.PointInHole(slice.First()); Polygon2D holeB = polygon.PointInHole(slice.Last()); Polygon2D holePoly = (holeA != null) ? holeA : holeB; if (holePoly == null) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: This happened when collider had a lot of paths but they were not holes"); } return(result); } List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus()); if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false) { // Slicing Into The Same Hole if (holeA == holeB) { if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular) { return(result); } if (collisionSlice.polygonCollisionPairs.Count == 1) { Polygon2D slicePoly = new Polygon2D(collisionSlice.GetPointsInsidePlus()); Polygon2D newHole = new Polygon2D(); if (slicePoly.PolyInPoly(holePoly)) { newHole = slicePoly; } else { foreach (Pair2D pair in Pair2D.GetList(holePoly.pointsList)) { newHole.AddPoint(pair.A); if (Vector2D.Distance(pair.A, collisionSlice.Last()) < Vector2D.Distance(pair.A, collisionSlice.First())) { collisionSlice.Reverse(); } if (Math2D.LineIntersectSlice(pair, slice)) { newHole.AddPoints(collisionSlice.GetPoints()); } } } Polygon2D polygonA = new Polygon2D(polygon.pointsList); polygonA.AddHole(newHole); // Adds polygons if they are not in the hole foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polygonA.PolyInPoly(poly) == true) { polygonA.AddHole(poly); } } if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(slicePoly); } result.AddPolygon(polygonA); result.AddSlice(slices); return(result); } else { Polygon2D polyA = new Polygon2D(polygon.pointsList); Polygon2D newHoleA = new Polygon2D(); Polygon2D newHoleB = new Polygon2D(); List <Pair2D> iterateList = Pair2D.GetList(holePoly.pointsList); bool addPoints = false; foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice); switch (addPoints) { case false: if (intersect.Count > 0) { addPoints = true; } break; case true: newHoleA.AddPoint(pair.A); if (intersect.Count > 0) { addPoints = false; if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First())) { collisionSlice.Reverse(); } newHoleA.AddPoints(collisionSlice.GetPointsInsidePlus()); } break; } } addPoints = true; foreach (Pair2D pair in iterateList) { List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice); switch (addPoints) { case false: if (intersect.Count > 0) { addPoints = true; } break; case true: newHoleB.AddPoint(pair.A); if (intersect.Count > 0) { addPoints = false; if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First())) { collisionSlice.Reverse(); } newHoleB.AddPoints(collisionSlice.GetPointsInsidePlus()); } break; } } if (newHoleB.GetArea() > newHoleA.GetArea()) { Polygon2D tempPolygon = newHoleA; newHoleA = newHoleB; newHoleB = tempPolygon; } polyA.AddHole(newHoleA); if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(newHoleB); } // Adds polygons if they are not in the hole foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polyA.PolyInPoly(poly) == true) { polyA.AddHole(poly); } } result.AddPolygon(polyA); result.AddSlice(slices); return(result); } // Slicing From Outside To Hole } else if (holePoly != null) { Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(holePoly.pointsList); polyB.pointsList.Reverse(); List <Vector2D> pointsA = Vector2DList.GetListStartingIntersectSlice(polygon.pointsList, slice); List <Vector2D> pointsB = Vector2DList.GetListStartingIntersectSlice(polyB.pointsList, slice); if (pointsA.Count < 1) { if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: " + pointsA.Count + " " + polygon.pointsList.Count); } } polyA.AddPoints(pointsA); // pointsA empty if (collisionSlice.GetPointsInside().Count > 0) { if (Vector2D.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2D.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice.GetPointsInside()); } polyA.AddPoints(pointsB); if (collisionSlice.GetPointsInside().Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice.GetPointsInside()); } foreach (Polygon2D poly in polygon.holesList) // Check for errors? { if (poly != holePoly && polyA.PolyInPoly(poly) == true) { polyA.AddHole(poly); } } result.AddPolygon(polyA); result.AddSlice(slices); return(result); } } return(result); }