/// <summary> /// Splites a multi part figure into single parts. /// See Polygon Split.png. /// </summary> /// <param name="sourceSegments"></param> /// <param name="obstacles"></param> protected virtual ICollection<Polygon> SplitPolygon(List<LineSegment> sourceSegments, ObstacleCollection obstacles) { var verticesCombinations = new HashSet<Polygon>(); foreach (var switchPoint in SwitchPoints) { foreach (var endPoint in switchPoint.Value.EndPoints) { var startPoint = switchPoint.Key; var polygon = new Polygon(); var remainingLines = new List<LineSegment>(sourceSegments); var currentItem = startPoint; var currentDirection = Direction.None; do { if (currentItem == startPoint && polygon.Count > 0) { if (!verticesCombinations.Contains(polygon)) verticesCombinations.Add(polygon); break; } if (polygon.Contains(currentItem)) break; polygon.Add(currentItem); LineSegment preferedLine; if (currentItem == startPoint) preferedLine = GetLine(currentItem, endPoint, true); else preferedLine = ChooseNextLine(currentItem, remainingLines, currentDirection); if (preferedLine == null) break; currentItem = preferedLine.End; currentDirection = preferedLine.Direction; polygon.Lines.Add(preferedLine); remainingLines.Remove(preferedLine); } while (true); } } RemoveUnnecessaryPolygons(verticesCombinations); var forlornLines = GetPolygonForlornLines(sourceSegments, verticesCombinations); obstacles.AddRange(forlornLines.Select(forlornLine => new LineObstacle(forlornLine.Start, forlornLine.End, Layer))); return verticesCombinations; }
//Polygon /// <summary> /// Creates a polygon out of a List of Lines. /// </summary> /// <param name="sourceSegments"></param> /// <returns></returns> public virtual Polygon CreatePolygon(IEnumerable<LineSegment> sourceSegments) { var polygon = new Polygon(); var lineSegments = new List<LineSegment>(sourceSegments); var currentItem = lineSegments.First().Start; var startPoint = currentItem; var currentDirection = Direction.None; while (lineSegments.Count > 0) { if (polygon.Count > 0 && startPoint == currentItem) break; var preferedLine = ChooseNextLine(currentItem, lineSegments, currentDirection); if (preferedLine == null) break; lineSegments.Remove(preferedLine); var previousItem = currentItem; currentItem = preferedLine.End; if (preferedLine.Direction == currentDirection) continue; currentDirection = preferedLine.Direction; polygon.Add(previousItem); polygon.Lines.Add(preferedLine); } return polygon; }