static private Slice2D SliceWithTwoHoles(Polygon polygon, Pair2f slice, Polygon holeA, Polygon holeB) { Slice2D result = Slice2D.Create(); if (holeA == holeB) { Debug.LogError("Slicer2D: Incorrect Split 2: Cannot Split Into Same Hole"); return(result); } Polygon polyA = new Polygon(); Polygon polyB = new Polygon(polygon.pointsList); polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(holeA.pointsList, slice)); polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(holeB.pointsList, slice)); foreach (Polygon poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); return(result); }
static private Slice2D SliceWithTwoHoles(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice) { Slice2D result = Slice2D.Create(); Polygon polyA = new Polygon(); Polygon polyB = new Polygon(polygon.pointsList); Polygon holeA = polygon.PointInHole(slice.First()); Polygon holeB = polygon.PointInHole(slice.Last()); if (holeA == null || holeB == null) { Debug.LogError("Slicer2D: ERROR Split"); // Shouldn't really happen return(result); } List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(holeA.pointsList, slice); List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(holeB.pointsList, slice); polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); return(result); }
// Linear Slice static public Slice2D Slice(Polygon polygon, Pair2f slice) { Slice2D result = Slice2D.Create(); // Normalize into clockwise polygon.Normalize(); // Getting the list of intersections List <Vector2f> intersections = polygon.GetListSliceIntersectPoly(slice); // Sorting intersections from one point intersections = VectorList2f.GetListSortedToPoint(intersections, slice.A); if (intersections.Count < 2) { return(result); } List <Pair2f> collisionList = new List <Pair2f>(); // Dividing intersections into single slices - This method doesn't look like very reliable!!! // Optimize this (polygon.PointInPoly) line // Fix this nonsense!!! foreach (Pair2f p in Pair2f.GetList(intersections, false)) { if (polygon.PointInPoly(new Vector2f((p.B.GetX() + p.A.GetX()) / 2, (p.B.GetY() + p.A.GetY()) / 2)) == true) { collisionList.Add(p); intersections.Remove(p.A); intersections.Remove(p.B); } } result.AddPolygon(polygon); // Slice line points generated from intersections list foreach (Pair2f id in collisionList) { result.AddCollision(id.A); result.AddCollision(id.B); Vector2f vec0 = new Vector2f(id.A); Vector2f vec1 = new Vector2f(id.B); float rot = Vector2f.Atan2(vec0, vec1); // Slightly pushing slice line so it intersect in all cases vec0.Push(rot, precision); vec1.Push(rot, -precision); // For each in polygons list attempt convex split foreach (Polygon poly in (new List <Polygon>(result.polygons))) { Slice2D resultList = SingleSlice(poly, new Pair2f(vec0, vec1)); if (resultList.polygons.Count > 0) { foreach (Polygon i in resultList.polygons) { 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 private Slice2D SliceWithOneHole(Polygon polygon, Pair2f slice, Polygon holeA, Polygon holeB) { Slice2D result = Slice2D.Create(); if (holeA == holeB) { Polygon polyA = new Polygon(polygon.pointsList); Polygon polyB = new Polygon(); Polygon polyC = new Polygon(); Polygon currentPoly = polyB; foreach (Pair2f pair in Pair2f.GetList(holeA.pointsList)) { Vector2f point = MathHelper.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) { Polygon holePoly = (holeA != null) ? holeA : holeB; if (holePoly != null) { Polygon polyA = new Polygon(); Polygon polyB = new Polygon(holePoly.pointsList); polyB.pointsList.Reverse(); polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(polygon.pointsList, slice)); polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(polyB.pointsList, slice)); foreach (Polygon poly in polygon.holesList) { if (poly != holePoly) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } } return(result); }
// Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice static public Slice2D Slice(Polygon polygon, Polygon polygonSlice) { Slice2D result = Slice2D.Create(); 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 Vector2f startPoint = null; foreach (Vector2f id in polygonSlice.pointsList) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } if (startPoint == null) { Debug.LogError("Slicer2D: Starting Point Error In PolygonSlice"); return(result); } polygonSlice.pointsList = VectorList2f.GetListStartingPoint(polygonSlice.pointsList, startPoint); polygonSlice.AddPoint(startPoint); //List<Vector2f> s = new List<Vector2f> (); //foreach (Pair2f pair in Pair2f.GetList(polygonSlice.pointsList, false)) { // List<Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair); // stackList = VectorList2f.GetListSortedToPoint (stackList, pair.A); // s.Add (pair.A); //foreach (Vector2f id in stackList) // s.Add (id); //} //polygonSlice.pointsList = s; // Not necessary if (polygon.SliceIntersectPoly(polygonSlice.pointsList) == false) { return(result); } result = ComplexSlicer.Slice(polygon, new List <Vector2f> (polygonSlice.pointsList)); //if (result.polygons.Count < 1) //debug用 消しても大丈夫そう // Debug.LogError ("Slicer2D: Returns Empty Polygon Slice"); Slicer2D.complexSliceType = tempSliceType; return(result); }
// Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice static public Slice2D Slice(Polygon polygon, Polygon polygonSlice) { Slice2D result = Slice2D.Create(); 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 Vector2f startPoint = null; foreach (Vector2f id in polygonSlice.pointsList) { if (polygon.PointInPoly(id) == false) { startPoint = id; break; } } if (startPoint == null) { Debug.LogError("Slicer2D: Starting Point Error In PolygonSlice"); return(result); } polygonSlice.pointsList = VectorList2f.GetListStartingPoint(polygonSlice.pointsList, startPoint); /* * List<Vector2f> s = new List<Vector2f> (); * foreach (Pair2f pair in Pair2f.GetList(polygonSlice.pointsList, false)) { * List<Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair); * stackList = VectorList2f.GetListSortedToPoint (stackList, pair.A); * Vector2f old = pair.A; * s.Add (old); * * foreach (Vector2f id in stackList) { * s.Add (new Vector2f((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 <Vector2f> (polygonSlice.pointsList)); if (result.polygons.Count < 1) { Debug.LogError("Slicer2D: Returns Empty Polygon Slice"); } Slicer2D.complexSliceType = tempSliceType; return(result); }
static public Slice2D Slice(Polygon polygon, List <Vector2f> slice) { Slice2D result = Slice2D.Create(); if (slice.Count < 2) { return(result); } // Normalize into clockwise polygon.Normalize(); if (Slicer2D.complexSliceType != Slicer2D.SliceType.Regular) { result = SlicePolygonInside(polygon, slice); if (result.polygons.Count > 0) { return(result); } } // Optimization (holes?) // if (polygon.SliceIntersectPoly (slice) == false) // return(result); List <List <Vector2f> > slices = new List <List <Vector2f> >(); bool entered = polygon.PointInPoly(slice.First()); List <Vector2f> currentSlice = new List <Vector2f> (); foreach (Pair2f pair in Pair2f.GetList(slice, false)) { List <Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair); stackList = VectorList2f.GetListSortedToPoint(stackList, pair.A); foreach (Vector2f id in stackList) { if (entered == true) { currentSlice.Add(id); slices.Add(currentSlice); } else { currentSlice = new List <Vector2f> (); currentSlice.Add(id); } entered = !entered; } if (entered == true) { currentSlice.Add(pair.B); } } // Adjusting split lines before performing convex split result.AddPolygon(polygon); foreach (List <Vector2f> id in slices) { if (id.Count > 1) { foreach (Vector2f p in id) { result.AddCollision(p); } // Sclice line points generated from intersections list Vector2f vec0 = id.First(); vec0.Push(Vector2f.Atan2(vec0, id[1]), precision); Vector2f vec1 = id.Last(); vec1.Push(Vector2f.Atan2(vec1, id[id.Count - 2]), precision); // For each in polygons list attempt convex split List <Polygon> temp = new List <Polygon>(result.polygons); // necessary? foreach (Polygon poly in temp) { Slice2D resultList = SingleSlice(poly, id); if (resultList.polygons.Count > 0) { foreach (Polygon i in resultList.polygons) { result.AddPolygon(i); } // If it's possible to perform convex split, remove parent polygon from result list result.RemovePolygon(poly); } } } } result.RemovePolygon(polygon); return(result); }
static private Slice2D SliceWithOneHole(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice) { Slice2D result = Slice2D.Create(); Polygon holeA = polygon.PointInHole(slice.First()); Polygon holeB = polygon.PointInHole(slice.Last()); Polygon 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) { Debug.LogError("Slicer2D: This happened when collider had a lot of paths but they were not holes"); return(result); } List <Vector2f> slice2 = new List <Vector2f> (slice); Polygon polyA = new Polygon(polygon.pointsList); Polygon polyB = new Polygon(slice); Polygon polyC = new Polygon(slice2); // Get First Point - NOT FINISHED WITH INTERSECTION int Add; List <Vector2f> list; List <Pair2f> iterateList = Pair2f.GetList(holeA.pointsList); Add = 0; list = new List <Vector2f> (); foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 1) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2f.Distance(list.First(), slice.First()) < Vector2f.Distance(list.First(), slice.Last())) { slice.Reverse(); } polyB.AddPoints(list); } Add = 0; list = new List <Vector2f> (); foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2f.Distance(list.First(), slice2.First()) < Vector2f.Distance(list.First(), slice2.Last())) { slice2.Reverse(); } polyC.AddPoints(list); } if (polyB.GetArea() > polyC.GetArea()) { Polygon swap = polyB; polyB = polyC; polyC = swap; } // Add holes to new created polygon foreach (Polygon 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 (Polygon poly in polygon.holesList) // Check for errors? { if (poly != holeA && polyC.PolyInPoly(poly) == false) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } else if (holePoly != null) { Polygon polyA = new Polygon(); Polygon polyB = new Polygon(holePoly.pointsList); polyB.pointsList.Reverse(); List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(polygon.pointsList, slice); List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(polyB.pointsList, slice); if (pointsA.Count < 1) { Debug.LogError("Slicer2D: " + pointsA.Count + " " + polygon.pointsList.Count); } polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { // pointsA empty if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon poly in polygon.holesList) // Check for errors? { if (poly != holePoly) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } } return(result); }
// Slice From Point static public Slice2D SliceFromPoint(Polygon polygon, Vector2f point, float rotation) { Slice2D result = Slice2D.Create(); // Normalize into clockwise polygon.Normalize(); Vector2f sliceA = new Vector2f(point); Vector2f sliceB = new Vector2f(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 <Vector2f> intersectionsA = polygon.GetListSliceIntersectPoly(new Pair2f(point, sliceA)); List <Vector2f> intersectionsB = polygon.GetListSliceIntersectPoly(new Pair2f(point, sliceB)); // Sorting intersections from one point if (intersectionsA.Count > 0 && intersectionsB.Count > 0) { sliceA = VectorList2f.GetListSortedToPoint(intersectionsA, point) [0]; sliceB = VectorList2f.GetListSortedToPoint(intersectionsB, point) [0]; } else { return(result); } List <Pair2f> collisionList = new List <Pair2f>(); collisionList.Add(new Pair2f(sliceA, sliceB)); result.AddPolygon(polygon); foreach (Pair2f id in collisionList) { // Sclice line points generated from intersections list Vector2f vec0 = new Vector2f(id.A); Vector2f vec1 = new Vector2f(id.B); float rot = Vector2f.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 <Polygon> temp = new List <Polygon>(result.polygons); // necessary? foreach (Polygon poly in temp) { // NO, that's the problem Slice2D resultList = LinearSlicer.Slice(poly, new Pair2f(vec0, vec1)); if (resultList.polygons.Count > 0) { foreach (Polygon i in resultList.polygons) { result.AddPolygon(i); } // If it's possible to perform splice, remove parent polygon from result list result.RemovePolygon(poly); } } } result.RemovePolygon(polygon); return(result); }