コード例 #1
0
        private static void goRight(ref Treap <Point> current, ref Point currentPoint, ref int toCut)
        {
            toCut = toCut + Treap <Point> .GetSize(current.Right.Left) + 1;

            current      = current.Right;
            currentPoint = current.Key;
        }
コード例 #2
0
        private static void goLeft(ref Treap <Point> current, ref Point currentPoint, ref int toCut)
        {
            toCut = toCut - Treap <Point> .GetSize(current.Left.Right) - 1;

            current      = current.Left;
            currentPoint = current.Key;
        }
コード例 #3
0
 public void SetConvexHull(bool isLeftHalf, Treap <Point> value)
 {
     if (isLeftHalf)
     {
         leftConvexHull = value;
     }
     else
     {
         rightConvexHull = value;
     }
 }
コード例 #4
0
ファイル: Treap.cs プロジェクト: gotthit/DynamicConvexHull
        public Treap(T newKey, Treap <T> newLeft = null, Treap <T> newRight = null)
        {
            Key   = newKey;
            Left  = newLeft;
            Right = newRight;
            Size  = 1;

            MaxElement = newKey;
            MinElement = newKey;

            update();
        }
コード例 #5
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);
            }
        }
コード例 #6
0
            private RedBlackNode(Point newPoint = null, RedBlackNode newLeft = null, RedBlackNode newRight = null, RedBlackNode newParent = null)
            {
                Left   = newLeft;
                Right  = newRight;
                Parent = newParent;

                MaxPoint = newPoint;

                NodeColor = IsRoot ? Color.Black : Color.Red;

                leftConvexHull       = null;
                leftLowerSubHullSize = 0;

                rightConvexHull       = null;
                rightLowerSubHullSize = 0;
            }
コード例 #7
0
ファイル: Utils.cs プロジェクト: gotthit/DynamicConvexHull
        public static bool IsValid(Treap <Point> hull)
        {
            if (hull == null)
            {
                return(true);
            }

            var list = hull.GetArray();

            for (int i = 0; i < list.Count - 2; ++i)
            {
                if (DeterminePosition(list[i], list[i + 2], list[i + 1]) == PointPosition.Right)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #8
0
ファイル: Treap.cs プロジェクト: gotthit/DynamicConvexHull
 public static void SplitBySize(Treap <T> current, int toCut, out Treap <T> leftHalf, out Treap <T> rightHalf)
 {
     if (current == null)
     {
         leftHalf  = null;
         rightHalf = null;
     }
     else if (GetSize(current.Left) >= toCut)
     {
         SplitBySize(current.Left, toCut, out leftHalf, out rightHalf);
         current.Left = rightHalf;
         current.update();
         rightHalf = current;
     }
     else
     {
         SplitBySize(current.Right, toCut - GetSize(current.Left) - 1, out leftHalf, out rightHalf);
         current.Right = leftHalf;
         current.update();
         leftHalf = current;
     }
 }
コード例 #9
0
ファイル: Treap.cs プロジェクト: gotthit/DynamicConvexHull
 public static Treap <T> Merge(Treap <T> leftTreap, Treap <T> rightTreap)
 {
     if (leftTreap == null)
     {
         return(rightTreap);
     }
     if (rightTreap == null)
     {
         return(leftTreap);
     }
     if (randomGenerator.Next(0, leftTreap.Size + rightTreap.Size) < leftTreap.Size)
     {
         leftTreap.Right = Merge(leftTreap.Right, rightTreap);
         leftTreap.update();
         return(leftTreap);
     }
     else
     {
         rightTreap.Left = Merge(leftTreap, rightTreap.Left);
         rightTreap.update();
         return(rightTreap);
     }
 }
コード例 #10
0
ファイル: Treap.cs プロジェクト: gotthit/DynamicConvexHull
 public static int GetSize(Treap <T> treap)
 {
     return(treap == null ? 0 : treap.Size);
 }
コード例 #11
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);
            }
        }
コード例 #12
0
        private static bool makeDecisionAboutRotation(ref Treap <Point> lowerCurrent, ref Point lowerCurrentPoint, Point lowerPrevPoint, Point lowerNextPoint,
                                                      ref int toCutFromLowerHull,
                                                      ref Treap <Point> upperCurrent, ref Point upperCurrentPoint, Point upperPrevPoint, Point upperNextPoint,
                                                      ref int toLeaveInUpperHull,
                                                      double mediumY, bool isLeftHalf)
        {
            PointPosition lowerPrevPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, lowerPrevPoint, isLeftHalf);
            PointPosition lowerNextPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, lowerNextPoint, isLeftHalf);

            PointPosition upperPrevPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, upperPrevPoint, isLeftHalf);
            PointPosition upperNextPos = determinePosition(lowerCurrentPoint, upperCurrentPoint, upperNextPoint, isLeftHalf);

            if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right &&
                upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // A - found
            {
                return(true);                                                               // answer found
            }
            else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right &&
                     upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // B
            {
                goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull);

                //goRight(ref rightTop, ref rightTopPoint, ref rightMinPoint, ref rightMaxPoint,
                //       ref toLeaveInRightHull, ref minPointLeaveInRight, ref maxPointLeaveInRight);
            }
            else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left &&
                     upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Right) // C
            {
                goRight(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull);

                //goRight(ref rightTop, ref rightTopPoint, ref rightMinPoint, ref rightMaxPoint,
                //       ref toLeaveInRightHull, ref minPointLeaveInRight, ref maxPointLeaveInRight);
            }
            else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right &&
                     upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // D
            {
                //goLeft(ref leftTop, ref leftTopPoint, ref leftMinPoint, ref leftMaxPoint,
                //       ref toCutFromLeftHull, ref minPointCutFromLeft, ref maxPointCutFromLeft);

                goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull);
            }
            else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Right &&
                     upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // E
            {
                //goLeft(ref leftTop, ref leftTopPoint, ref leftMinPoint, ref leftMaxPoint,
                //       ref toCutFromLeftHull, ref minPointCutFromLeft, ref maxPointCutFromLeft);

                goLeft(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull);
            }
            else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right &&
                     upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // F
            {
                goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull);

                goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull);
            }
            else if (lowerPrevPos == PointPosition.Left && lowerNextPos == PointPosition.Right &&
                     upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // G
            {
                goLeft(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull);
            }
            else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left &&
                     upperPrevPos == PointPosition.Right && upperNextPos == PointPosition.Left) // H
            {
                goRight(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull);
            }
            else if (lowerPrevPos == PointPosition.Right && lowerNextPos == PointPosition.Left &&
                     upperPrevPos == PointPosition.Left && upperNextPos == PointPosition.Right) // I - the hardest
            {
                if (isIntersectLoverY(lowerCurrentPoint, lowerNextPoint, upperCurrentPoint, upperPrevPoint, mediumY, isLeftHalf))
                {
                    goRight(ref lowerCurrent, ref lowerCurrentPoint, ref toCutFromLowerHull);
                }
                else
                {
                    goLeft(ref upperCurrent, ref upperCurrentPoint, ref toLeaveInUpperHull);
                }
            }
            else
            {
                throw new Exception("something wrong");
            }

            return(false); // answer not found
        }
コード例 #13
0
 public RedBlackNode(Point newPoint, RedBlackNode newParent = null) : this(newPoint, null, null, newParent)
 {
     leftConvexHull  = new Treap <Point>(newPoint);
     rightConvexHull = new Treap <Point>(newPoint);
 }