public static Polygon Union(Canvas canvas, Polygon window, Polygon subject) { Point startPoint; POLYGON startPolygon; FindAndOrderPoints(window, subject, out startPoint, out startPolygon); if (startPoint.X == int.MaxValue) { return(window.minX < subject.minX ? window : subject); } Point currentPoint = startPoint; POLYGON currentPolygon = startPolygon; Polygon polygon = new Polygon(canvas); do { polygon.AddVertex(currentPoint.X, currentPoint.Y); if (currentPolygon == POLYGON.WINDOW) { currentPolygon = currentPoint.CrossPoint ? POLYGON.SUBJECT : POLYGON.WINDOW; currentPoint = currentPoint.CrossPoint ? currentPoint.SubjectNext : currentPoint.WindowNext; } else { currentPolygon = currentPoint.CrossPoint ? POLYGON.WINDOW : POLYGON.SUBJECT; currentPoint = currentPoint.CrossPoint ? currentPoint.WindowNext : currentPoint.SubjectNext; } } while (currentPoint != startPoint); //end do while there are more points polygon.ClosePolygon(); return(polygon); }
private static void FindAndOrderPoints(Polygon window, Polygon subject, out Point startPoint, out POLYGON startPolygon) { startPolygon = POLYGON.WINDOW; startPoint = new Point(int.MaxValue, int.MaxValue, false); WindowPointList windowPoints = new WindowPointList(); SubjectPointList subjectPoints = new SubjectPointList(); Dictionary <Edge, List <Point> > edgeCrossPoints = FindPoints(window, subject); foreach (Edge windowEdge in window.Edges) { Point vertexPoint = new Point(windowEdge.V1.X, windowEdge.V1.Y, false); if (vertexPoint.X < startPoint.X) { startPoint = vertexPoint; startPolygon = POLYGON.WINDOW; } windowPoints.Add(vertexPoint); edgeCrossPoints[windowEdge].Sort((p1, p2) => { return(Math.Abs(p1.X - windowEdge.V1.X) - Math.Abs(p2.X - windowEdge.V1.X)); }); foreach (Point point in edgeCrossPoints[windowEdge]) { windowPoints.Add(point); } } foreach (Edge subjectEdge in subject.Edges) { Point vertexPoint = new Point(subjectEdge.V1.X, subjectEdge.V1.Y, false); if (vertexPoint.X < startPoint.X) { startPoint = vertexPoint; startPolygon = POLYGON.SUBJECT; } subjectPoints.Add(vertexPoint); edgeCrossPoints[subjectEdge].Sort((p1, p2) => { return(Math.Abs(p1.X - subjectEdge.V1.X) - Math.Abs(p2.X - subjectEdge.V1.X)); }); foreach (Point point in edgeCrossPoints[subjectEdge]) { subjectPoints.Add(point); } } }