public void Add(Segment s) { // j iterates through the openPolygon chains. for (int j = 0; j < openPolygonsCount; j++) { PointChain chain = openPolygons [j]; if (!chain.LinkSegment(s)) { continue; } if (chain.closed) { if (chain.pointList.Count == 2) { // We tried linking the same segment (but flipped end and start) to // a chain. (i.e. chain was <p0, p1>, we tried linking Segment(p1, p0) // so the chain was closed illegally. chain.closed = false; return; } closedPolygons.Add(chain); openPolygons.RemoveAt(j); openPolygonsCount--; return; } // int k = openPolygons.Count; for (int i = j + 1; i < openPolygonsCount; i++) { // Try to connect this open link to the rest of the chains. // We won't be able to connect this to any of the chains preceding this one // because we know that linkSegment failed on those. if (chain.LinkPointChain(openPolygons [i])) { openPolygons.RemoveAt(i); openPolygonsCount--; return; } } return; } PointChain newChain; if (pointChainPoolUsed >= pointChainPool.Count) { newChain = new PointChain(); pointChainPool.Add(newChain); } else { newChain = pointChainPool [pointChainPoolUsed]; } pointChainPoolUsed++; newChain.Init(s); openPolygons.Add(newChain); openPolygonsCount++; }
/// <summary> /// Since polygons from countries and cells are not perfectly aligned in all cases, this method will take the largest contour and assume this is the resulting polygon /// (even if it's not closed...) /// </summary> public Polygon ToPolygonFromLargestLineStrip() { // Check for empty result if ((closedPolygons.Count == 0 || (closedPolygons.Count == 1 && closedPolygons [0].pointList.Count == 0)) && (openPolygonsCount == 0 || (openPolygonsCount == 1 && openPolygons [0].pointList.Count == 0))) { return(null); } // Get the largest contour (open or closed) int maxPoints = -1; PointChain largestPointChain = null; foreach (PointChain pointChain in closedPolygons) { if (pointChain.pointList.Count > maxPoints) { maxPoints = pointChain.pointList.Count; largestPointChain = pointChain; } } foreach (PointChain pointChain in openPolygons) { if (pointChain.pointList.Count > maxPoints) { maxPoints = pointChain.pointList.Count; largestPointChain = pointChain; } } // ... and create a new polygon of that if (maxPoints < 0) { return(null); } // Polygon polygon = new Polygon (); // Contour c = new Contour (); // c.AddRange (largestPointChain.pointList); // polygon.AddContour (c); // FixOrientation (polygon); tempContour.Clear(); tempContour.AddRange(largestPointChain.pointList); tempPolygon.Clear(); tempPolygon.AddContour(tempContour); FixOrientation(tempPolygon); return(tempPolygon); }
public bool LinkPointChain(PointChain chain) { Point firstPoint = pointList [0]; Point lastPoint = pointList [pointList.Count - 1]; Point chainFront = chain.pointList [0]; Point chainBack = chain.pointList [chain.pointList.Count - 1]; if (Point.EqualsBoth(chainFront, lastPoint)) { temp.Clear(); int chainPointListCount = chain.pointList.Count; for (int k = 1; k < chainPointListCount; k++) { temp.Add(chain.pointList [k]); } pointList.AddRange(temp); return(true); } if (Point.EqualsBoth(chainBack, firstPoint)) { temp.Clear(); temp.AddRange(chain.pointList); int pointListCount = pointList.Count; for (int k = 1; k < pointListCount; k++) { temp.Add(pointList [k]); } pointList.Clear(); pointList.AddRange(temp); return(true); } if (Point.EqualsBoth(chainFront, firstPoint)) { // List<Point> temp = new List<Point> (chain.pointList); temp.Clear(); temp.AddRange(chain.pointList); temp.Reverse(); int pointListCount = pointList.Count; // temp.Capacity += pointListCount; for (int k = 1; k < pointListCount; k++) { temp.Add(pointList [k]); } pointList.Clear(); pointList.AddRange(temp); // pointList = temp; return(true); } if (Point.EqualsBoth(chainBack, lastPoint)) { pointList.RemoveAt(pointList.Count - 1); temp.Clear(); temp.AddRange(chain.pointList); // List<Point> temp = new List<Point> (chain.pointList); temp.Reverse(); pointList.AddRange(temp); return(true); } return(false); }
// Links another pointChain onto this point chain. public bool LinkPointChain(PointChain chain) { Point firstPoint = pointList[0]; Point lastPoint = pointList[pointList.Count - 1]; Point chainFront = chain.pointList[0]; Point chainBack = chain.pointList[chain.pointList.Count - 1]; if (Point.EqualsBoth(chainFront, lastPoint)) { List <Point> temp = new List <Point>(chain.pointList.Count); for (int k = 1; k < chain.pointList.Count; k++) { temp.Add(chain.pointList[k]); } // temp.RemoveAt(0); pointList.AddRange(temp); // if (pointList.Count>maxLen) { // maxLen = pointList.Count; // Debug.Log (maxLen); // } // chain.pointList.Clear(); return(true); } if (Point.EqualsBoth(chainBack, firstPoint)) { // pointList.RemoveAt (0); // Remove the first element, and join this list to chain.pointList. List <Point> temp = new List <Point>(chain.pointList); temp.Capacity += pointList.Count; for (int k = 1; k < pointList.Count; k++) { temp.Add(pointList[k]); } // temp.AddRange(pointList); pointList = temp; // if (pointList.Count>maxLen) { // maxLen = pointList.Count; // Debug.Log (maxLen); // } // chain.pointList.Clear(); return(true); } if (Point.EqualsBoth(chainFront, firstPoint)) { // pointList.RemoveAt (0); // Remove the first element, and join to reversed chain.pointList List <Point> temp = new List <Point>(chain.pointList); temp.Reverse(); temp.Capacity += pointList.Count; for (int k = 1; k < pointList.Count; k++) { temp.Add(pointList[k]); } // temp.AddRange(pointList); pointList = temp; // if (pointList.Count>maxLen) { // maxLen = pointList.Count; // Debug.Log (maxLen); // } // chain.pointList.Clear(); return(true); } if (Point.EqualsBoth(chainBack, lastPoint)) { pointList.RemoveAt(pointList.Count - 1); List <Point> temp = new List <Point>(chain.pointList); temp.Reverse(); pointList.AddRange(temp); // if (pointList.Count>maxLen) { // maxLen = pointList.Count; // Debug.Log (maxLen); // } // chain.pointList.Clear(); return(true); } return(false); }