PolylineGraph CalculateOverlapGraph()
        {
            var graph = new PolylineGraph();

            CreateEdgesUnderTwoNodes(rootOfTightHierarachy, rootOfTightHierarachy, graph);
            return(graph);
        }
        void CreateEdgesUnderTwoNodes(RectangleNode <Polyline> a, RectangleNode <Polyline> b,
                                      PolylineGraph overlapGraph)
        {
            //if (a.GetHashCode() < b.GetHashCode())
            //    return;

            Debug.Assert((a.UserData == null && a.Left != null && a.Right != null) ||
                         (a.UserData != null && a.Left == null && a.Right == null));
            Debug.Assert((b.UserData == null && b.Left != null && b.Right != null) ||
                         (b.UserData != null && b.Left == null && b.Right == null));
            if (a.Rectangle.Intersects(b.Rectangle))
            {
                if (a.UserData != null)
                {
                    if (b.UserData != null)
                    {
                        if (a.UserData != b.UserData)
                        {
                            if (Curve.GetAllIntersections(a.UserData, b.UserData, false).Count > 0 ||
                                OneCurveLiesInsideOfOther(a.UserData, b.UserData))
                            {
                                overlapGraph.AddEdge(a.UserData, b.UserData);
                                overlapGraph.AddEdge(b.UserData, a.UserData);
                            }
                        }
                    }
                    else
                    {
                        CreateEdgesUnderTwoNodes(a, b.Left, overlapGraph);
                        CreateEdgesUnderTwoNodes(a, b.Right, overlapGraph);
                    }
                }
                else if (b.UserData != null)
                {
                    CreateEdgesUnderTwoNodes(b, a.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(b, a.Right, overlapGraph);
                }
                else
                {
                    CreateEdgesUnderTwoNodes(a.Left, b.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Left, b.Right, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Right, b.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Right, b.Right, overlapGraph);
                }
            }
        }
        static List <Set <Polyline> > ConnectedComponents(PolylineGraph overlapGraph)
        {
            var list = new List <Set <Polyline> >();
            var processedPolylines = new Set <Polyline>();

            foreach (Polyline poly in overlapGraph.Nodes)
            {
                if (!processedPolylines.Contains(poly))
                {
                    Set <Polyline> component = GetComponent(poly, overlapGraph);
                    if (component.Count > 1)
                    {
                        list.Add(component);
                    }
                    processedPolylines += component;
                }
            }
            return(list);
        }
        static Set <Polyline> GetComponent(Polyline poly, PolylineGraph graph)
        {
            var ret = new Set <Polyline>();

            ret.Insert(poly);
            var queue = new Queue <Polyline>();

            queue.Enqueue(poly);
            while (queue.Count > 0)
            {
                foreach (Polyline p in graph.Descendents(queue.Dequeue()))
                {
                    if (!ret.Contains(p))
                    {
                        queue.Enqueue(p);
                        ret.Insert(p);
                    }
                }
            }
            return(ret);
        }
        List <Set <Polyline> > GetOverlappingSets()
        {
            PolylineGraph overlapGraph = CalculateOverlapGraph();

            return(ConnectedComponents(overlapGraph));
        }
        void CreateEdgesUnderTwoNodes(RectangleNode<Polyline> a, RectangleNode<Polyline> b,
                                      PolylineGraph overlapGraph) {
            //if (a.GetHashCode() < b.GetHashCode())
            //    return;

            Debug.Assert((a.UserData == null && a.Left != null && a.Right != null) ||
                         (a.UserData != null && a.Left == null && a.Right == null));
            Debug.Assert((b.UserData == null && b.Left != null && b.Right != null) ||
                         (b.UserData != null && b.Left == null && b.Right == null));
            if (a.Rectangle.Intersects(b.Rectangle)) {
                if (a.UserData != null) {
                    if (b.UserData != null) {
                        if (a.UserData != b.UserData)
                            if (Curve.GetAllIntersections(a.UserData, b.UserData, false).Count > 0 ||
                                OneCurveLiesInsideOfOther(a.UserData, b.UserData)) {
                                overlapGraph.AddEdge(a.UserData, b.UserData);
                                overlapGraph.AddEdge(b.UserData, a.UserData);
                            }
                    } else {
                        CreateEdgesUnderTwoNodes(a, b.Left, overlapGraph);
                        CreateEdgesUnderTwoNodes(a, b.Right, overlapGraph);
                    }
                } else if (b.UserData != null) {
                    CreateEdgesUnderTwoNodes(b, a.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(b, a.Right, overlapGraph);
                } else {
                    CreateEdgesUnderTwoNodes(a.Left, b.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Left, b.Right, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Right, b.Left, overlapGraph);
                    CreateEdgesUnderTwoNodes(a.Right, b.Right, overlapGraph);
                }
            }
        }
 PolylineGraph CalculateOverlapGraph() {
     var graph = new PolylineGraph();
     CreateEdgesUnderTwoNodes(rootOfTightHierarachy, rootOfTightHierarachy, graph);
     return graph;
 }
 static Set<Polyline> GetComponent(Polyline poly, PolylineGraph graph) {
     var ret = new Set<Polyline>();
     ret.Insert(poly);
     var queue = new Queue<Polyline>();
     queue.Enqueue(poly);
     while (queue.Count > 0) {
         foreach (Polyline p in graph.Descendents(queue.Dequeue())) {
             if (!ret.Contains(p)) {
                 queue.Enqueue(p);
                 ret.Insert(p);
             }
         }
     }
     return ret;
 }
 static List<Set<Polyline>> ConnectedComponents(PolylineGraph overlapGraph) {
     var list = new List<Set<Polyline>>();
     var processedPolylines = new Set<Polyline>();
     foreach (Polyline poly in overlapGraph.Nodes) {
         if (!processedPolylines.Contains(poly)) {
             Set<Polyline> component = GetComponent(poly, overlapGraph);
             if (component.Count > 1)
                 list.Add(component);
             processedPolylines += component;
         }
     }
     return list;
 }