Ejemplo n.º 1
0
        private static RedBlackNode insert(RedBlackNode current, Point pointToInsert)
        {
            if (current.IsLeaf && pointToInsert.CompareTo(current.MaxPoint) != 0)
            {
                if (pointToInsert.CompareTo(current.MaxPoint) < 0)
                {
                    current.Left  = new RedBlackNode(pointToInsert, current);
                    current.Right = new RedBlackNode(current.MaxPoint, current);
                }
                else
                {
                    current.Left  = new RedBlackNode(current.MaxPoint, current);
                    current.Right = new RedBlackNode(pointToInsert, current);
                }
                current.SetConvexHull(true, null);
                current.SetConvexHull(false, null);

                recount(current);
                return(initialInsertRepair(current));
            }
            else if (!current.IsLeaf)
            {
                pushSubHullDown(current);

                if (pointToInsert.CompareTo(current.Left.MaxPoint) <= 0)
                {
                    return(insert(current.Left, pointToInsert));
                }
                else
                {
                    return(insert(current.Right, pointToInsert));
                }
            }
            return(recountToUp(current));
        }
Ejemplo n.º 2
0
        private static void pushSubHullDown(RedBlackNode current, bool isLeftHalf)
        {
            if (current != null && !current.IsLeaf && current.GetConvexHull(isLeftHalf) != null)
            {
                Treap <Point> leftHalf;
                Treap <Point> rightHalf;
                Treap <Point> .SplitBySize(current.GetConvexHull(isLeftHalf), current.GeLowerSubHullSize(isLeftHalf), out leftHalf, out rightHalf);

                current.Left.SetConvexHull(isLeftHalf, Treap <Point> .Merge(leftHalf, current.Left.GetConvexHull(isLeftHalf)));
                current.Right.SetConvexHull(isLeftHalf, Treap <Point> .Merge(current.Right.GetConvexHull(isLeftHalf), rightHalf));

                current.SetConvexHull(isLeftHalf, null);
            }
        }
Ejemplo n.º 3
0
        private static void recount(RedBlackNode current, bool isLeftHalf)
        {
            if (current != null && current.Left != null && current.Right != null && current.GetConvexHull(isLeftHalf) == null)
            {
                current.MaxPoint = Utils.Max(current.Left.MaxPoint, current.Right.MaxPoint);

                Treap <Point> lowerCurrent      = current.Left.GetConvexHull(isLeftHalf);
                Treap <Point> upperCurrent      = current.Right.GetConvexHull(isLeftHalf);
                Point         loweCurrentPoint  = lowerCurrent.Key;
                Point         upperCurrentPoint = upperCurrent.Key;

                double mediumY = (lowerCurrent.MaxElement.Y + upperCurrent.MinElement.Y) / 2;

                int toCutFromLowerHull = Treap <Point> .GetSize(lowerCurrent?.Left) + 1;

                int toLeaveInUpperHull = Treap <Point> .GetSize(upperCurrent?.Left) + 1;

                bool bridgeFound = false;
                while (!bridgeFound)
                {
                    Point lowerPrevPoint = lowerCurrent?.Left != null ? lowerCurrent.Left.MaxElement : null;
                    Point lowerNextPoint = lowerCurrent?.Right != null ? lowerCurrent.Right.MinElement : null;

                    Point upperPrevPoint = upperCurrent?.Left != null ? upperCurrent.Left.MaxElement : null;
                    Point upperNextPoint = upperCurrent?.Right != null ? upperCurrent.Right.MinElement : null;

                    bridgeFound = makeDecisionAboutRotation(ref lowerCurrent, ref loweCurrentPoint, lowerPrevPoint, lowerNextPoint, ref toCutFromLowerHull,
                                                            ref upperCurrent, ref upperCurrentPoint, upperPrevPoint, upperNextPoint, ref toLeaveInUpperHull,
                                                            mediumY, isLeftHalf);
                }
                // we want to have top point in right treap after split
                --toLeaveInUpperHull;

                Treap <Point> leftPartOfLowerHull;
                Treap <Point> rightPartOfLowerHull;
                Treap <Point> leftPartOfUpperHull;
                Treap <Point> rightPartOfUpperHull;

                if (loweCurrentPoint.Y == upperCurrentPoint.Y)
                {
                    if ((loweCurrentPoint.X < upperCurrentPoint.X && isLeftHalf) ||
                        (loweCurrentPoint.X > upperCurrentPoint.X && !isLeftHalf))
                    {
                        ++toLeaveInUpperHull;
                    }
                    else if ((loweCurrentPoint.X > upperCurrentPoint.X && isLeftHalf) ||
                             (loweCurrentPoint.X < upperCurrentPoint.X && !isLeftHalf))
                    {
                        --toCutFromLowerHull;
                    }
                    else
                    {
                        toLeaveInUpperHull++;
                    }
                }

                current.SetLowerSubHullSize(isLeftHalf, toCutFromLowerHull);
                Treap <Point> .SplitBySize(current.Left.GetConvexHull(isLeftHalf), toCutFromLowerHull, out leftPartOfLowerHull, out rightPartOfLowerHull);

                Treap <Point> .SplitBySize(current.Right.GetConvexHull(isLeftHalf), toLeaveInUpperHull, out leftPartOfUpperHull, out rightPartOfUpperHull);

                current.SetConvexHull(isLeftHalf, Treap <Point> .Merge(leftPartOfLowerHull, rightPartOfUpperHull));
                current.Left.SetConvexHull(isLeftHalf, rightPartOfLowerHull);
                current.Right.SetConvexHull(isLeftHalf, leftPartOfUpperHull);
            }
        }