Search code examples
eyeshot

Join simple polygons and draw the resulting contours in Eyeshot


What is the simplest way to join a collection of polygons and draw the resulting contour using Eyeshot? So far I was able only to get filled regions but I am interested in the merging of the contours.


Solution

  • I came up to this solution. To display the polygons simply iterate through the joined regions, iterate through the ContourList and create the LinearPaths.

    private List<PolyRegion2D> Joiner(IEnumerable<Polygon2D> polygons) {
            // The resulting polygons are unconnected
            List<PolyRegion2D> res = new List<PolyRegion2D>();
    
            // Put every polygon in a region to do the unions.
            LinkedList<PolyRegion2D> polygonRegions = new LinkedList<PolyRegion2D>();
            foreach (Polygon2D polygon in polygons) {
                polygonRegions.AddLast(new PolyRegion2D(new Polygon2D[]{polygon}));
            }
    
            while (polygonRegions.Count > 0) {
                PolyRegion2D first = polygonRegions.First.Value;
                polygonRegions.RemoveFirst();
                PolyRegion2D union;
                LinkedListNode<PolyRegion2D> connected = FindConnected(first, polygonRegions, out union);
                if (connected == null) {
                    // Unconnected polygon
                    res.Add(first);
                } else {
                    // Intersection found
                    polygonRegions.Remove(connected);
                    polygonRegions.AddFirst(union);
                }
            }
    
            return res;
        }
    
        private LinkedListNode<PolyRegion2D> FindConnected(PolyRegion2D poly, LinkedList<PolyRegion2D> polys, out PolyRegion2D union) {
            LinkedListNode<PolyRegion2D> node = polys.First;
            while(node != null){
                PolyRegion2D[] union_ = PolyRegion2D.Union(poly, node.Value);
                if (union_.Length == 1) {
                    union = union_[0];
                    return node;
                }
                node = node.Next;
            }
            union = null;
            return null;
        }