Esempio n. 1
0
        //worst case O(n)
        public Hull combine(Hull left, Hull right)
        {
            //extract lists from hulls
            List <PointF> l = left.getList();
            List <PointF> r = right.getList();

            //set booleans, they come in handy
            bool bothDone  = false;
            bool rightDone = false;
            bool leftDone  = false;

            //those 4 ints abreviate topleftindex,toprightindex,bottomleftindex,and bottomrightindex
            int tli = left.getRightIndex();
            int tri = 0;
            int bli = left.getRightIndex();
            int bri = 0;


            //find top edge, repeat this loop until no change in left or right index
            while (!bothDone)
            {
                bothDone  = true;
                rightDone = false;
                leftDone  = false;

                //move right index "up" until no advantage in slope change
                while (!rightDone)
                {
                    int newIndex;

                    if (tri == 0)
                    {
                        newIndex = r.Count() - 1;
                    }
                    else
                    {
                        newIndex = tri - 1;
                    }

                    if (slope(l[tli], r[tri]) > slope(l[tli], r[newIndex]))
                    {
                        tri      = newIndex;
                        bothDone = false;
                    }
                    else
                    {
                        rightDone = true;
                    }
                }

                //move left index "up" until no advantage in slope change
                while (!leftDone)
                {
                    int newIndex;

                    if (tli == (l.Count() - 1))
                    {
                        newIndex = 0;
                    }
                    else
                    {
                        newIndex = tli + 1;
                    }

                    if (slope(l[tli], r[tri]) < slope(l[newIndex], r[tri]))
                    {
                        tli      = newIndex;
                        bothDone = false;
                    }
                    else
                    {
                        leftDone = true;
                    }
                }
            }



            bothDone = false;
            //find bottom edge, repeat this loop until no change in left or right index
            while (!bothDone)
            {
                bothDone  = true;
                rightDone = false;
                leftDone  = false;

                //move right index "down" until no advantage in slope change
                while (!rightDone)
                {
                    if (bri == (r.Count() - 1))
                    {
                        rightDone = true;
                    }
                    else
                    {
                        if (slope(l[bli], r[bri]) < slope(l[bli], r[bri + 1]))
                        {
                            bri++;
                            bothDone = false;
                        }
                        else
                        {
                            rightDone = true;
                        }
                    }
                }

                //move left index "down" until no advantage in slope change
                while (!leftDone)
                {
                    if (bli == 0)
                    {
                        leftDone = true;
                    }
                    else
                    {
                        if (slope(l[bli], r[bri]) > slope(l[bli - 1], r[bri]))
                        {
                            bli--;
                            bothDone = false;
                        }
                        else
                        {
                            leftDone = true;
                        }
                    }
                }
            }

            //pass in the indeces we found
            return(getNewHull(bli, bri, tri, tli, right.getRightIndex(), l, r));
        }
Esempio n. 2
0
        public Hull merge(Hull left, Hull right)
        {
            int rightMost = left.getRightMostIndex();
            int leftMost  = right.getLeftMostIndex();

            int currentLeftIndex  = rightMost;
            int currentRightIndex = leftMost;

            int upperLeft  = -1;
            int upperRight = -1;
            int lowerLeft  = -1;
            int lowerRight = -1;

            bool leftIndexChanged  = false;
            bool rightIndexChanged = false;
            //iterate through at least once
            bool firstRight = true;
            bool firstLeft  = true;

            //get upper common tangent
            while (leftIndexChanged || rightIndexChanged || firstLeft || firstRight)
            {
                if (firstRight || leftIndexChanged)
                {
                    firstRight = false;
                    upperRight = getRightUpper(left, right, currentLeftIndex, currentRightIndex);
                    if (upperRight == currentRightIndex)
                    {
                        leftIndexChanged  = false;
                        rightIndexChanged = false;
                    }
                    else
                    {
                        rightIndexChanged = true;
                        currentRightIndex = upperRight;
                    }
                }
                if (firstLeft || rightIndexChanged)
                {
                    firstLeft = false;
                    upperLeft = getLeftUpper(left, right, currentLeftIndex, currentRightIndex);
                    if (upperLeft == currentLeftIndex)
                    {
                        leftIndexChanged  = false;
                        rightIndexChanged = false;
                    }
                    else
                    {
                        leftIndexChanged = true;
                        currentLeftIndex = upperLeft;
                    }
                }
            }

            //get lower common tangentt
            currentLeftIndex  = rightMost;
            currentRightIndex = leftMost;

            leftIndexChanged  = false;
            rightIndexChanged = false;
            //iterate through at least once
            firstRight = true;
            firstLeft  = true;
            while (leftIndexChanged || rightIndexChanged || firstLeft || firstRight)
            {
                if (firstLeft || rightIndexChanged)
                {
                    firstLeft = false;
                    lowerLeft = getLeftLower(left, right, currentLeftIndex, currentRightIndex);
                    if (lowerLeft == currentLeftIndex)
                    {
                        leftIndexChanged  = false;
                        rightIndexChanged = false;
                    }
                    else
                    {
                        leftIndexChanged = true;
                        currentLeftIndex = lowerLeft;
                    }
                }

                if (firstRight || leftIndexChanged)
                {
                    firstRight = false;
                    lowerRight = getRightLower(left, right, currentLeftIndex, currentRightIndex);
                    if (lowerRight == currentRightIndex)
                    {
                        leftIndexChanged  = false;
                        rightIndexChanged = false;
                    }
                    else
                    {
                        rightIndexChanged = true;
                        currentRightIndex = lowerRight;
                    }
                }
            }

            //join points
            List <PointF> resultPoints = new List <PointF>();

            //add up to (and including) upperLeft
            for (int i = 0; i <= upperLeft; i++)
            {
                resultPoints.Add(left.getPoints()[i]);
            }
            //add up to lowerRight
            for (int i = upperRight; i != lowerRight; i = right.getNextIndex(i))
            {
                resultPoints.Add(right.getPoints()[i]);
            }
            //add lowerRight
            resultPoints.Add(right.getPoints()[lowerRight]);
            //add from lowerLeft to beginning
            for (int i = lowerLeft; i != 0; i = left.getNextIndex(i))
            {
                resultPoints.Add(left.getPoints()[i]);
            }

            return(new Hull(resultPoints));
        }