static public Slice2D ExplodeByPoint(Polygon2D polygon, Vector2D point, int explosionSlices = 0) { if (explosionSlices < 1) { explosionSlices = Slicer2DSettings.GetExplosionSlices(); } Slice2D result = Slice2D.Create(null, 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.GetPolygons().Count < explosionSlices) { foreach (Polygon2D p in new List <Polygon2D>(result.GetPolygons())) { 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.GetPolygons().Count > 0) { if (newResult.slices.Count > 0) { foreach (List <Vector2D> i in newResult.slices) { result.AddSlice(i); } } foreach (Polygon2D poly in newResult.GetPolygons()) { result.AddPolygon(poly); } result.RemovePolygon(p); } } tries += 1; if (tries > 20) { return(result); } } return(result); }
// Slice From Point static public Slice2D SliceFromPoint(Polygon2D polygon, Vector2D point, float rotation) { Slice2D result = Slice2D.Create(null, point, rotation); // Normalize into clockwise polygon.Normalize(); Vector2D sliceA = new Vector2D(point); Vector2D sliceB = new Vector2D(point); sliceA.Push(rotation, 1e+10f / 2); sliceB.Push(rotation, -1e+10f / 2); if (polygon.PointInPoly(point) == false) { return(result); } // Getting the list of intersections List <Vector2D> intersectionsA = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceA)); List <Vector2D> intersectionsB = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceB)); // Sorting intersections from one point if (intersectionsA.Count > 0 && intersectionsB.Count > 0) { sliceA = Vector2DList.GetListSortedToPoint(intersectionsA, point) [0]; sliceB = Vector2DList.GetListSortedToPoint(intersectionsB, point) [0]; } else { return(result); } List <Pair2D> collisionList = new List <Pair2D>(); collisionList.Add(new Pair2D(sliceA, sliceB)); result.AddPolygon(polygon); foreach (Pair2D id in collisionList) { result.AddCollision(id.A); result.AddCollision(id.B); // Sclice line points generated from intersections list Vector2D vec0 = new Vector2D(id.A); Vector2D vec1 = new Vector2D(id.B); double rot = Vector2D.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, LinearSlicer.precision); vec1.Push(rot, -LinearSlicer.precision); // For each in polygons list attempt convex split List <Polygon2D> temp = new List <Polygon2D>(result.GetPolygons()); // necessary? foreach (Polygon2D poly in temp) { // NO, that's the problem Slice2D resultList = LinearSlicer.Slice(poly, new Pair2D(vec0, vec1)); if (resultList.GetPolygons().Count > 0) { if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } foreach (Polygon2D i in resultList.GetPolygons()) { result.AddPolygon(i); } // If it's possible to perform splice, remove parent polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }
static public Slice2D Slice(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 Slice(Polygon2D polygon, Pair2D slice) { Slice2D result = Slice2D.Create(null, slice); if (polygon.LineIntersectHoles(slice).Count > 0) { // When does this happen? - Only when using point slicer!!! if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Slice Intersect Holes (Point Slicer?)"); } return(result); } Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(); Polygon2D currentPoly = polyA; int collisionCount = 0; Pair2D id = Pair2D.Zero(); id.A = polygon.pointsList.Last(); for (int i = 0; i < polygon.pointsList.Count; i++) { id.B = polygon.pointsList[i]; Vector2D intersection = Math2D.GetPointLineIntersectLine(id, slice); if (intersection != null) { polyA.AddPoint(intersection); polyB.AddPoint(intersection); currentPoly = (currentPoly == polyA) ? polyB : polyA; collisionCount++; } currentPoly.AddPoint(id.B); id.A = id.B; } switch (collisionCount) { case 2: if (polyA.pointsList.Count() >= 3) { result.AddPolygon(polyA); } if (polyB.pointsList.Count() >= 3) { result.AddPolygon(polyB); } foreach (Polygon2D poly in result.GetPolygons()) { foreach (Polygon2D hole in polygon.holesList) { if (poly.PolyInPoly(hole) == true) { poly.AddHole(hole); } } } return(result); default: if (Slicer2D.Debug.enabled) { //Debug.LogWarning("Slicer2D: Linear Slice with " + collisionCount + " collision points"); } break; } return(result); }
static private Slice2D MultipleSlice(Polygon2D polygon, Pair2D slice) { Slice2D result = Slice2D.Create(null, slice); List <Pair2D> slices = GetSplitSlices(polygon, slice); //Debug.Log(slices.Count); //Debug.Log(slices[0].A.ToVector2() + " " + slices[0].B.ToVector2()); //Debug.Log(slices[1].A.ToVector2() + " " + slices[1].B.ToVector2()); if (slices.Count < 1) { return(result); } result.AddPolygon(polygon); // Slice line points generated from intersections list foreach (Pair2D id in slices) { result.AddCollision(id.A); result.AddCollision(id.B); Vector2D vec0 = new Vector2D(id.A); Vector2D vec1 = new Vector2D(id.B); double rot = Vector2D.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, precision); vec1.Push(rot, -precision); Pair2D line = new Pair2D(vec0, vec1); // For each in polygons list attempt convex split foreach (Polygon2D poly in (new List <Polygon2D>(result.GetPolygons()))) { Slice2D resultList = SingleSlice(poly, line); if (resultList.GetPolygons().Count > 0) { if (resultList.slices.Count > 0) { foreach (List <Vector2D> i in resultList.slices) { result.AddSlice(i); } } result.AddSlice(line); foreach (Polygon2D i in resultList.GetPolygons()) { result.AddPolygon(i); } // If it's possible to perform splice, remove currently sliced polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }
static public Slice2D Slice(Polygon2D polygon, Pair2D slice, Vector2D vertex) { Slice2D result = Slice2D.Create(null, slice); polygon.pointsList = Vector2DList.GetListStartingPoint(polygon.pointsList, vertex); Polygon2D polyA = new Polygon2D(); Polygon2D polyB = new Polygon2D(); Polygon2D currentPoly = polyA; int collisionCount = 0; Pair2D id = Pair2D.Zero(); id.A = polygon.pointsList.Last(); for (int i = 0; i < polygon.pointsList.Count; i++) { id.B = polygon.pointsList[i]; Vector2D intersection = Math2D.GetPointLineIntersectLine(id, slice); if (intersection != null) // && Vector2D.Distance(intersection, vertex) < 0.001f { if (polyA.pointsList.Count < 1 || Vector2D.Distance(intersection, polyA.pointsList.Last()) > 0.001f) { polyA.AddPoint(intersection); } if (polyB.pointsList.Count < 1 || Vector2D.Distance(intersection, polyB.pointsList.Last()) > 0.001f) { polyB.AddPoint(intersection); } currentPoly = (currentPoly == polyA) ? polyB : polyA; collisionCount++; } if (currentPoly.pointsList.Count < 1 || Vector2D.Distance(id.B, currentPoly.pointsList.Last()) > 0.001f) { currentPoly.AddPoint(id.B); } id.A = id.B; } switch (collisionCount) { case 1: case 2: case 3: if (polyA.pointsList.Count() >= 3) { result.AddPolygon(polyA); } if (polyB.pointsList.Count() >= 3) { result.AddPolygon(polyB); } foreach (Polygon2D poly in result.GetPolygons()) { foreach (Polygon2D hole in polygon.holesList) { if (poly.PolyInPoly(hole) == true) { poly.AddHole(hole); } } } return(result); default: if (Slicer2D.Debug.enabled) { Debug.LogWarning("Slicer2D: Vertex Linear Slice with " + collisionCount + " collision points " + slice.ToString()); } break; } return(result); }