Beispiel #1
0
        public PointList Merge(PointList lhs, PointList rhs)
        {
            // the base case
            PointList p = null;

            if (lhs.Length == 1 && rhs.Length == 1)
            {
                p = new PointList(lhs, rhs);
                return(p);
            }
            // finding the top connecting nodes

            /*
             * O(n) because you will visit each node a maximum of one time within the while loop
             * (with the possible exception of the first node checked, which may get visited twice, at most)
             * where n is the number of nodes given before they are split in the Divide function
             */
            // Finding the rightmost of the lhs and the leftmost of the rhs are a combined O(n)
            PointF lpt_top = lhs.Rightmost(), rpt_top = rhs.Leftmost();
            PointF current;
            bool   changed = true;
            bool   growing = true;

            while (changed)
            {
                changed = false;

                growing = true;
                while (growing)
                {
                    current = lhs.prev();
                    if (Slope(current, rpt_top) > Slope(lpt_top, rpt_top))
                    {
                        lpt_top = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        lhs.next();
                    }
                }

                growing = true;
                while (growing)
                {
                    current = rhs.next();
                    if (Slope(lpt_top, current) < Slope(lpt_top, rpt_top))
                    {
                        rpt_top = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        rhs.prev();
                    }
                }
            }
            // finding the bottom connecting nodes

            /*
             * O(n) because you will visit each node a maximum of one time within the while loop
             * (with the possible exception of the first node checked, which may get visited twice, at most)
             * where n is the number of nodes given before they are split in the Divide function
             */
            // Finding the rightmost of the lhs and the leftmost of the rhs are a combined O(n)
            PointF lpt_bot = lhs.Rightmost(), rpt_bot = rhs.Leftmost();

            changed = true;
            growing = true;
            while (changed)
            {
                changed = false;

                growing = true;
                while (growing)
                {
                    current = lhs.next();
                    if (Slope(current, rpt_bot) < Slope(lpt_bot, rpt_bot))
                    {
                        lpt_bot = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        lhs.prev();
                    }
                }

                growing = true;
                while (growing)
                {
                    current = rhs.prev();
                    if (Slope(lpt_bot, current) > Slope(lpt_bot, rpt_bot))
                    {
                        rpt_bot = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        rhs.next();
                    }
                }
            }

            // forming the new list with only the convex hull nodes

            /*
             * O(n) because you might have to add all n nodes from the lhs and rhs
             * bounding lists to the new bounding list.
             * Usually this will only be a fraction of the actual number of nodes given to Divide()
             */
            List <PointF> list = new List <PointF>();

            growing = true;
            current = lpt_bot;
            lhs.SetIndex(lpt_bot);
            while (growing)
            {
                if (current == lpt_top)
                {
                    growing = false;
                }
                list.Add(current);
                current = lhs.next();
            }

            growing = true;
            current = rpt_top;
            rhs.SetIndex(rpt_top);
            while (growing)
            {
                if (current == rpt_bot)
                {
                    growing = false;
                }
                list.Add(current);
                current = rhs.next();
            }
            p = new PointList(list);
            return(p);
            // Total Time: O(5n) = O(n)
            // Total Space: O(n) for the new list allocated at the end
        }
Beispiel #2
0
        public PointList Merge(PointList lhs, PointList rhs)
        {
            // the base case
            if (lhs.Length == 1 || rhs.Length == 1)
            {
                return(new PointList(lhs, rhs));
            }
            // finding the top connecting nodes
            PointF lpt_top = lhs.Rightmost(), rpt_top = rhs.Leftmost();
            PointF current;
            bool   changed = true;
            bool   growing = true;

            while (changed)
            {
                changed = false;

                growing = true;
                while (growing)
                {
                    current = lhs.prev();
                    if (Slope(current, rpt_top) > Slope(lpt_top, rpt_top))
                    {
                        lpt_top = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        lhs.next();
                    }
                }

                growing = true;
                while (growing)
                {
                    current = rhs.next();
                    if (Slope(lpt_top, current) < Slope(lpt_top, rpt_top))
                    {
                        rpt_top = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        rhs.prev();
                    }
                }
            }

            // finding the bottom connecting nodes
            PointF lpt_bot = lhs.Rightmost(), rpt_bot = rhs.Leftmost();
            bool   changed = true;
            bool   growing = true;

            while (changed)
            {
                changed = false;

                growing = true;
                while (growing)
                {
                    current = lhs.next();
                    if (Slope(current, rpt_bot) < Slope(lpt_bot, rpt_bot))
                    {
                        lpt_bot = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        lhs.prev();
                    }
                }

                growing = true;
                while (growing)
                {
                    current = rhs.prev();
                    if (Slope(lpt_bot, current) > Slope(lpt_bot, rpt_bot))
                    {
                        rpt_bot = current;
                        changed = true;
                    }
                    else
                    {
                        growing = false;
                        rhs.next();
                    }
                }
            }

            // forming the new list with only the convex hull nodes
            List <PointF> list = new List <>();

            growing = true;
            current = lpt_bot;
            lhs.SetIndex(lpt_bot);
            while (growing)
            {
                if (current == lpt_top)
                {
                    growing = false;
                }
                list.Add(current);
                current = lhs.next();
            }

            growing = true;
            current = rpt_top;
            rhs.SetIndex(rpt_top);
            while (growing)
            {
                if (current == rpt_bot)
                {
                    growing = false;
                }
                list.Add(current);
                current = rhs.next();
            }

            return(new PointList(list));
        }
Beispiel #3
0
 public PointList(PointList pts1, PointList pts2)
 {
     points = new PointF[pts1.Length + pts2.Length];
     Array.Copy(pts1.points, 0, points, 0, pts1.Length);
     Array.Copy(pts2.points, 0, points, pts1.Length, pts1.Length + pts2.Length);
 }