Example #1
0
 public ClusterTestNode(ClusterPart Parent, bool Top)
 {
     this.Parent = Parent;
     this.IsTop  = Top;
     Y           = Top ? Parent.Rectangle.Top : Parent.Rectangle.Bottom;
 }
Example #2
0
        List <Cluster> ClusterRanges(IEnumerable <List <Rectangle> > ranges)
        {
            ClustersFinished = false;
            List <ClusterTestNode> tests = new List <ClusterTestNode>();

            ranges.ForEach(rrl => {
                rrl.ForEach(rr => {
                    ClusterPart toAdd = new ClusterPart(rr);
                    tests.Add(new ClusterTestNode(toAdd, true));
                    tests.Add(new ClusterTestNode(toAdd, false));
                }
                            );
            });
            tests.Sort((a, b) => {           //sort by y, if ys are same, bottoms are first
                int ydif = a.Y - b.Y;
                if (0 != ydif)
                {
                    return(ydif);
                }
                return(a.IsTop.CompareTo(b.IsTop));
            });

            List <Cluster> Clusters    = new List <Cluster>();
            Stack <int>    searchStack = new Stack <int>();
            int            max         = tests.Count;

            for (int i = max - 1; i >= 0; --i)
            {
                ClusterTestNode CurrentNode = tests[i];
                if (!CurrentNode.IsTop)
                {
                    continue;                                   //if it is a bottom or is already in a cluster, nothing is done
                }
                if (CurrentNode.Parent.Cluster == null)
                {
                    //Console.WriteLine("\nTesting "+CurrentNode.Parent.Rectangle);
                    Cluster CurrentCluster = new Cluster();
                    Clusters.Add(CurrentCluster);
                    searchStack.Push(i);
                    while (searchStack.Count > 0)
                    {                    //search for contacts
                        if (IsCancelRequested)
                        {
                            goto endloop;
                        }
                        int             searchIndex = searchStack.Pop();
                        ClusterTestNode SearchNode  = tests[searchIndex];
                        //Console.WriteLine("\tSearch Seed: "+SearchNode.Parent.Rectangle);
                        if (SearchNode.Parent.Cluster != null)
                        {
                            continue;
                        }
                        SearchNode.Parent.Cluster = CurrentCluster;
                        CurrentCluster.Ranges.Add(SearchNode.Parent.Rectangle);
                        //search up for bottoms
                        for (int s = searchIndex - 1; s >= 0; --s)
                        {
                            if (!tests[s].IsTop)
                            {
                                if (tests[s].Y == SearchNode.Parent.Rectangle.Top && OverlapsX(tests[s].Parent.Rectangle, SearchNode.Parent.Rectangle))
                                {
                                    searchStack.Push(s);
                                }
                                else if (tests[s].Y < SearchNode.Parent.Rectangle.Top)
                                {
                                    //Console.WriteLine("\t\tStopped at "+s);
                                    break;
                                }
                            }
                        }
                        //search down for tops
                        for (int s = searchIndex + 1; s < max; ++s)
                        {
                            if (tests[s].IsTop)
                            {
                                if (tests[s].Y == SearchNode.Parent.Rectangle.Bottom && OverlapsX(tests[s].Parent.Rectangle, SearchNode.Parent.Rectangle))
                                {
                                    searchStack.Push(s);
                                }
                                else if (tests[s].Y > SearchNode.Parent.Rectangle.Bottom)
                                {
                                    //Console.WriteLine("\t\tStopped at "+s);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            ClustersFinished = true;
endloop:
            return(Clusters);
        }