Ejemplo n.º 1
0
    public override void Insert(T data)
    {
        RBNode <T> node = new RBNode <T>(data);

        root = InsertNode(node, root) as RBNode <T>;

        FixViolation(node);
    }
Ejemplo n.º 2
0
 private int Size(RBNode x)
 {
     if (x == null)
     {
         return(0);
     }
     return(x.Size);
 }
Ejemplo n.º 3
0
 private bool IsRed(RBNode x)
 {
     if (x == null)
     {
         return(false);
     }
     return(x.Color == RED);
 }
Ejemplo n.º 4
0
 private int Count(RBNode root)
 {
     if (root == sentinelNode)
     {
         return(0);
     }
     return(1 + Count(root.Left) + Count(root.Right));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// deleting elem with its key
        /// </summary>
        /// <param name="elem"></param>
        public void RBDelete(TKey elem)
        {
            RBNode node = SearchKey(elem);

            RBDelete(node);
            count--;
            entries.Remove(node);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// searching minimum element in tree.
 /// </summary>
 /// <param name="elem"></param>
 /// <returns></returns>
 private RBNode RBMin(RBNode elem)
 {
     while (elem.left != RBLeaf.Instance())
     {
         elem = elem.right;
     }
     return(elem);
 }
Ejemplo n.º 7
0
 public RBNode()
 {
     value  = 0;
     color  = Color.RED;
     parent = null;
     left   = null;
     right  = null;
 }
Ejemplo n.º 8
0
            //Default comparison function
            //internal int? defaultCompare<T>(T a, T b)
            //{
            //    if ( a is long && b is long)
            //    {
            //        long a1 = (long)Convert.ChangeType(a, typeof(long));
            //        long b1 = (long)Convert.ChangeType(b, typeof(long));

            //        return ((a1 < b1) ? -1 : ((a1 > b1) ? 1 : 0));
            //    }
            //    return null;
            //}

            internal RedBlackTree(Comporator _compare, RBNode _root)
            {
                //if( _compare != null )
                this.compare = _compare;
                //else
                //    this.compare = defaultCompare;

                this.root = _root;
            }
Ejemplo n.º 9
0
        void CreateConeOnPortLocation(SweepEvent sweepEvent)
        {
            var cone = new Cone(sweepEvent.Site, this);
            RBNode <ConeSide> leftNode  = InsertToTree(leftConeSides, cone.LeftSide = new ConeLeftSide(cone));
            RBNode <ConeSide> rightNode = InsertToTree(rightConeSides, cone.RightSide = new ConeRightSide(cone));

            LookForIntersectionWithConeRightSide(rightNode);
            LookForIntersectionWithConeLeftSide(leftNode);
        }
Ejemplo n.º 10
0
 //Swaps two nodes
 internal void swapNode(RBNode n, RBNode v)
 {
     n.key   = v.key;
     n.value = v.value;
     n.left  = v.left;
     n.right = v.right;
     n.color = v.color;
     n.count = v.count;
 }
Ejemplo n.º 11
0
 public static RBNode Instance()
 {
     if (node == null)
     {
         node       = new RBNode();
         node.color = Color.black;
     }
     return(node);
 }
Ejemplo n.º 12
0
 internal RBNode(RBTreeNodeColor color, SweepEvent key, SweepEvent value, RBNode left, RBNode right, long count)
 {
     this.color = color;
     this.key   = key;
     this.value = value;
     this.left  = left;
     this.right = right;
     this.count = count;
 }
Ejemplo n.º 13
0
            //Build a tree
            internal RedBlackTree(Comporator _compare)
            {
                //*if (_compare != null)
                this.compare = _compare;
                ///*else
                //    this.compare = defaultCompare;

                this.root = null;
            }
Ejemplo n.º 14
0
    internal RBNode <T> remove_r(RBNode <T> root, T data, ref bool done)
    {
        if (root == null)
        {
            done = true;
        }
        else
        {
            int dir;

            if (root.value.CompareTo(data) == 0)
            {
                if (root.link[0] == null || root.link[1] == null)
                {
                    int        id   = (root.link[0] == null ? 1 : 0);
                    RBNode <T> save = root.link[id];

                    /* case 0 */
                    if (is_red(root))
                    {
                        done = true;
                    }
                    else if (is_red(save))
                    {
                        save.red = false;
                        done     = true;
                    }

                    /* delete root; */

                    return(save);
                }
                else
                {
                    RBNode <T> heir = root.link[0];

                    while (heir.link[1] != null)
                    {
                        heir = heir.link[1];
                    }

                    root.value = heir.value;
                    data       = heir.value;
                }
            }

            dir            = (root.value.CompareTo(data) < 0 ? 1 : 0);
            root.link[dir] = remove_r(root.link[dir], data, ref done);

            if (!done)
            {
                root = remove_balance(root, dir, ref done);
            }
        }

        return(root);
    }
                protected override ValueTreeNode Find(T item)
                {
                    RBNode node = (RBNode)base.Find(item);

                    if (node.IsLeaf)
                    {
                        return(null);
                    }
                    return(node);
                }
Ejemplo n.º 16
0
 public RBNode RB()
 {
     if (lexer.GetToken().Id == 4)
     {
         var result = new RBNode(lexer.GetText());
         lexer.NextToken();
         return(result);
     }
     throw new ParserException("Got unxpected token from lexer");
 }
Ejemplo n.º 17
0
        private RBNode NewRBNode(T data)
        {
            var node = new RBNode(data);

            node.Parent     = NullNode;
            node.LeftChild  = NullNode;
            node.RightChild = NullNode;
            node.ColorRed();
            return(node);
        }
Ejemplo n.º 18
0
        internal RBNode <BasicReflectionEvent> FindNextInRange(RBNode <BasicReflectionEvent> prev, Point high)
        {
            RBNode <BasicReflectionEvent> nextNode = eventTree.Next(prev);

            if ((null != nextNode) && (Compare(nextNode.Item.Site, high) <= 0))
            {
                return(nextNode);
            }
            return(null);
        }
Ejemplo n.º 19
0
 internal void RemoveSitesForFlatBottom(Point low, Point high)
 {
     for (RBNode <BasicReflectionEvent> node = FindFirstInRange(low, high);
          null != node;
          node = FindNextInRange(node, high))
     {
         MarkStaleSite(node.Item);
     }
     RemoveStaleSites();
 }
Ejemplo n.º 20
0
 private RBNode MoveRedRight(RBNode h)
 {
     FlipColors(h);
     if (IsRed(h.Left.Left))
     {
         h = RotateRight(h);
         FlipColors(h);
     }
     return(h);
 }
Ejemplo n.º 21
0
                protected override KeyValueTreeNode Find(TKey key)
                {
                    RBNode node = (RBNode)base.Find(key);

                    if (node.IsLeaf)
                    {
                        return(null);
                    }
                    return(node);
                }
                /// <summary>
                /// Removes the first occurrence of a specific object from the RedBlackTree&lt;T&gt;.
                /// </summary>
                /// <param name="item">The object to be removed.</param>
                /// <returns>true if item was successfully removed from the RedBlackTree&lt;T&gt;; otherwise, false.</returns>
                public override bool Remove(T item)
                {
                    RBNode current = (RBNode)this.root;

                    while (!current.IsLeaf)
                    {
                        int c = item.CompareTo(current.Value);
                        if (c < 0)
                        {
                            current = current.Left;
                        }
                        else if (c > 0)
                        {
                            current = current.Right;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (current.IsLeaf)
                    {
                        return(false);
                    }

                    if (current.Count > 1)
                    {
                        current.Count--;
                        this.Count--;
                        return(true);
                    }

                    if (current.Left.IsLeaf || current.Right.IsLeaf)
                    {
                        this.Delete(current);
                    }
                    else
                    {
                        RBNode replace = (RBNode)this.Predecessor(current);
                        if (replace == null)
                        {
                            replace = (RBNode)this.Successor(current);
                        }

                        current.Value = replace.Value;
                        current.Count = replace.Count;

                        this.Delete(replace);
                    }

                    this.Count--;
                    return(true);
                }
Ejemplo n.º 23
0
 private void DeleteCorrectCase1(RBNode n)
 {
     if (n.parent == null)
     {
         _root = n;
     }
     else
     {
         DeleteCorrectCase2(n);
     }
 }
Ejemplo n.º 24
0
 public int ActualFrom(RBNode r)
 {
     if (r == sentinelNode)
     {
         return(0);
     }
     else
     {
         return(r.Value + ActualFrom(r.Left) + ActualFrom(r.Right));
     }
 }
Ejemplo n.º 25
0
 private RBNode Minimum(RBNode node)
 {
     if (node != NullNode)
     {
         while (node.LeftChild != NullNode)
         {
             node = node.LeftChild;
         }
     }
     return(node);
 }
Ejemplo n.º 26
0
        CdtSite MiddleCase(CdtSite pi, RBNode <CdtFrontElement> hittedFrontElementNode, out CdtSite rightSite)
        {
//            if(db)
//                ShowFrontWithSite(pi, new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.upperSite.Point), new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.lowerSite.Point));
            var leftSite = hittedFrontElementNode.Item.LeftSite;

            rightSite = hittedFrontElementNode.Item.RightSite;
            InsertAndLegalizeTriangle(pi, hittedFrontElementNode.Item);
            front.DeleteNodeInternal(hittedFrontElementNode);
            return(leftSite);
        }
Ejemplo n.º 27
0
 private RBNode Maximum(RBNode node)
 {
     if (node != NullNode)
     {
         while (node.RightChild != NullNode)
         {
             node = node.RightChild;
         }
     }
     return(node);
 }
Ejemplo n.º 28
0
        /// <summary>
        /// fixing violations
        /// </summary>
        /// <param name="elem"></param>
        /// <returns></returns>
        private RBNode RBFixInsertion(RBNode elem)
        {
            RBNode temp = new RBNode();

            while (elem.parent.color == Color.red)
            {
                if (elem.parent == elem.parent.parent.left)
                {
                    temp = elem.parent.parent.right;
                    if (temp.color == Color.red)
                    {
                        elem.parent.color        = Color.black;
                        temp.color               = Color.black;
                        elem.parent.parent.color = Color.red;
                        elem = elem.parent.parent;
                    }
                    else
                    {
                        if (elem == elem.parent.right)
                        {
                            elem = elem.parent;
                            RBLeftRotate(elem);
                        }
                        elem.parent.color        = Color.black;
                        elem.parent.parent.color = Color.black;
                        RBRightRotate(elem.parent.parent);
                    }
                }
                else
                {
                    temp = elem.parent.parent.left;
                    if (temp.color == Color.red)
                    {
                        elem.parent.color        = Color.black;
                        temp.color               = Color.black;
                        elem.parent.parent.color = Color.red;
                        elem = elem.parent.parent;
                    }
                    else
                    {
                        if (elem == elem.parent.left)
                        {
                            elem = elem.parent;
                            RBRightRotate(elem);
                        }
                        elem.parent.color        = Color.black;
                        elem.parent.parent.color = Color.red;
                        RBLeftRotate(elem.parent.parent);
                    }
                }
            }
            RBroot.color = Color.black;
            return(elem);
        }
Ejemplo n.º 29
0
 // the smallest key in subtree rooted at x; null if no such key
 private RBNode Min(RBNode x)
 {
     if (x.Left == null)
     {
         return(x);
     }
     else
     {
         return(Min(x.Left));
     }
 }
Ejemplo n.º 30
0
 private RBNode MoveRedLeft(RBNode h)
 {
     FlipColors(h);
     if (IsRed(h.Right.Left))
     {
         h.Right = RotateRight(h.Right);
         h       = RotateLeft(h);
         FlipColors(h);
     }
     return(h);
 }
 internal void SetSides(Directions dir, RBNode<BasicObstacleSide> neighborNode, RBNode<BasicObstacleSide> overlapEndNode,
                         BasicObstacleSide interveningGroupSide) {
     if (StaticGraphUtility.IsAscending(dir)) {
         HighNeighbor = neighborNode;
         HighOverlapEnd = overlapEndNode;
         this.GroupSideInterveningBeforeHighNeighbor = interveningGroupSide;
         return;
     }
     LowNeighbor = neighborNode;
     LowOverlapEnd = overlapEndNode;
     this.GroupSideInterveningBeforeLowNeighbor = interveningGroupSide;
 }
 void FindPiercedTriangle(RBNode<CdtFrontElement> v) {
     var e = v.Item.Edge;
     var t = e.CcwTriangle ?? e.CwTriangle;
     var eIndex = t.Edges.Index(e);
     for (int i = 1; i <= 2; i++) {
         var ei = t.Edges[i + eIndex];
         var signedArea0 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(ei.lowerSite.Point, a.Point, b.Point));
         var signedArea1 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(ei.upperSite.Point, a.Point, b.Point));
         if (signedArea1 * signedArea0 <= 0) {
             piercedTriangle = t;
             piercedEdge = ei;
             break;
         }
     }
 }
        void ProcessLeftFrontPiercedElement() {
                       // CdtSweeper.ShowFront(triangles, front,new []{new LineSegment(a.Point, b.Point),new LineSegment(piercedToTheLeftFrontElemNode.Item.Edge.lowerSite.Point,piercedToTheLeftFrontElemNode.Item.Edge.upperSite.Point)},null);
            var v = piercedToTheLeftFrontElemNode;

            do {
                elementsToBeRemovedFromFront.Add(v.Item);
                AddSiteToLeftPolygon(v.Item.LeftSite);
                v = front.Previous(v);
            } while (Point.PointToTheLeftOfLine(v.Item.LeftSite.Point, a.Point, b.Point)); //that is why we are adding to the left polygon
            elementsToBeRemovedFromFront.Add(v.Item);
            AddSiteToRightPolygon(v.Item.LeftSite);
            if (v.Item.LeftSite == b) {
                piercedToTheLeftFrontElemNode = v; //this will stop the traversal
                return;
            }
            FindPiercedTriangle(v);
            piercedToTheLeftFrontElemNode = null;
        }
        void ProcessRightFrontPiercedElement() {
            var v = piercedToTheRightFrontElemNode;

            do {
                elementsToBeRemovedFromFront.Add(v.Item);
                AddSiteToRightPolygon(v.Item.RightSite);
                v = front.Next(v);
            } while (Point.PointToTheRightOfLine(v.Item.RightSite.Point, a.Point, b.Point)); //that is why we are adding to the right polygon
            elementsToBeRemovedFromFront.Add(v.Item);
            AddSiteToLeftPolygon(v.Item.RightSite);
            if (v.Item.RightSite == b) {
                piercedToTheRightFrontElemNode = v; //this will stop the traversal
                return;
            }
            FindPiercedTriangle(v);
            piercedToTheRightFrontElemNode = null;
        }
        void Init() {
//            if (CdtSweeper.D)
//                CdtSweeper.ShowFront(triangles, front, new[] {new LineSegment(a.Point, b.Point)},null);
                                     //new[] {new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point)});
            var frontElemNodeRightOfA = CdtSweeper.FindNodeInFrontBySite(front, a);
            var frontElemNodeLeftOfA = front.Previous(frontElemNodeRightOfA);
            if (Point.PointToTheLeftOfLine(b.Point, frontElemNodeLeftOfA.Item.LeftSite.Point, frontElemNodeLeftOfA.Item.RightSite.Point))
                piercedToTheLeftFrontElemNode = frontElemNodeLeftOfA;
            else if (Point.PointToTheRightOfLine(b.Point, frontElemNodeRightOfA.Item.RightSite.Point, frontElemNodeRightOfA.Item.LeftSite.Point))
                piercedToTheRightFrontElemNode = frontElemNodeRightOfA;
            else {
                foreach (var e in a.Edges) {
                    var t = e.CcwTriangle;
                    if (t == null) continue;
                    if (Point.PointToTheLeftOfLine(b.Point, e.lowerSite.Point, e.upperSite.Point))
                        continue;
                    var eIndex = t.Edges.Index(e);
                    var site = t.Sites[eIndex + 2];
                    if (Point.PointToTheLeftOfLineOrOnLine(b.Point, site.Point, e.upperSite.Point)) {
                        piercedEdge = t.Edges[eIndex + 1];
                        piercedTriangle = t;
//                                                CdtSweeper.ShowFront(triangles, front, new[] { new LineSegment(e.upperSite.Point, e.lowerSite.Point) }, 
//                                                    new[] { new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point) });
                        break;
                    }
                }
            }
        }
 private void CreateScanSegmentFromLowSide(RBNode<BasicObstacleSide> lowSideNode, BasicVertexEvent vertexEvent) {
     // Create one or more segments from low to high using the neighbors of the LowObstacleSide.
     this.CreateScanSegments(lowSideNode.Item.Obstacle, this.LowNeighborSides, vertexEvent);
 }
        void PrepareNextStateAfterPiercedEdge() {
            var t = piercedEdge.CwTriangle ?? piercedEdge.CcwTriangle;
            var eIndex = t.Edges.Index(piercedEdge);
            for (int i = 1; i <= 2; i++) {
                var e = t.Edges[i + eIndex];
                var signedArea0 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(e.lowerSite.Point, a.Point, b.Point));
                var signedArea1 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(e.upperSite.Point, a.Point, b.Point));
                if (signedArea1 * signedArea0 <= 0) {
                    if (e.CwTriangle != null && e.CcwTriangle != null) {
                        piercedTriangle = t;
                        piercedEdge = e;
                        break;
                    }
                    //e has to belong to the front, and its triangle has to be removed
                    piercedTriangle = null;
                    piercedEdge = null;
                    var leftSite = e.upperSite.Point.X < e.lowerSite.Point.X ? e.upperSite : e.lowerSite;
                    var frontElem = CdtSweeper.FindNodeInFrontBySite(front, leftSite);
                    Debug.Assert(frontElem != null);
                    if (leftSite.Point.X < a.Point.X)
                        piercedToTheLeftFrontElemNode = frontElem;
                    else
                        piercedToTheRightFrontElemNode = frontElem;

                    RemovePiercedTriangle(e.CwTriangle ?? e.CcwTriangle);
                    break;
                }
            }
        }
 void CreateScanSegmentFromHighSide(RBNode<BasicObstacleSide> highSideNode, BasicVertexEvent vertexEvent) {
     // Create one or more segments from low to high using the neighbors of the HighObstacleSide.
     this.CreateScanSegments(highSideNode.Item.Obstacle, this.HighNeighborSides, vertexEvent);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="obstSideEndVertex"></param>
 /// <param name="rbNode">represents a node of the right cone side</param>
 /// <param name="obstSideStartVertex"></param>
 void FixConeRightSideIntersections(PolylinePoint obstSideStartVertex, PolylinePoint obstSideEndVertex,
                                    RBNode<ConeSide> rbNode) {
     if (rbNode != null) {
         Point intersection;
         var seg = rbNode.Item as ConeRightSide;
         if (seg != null &&
             Point.IntervalIntersectsRay(obstSideStartVertex.Point, obstSideEndVertex.Point, seg.Start,
                                         seg.Direction,
                                         out intersection)) {
             EnqueueEvent(CreateRightIntersectionEvent(seg, intersection, obstSideEndVertex));
         }
     }
 }
        private bool ProcessGroupSideEncounteredOnTraversalToNeighbor(RBNode<BasicObstacleSide> nborNode, Point sideReferencePoint,
                                                                                Directions nborSearchDir) {
            if (!this.ScanLineCrossesObstacle(sideReferencePoint, nborNode.Item.Obstacle)) {
                return false;
            }

            // We don't stop overlap or neighbor-traversal for groups, because we must go through the boundary;
            // neither do we create overlapped edges (unless we're inside a non-group obstacle).  Instead we turn
            // the boundary crossing on or off based on group membership at ShortestPath-time.
            Directions dirToInsideOfGroup = ((nborNode.Item is LowObstacleSide) == StaticGraphUtility.IsAscending(nborSearchDir))
                    ? nborSearchDir : CompassVector.OppositeDir(nborSearchDir);
            var intersect = this.ScanLineIntersectSide(sideReferencePoint, nborNode.Item);
            this.CurrentGroupBoundaryCrossingMap.AddIntersection(intersect, nborNode.Item.Obstacle, dirToInsideOfGroup);
            return true;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="rightSide"></param>
 /// <param name="rbNode">represents a node of the right cone side</param>
 void FixConeRightSideIntersections(BrokenConeSide rightSide, RBNode<ConeSide> rbNode) {
     //the first intersection can happen only with predecessors of rightSide
     Debug.Assert(rbNode != null);
     do { //this loop usually works only once
         rbNode = rightConeSides.Previous(rbNode);
     } while (rbNode != null && Point.PointToTheLeftOfLineOrOnLine(rightSide.Start, rbNode.Item.Start, rbNode.Item.Start + rbNode.Item.Direction));  
     if (rbNode != null) {
         Point intersection;
         var seg = rbNode.Item as ConeRightSide;
         if (seg != null &&
             Point.IntervalIntersectsRay(rightSide.Start, rightSide.End, seg.Start, seg.Direction,
                                         out intersection)) {
             EnqueueEvent(CreateRightIntersectionEvent(seg, intersection, rightSide.EndVertex));
             // Show(CurveFactory.CreateDiamond(3, 3, intersection));
         }
     }
 }
 void FindInitialNeighborSides(RBNode<BasicObstacleSide> sideNode, out RBNode<BasicObstacleSide> lowNborSideNode,
                               out RBNode<BasicObstacleSide> highNborSideNode)
 {
     lowNborSideNode = this.scanLine.NextLow(sideNode);
     highNborSideNode = this.scanLine.NextHigh(sideNode);
 }
 protected void FindNeighbors(BasicVertexEvent vertexEvent, RBNode<BasicObstacleSide> sideNode, NeighborSides neighborSides) {
     // vertexEvent.Site is on one of vertexEvent.Obstacle.Active(Low|High)Side, so we must get the 
     // appropriate vertex on whichever one of those Active*Sides is sideNode.
     var sideReferencePoint = (vertexEvent is OpenVertexEvent) ? sideNode.Item.Start : sideNode.Item.End;
     RBNode<BasicObstacleSide> initialLowNbor, initialHighNbor;
     this.FindInitialNeighborSides(sideNode, out initialLowNbor, out initialHighNbor);
     this.SkipToNeighbor(this.ScanDirection.OppositeDirection, sideNode.Item, sideReferencePoint, initialLowNbor, neighborSides);
     this.SkipToNeighbor(this.ScanDirection.Direction, sideNode.Item, sideReferencePoint, initialHighNbor, neighborSides);
 }
        void LookForIntersectionWithConeLeftSide(RBNode<ConeSide> leftNode) {
            //Show(new Ellipse(1, 1, leftNode.item.Start));


            var coneLeftSide = leftNode.Item as ConeLeftSide;
            if (coneLeftSide != null) {
                //leftNode = leftSegmentTree.TreePredecessor(leftNode);
                //if (leftNode != null) {
                //    var seg = leftNode.item as ObstacleSideSegment;
                //    if (seg != null)
                //        TryIntersectionOfConeLeftSideAndObstacleConeSide(coneLeftSide, seg);
                //}

                RightObstacleSide rightObstacleSide = FindFirstObstacleSideToTheLeftOfPoint(coneLeftSide.Start);
                if (rightObstacleSide != null)
                    TryIntersectionOfConeLeftSideAndObstacleSide(coneLeftSide, rightObstacleSide);
            } else {
                var seg = (BrokenConeSide)leftNode.Item;
                leftNode = leftConeSides.Next(leftNode);
                if (leftNode != null) {
                    coneLeftSide = leftNode.Item as ConeLeftSide;
                    if (coneLeftSide != null)
                        TryIntersectionOfConeLeftSideAndObstacleConeSide(coneLeftSide, seg);
                }
            }
        }
        void TriangulateEmptySpaceToTheLeft(RBNode<CdtFrontElement> leftLegNode) {
            var peakSite = leftLegNode.Item.RightSite;
            var previousNode = front.Previous(leftLegNode);

            while (previousNode != null) {
                var prevElement = previousNode.Item;
                var rp = prevElement.LeftSite;
                var r=prevElement.RightSite;
                if ((r.Point - peakSite.Point) * (rp.Point - r.Point) < 0) {
                    //see figures 9(a) and 9(b) of the paper
                    leftLegNode=ShortcutTwoFrontElements(previousNode, leftLegNode);
                    previousNode = front.Previous(leftLegNode);
                } else {
                    TryTriangulateBasinToTheLeft(leftLegNode);
                    break;
                }

            }
        }
        CdtSite MiddleCase(CdtSite pi, RBNode<CdtFrontElement> hittedFrontElementNode, out CdtSite rightSite) {
//            if(db)
//                ShowFrontWithSite(pi, new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.upperSite.Point), new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.lowerSite.Point));
            var leftSite = hittedFrontElementNode.Item.LeftSite;
            rightSite = hittedFrontElementNode.Item.RightSite;
            InsertAndLegalizeTriangle(pi, hittedFrontElementNode.Item);
            front.DeleteNodeInternal(hittedFrontElementNode);
            return leftSite;
        }
        void LookForIntersectionWithConeRightSide(RBNode<ConeSide> rightNode) {
            //Show(new Ellipse(10, 5, rightNode.item.Start));
            var coneRightSide = rightNode.Item as ConeRightSide;
            if (coneRightSide != null) {
                //rightNode = rightSegmentTree.TreeSuccessor(rightNode);
                //if (rightNode != null) {
                //    var seg = rightNode.item as ObstacleSideSegment;
                //    if (seg != null)
                //        TryIntersectionOfConeRightSideAndObstacleConeSide(coneRightSide, seg);
                //}

                LeftObstacleSide leftObstacleSide = FindFirstObstacleSideToToTheRightOfPoint(coneRightSide.Start);
                if (leftObstacleSide != null)
                    TryIntersectionOfConeRightSideAndObstacleSide(coneRightSide, leftObstacleSide);
            } else {
                var seg = (BrokenConeSide)rightNode.Item;
                rightNode = rightConeSides.Previous(rightNode);
                if (rightNode != null) {
                    coneRightSide = rightNode.Item as ConeRightSide;
                    if (coneRightSide != null)
                        TryIntersectionOfConeRightSideAndObstacleConeSide(coneRightSide, seg);
                }
            }
        }
        protected override void ProcessVertexEvent(RBNode<BasicObstacleSide> lowSideNode,
                    RBNode<BasicObstacleSide> highSideNode, BasicVertexEvent vertexEvent) {
            // Create the scan segment from the low side.
            CreateScanSegmentFromLowSide(lowSideNode, vertexEvent);

            // If the low segment covered up to our high neighbor, we're done.  Otherwise, there were overlaps
            // inside a flat boundary and now we need to come in from the high side.  In this case there's a chance
            // that we're redoing a single subsegment in the event of two obstacles' outside edges crossing
            // the middle of a flat boundary of the event obstacle, but that should be sufficiently rare that
            // we don't need to optimize it away as the segments will be merged by ScanSegmentTree.MergeSegments.
            // TODOgroup TODOperf: currentGroupBoundaryCrossingMap still has the Low-side stuff in it but it shouldn't
            // matter much - profile to see how much time GetOrderedIndexBetween takes.
            if (LowNeighborSides.HighNeighbor.Item != HighNeighborSides.HighNeighbor.Item) {
                CreateScanSegmentFromHighSide(highSideNode, vertexEvent);
            }
        }
 /// <summary>
 /// aNode is to the left of bNode, and they are consecutive
 /// </summary>
 /// <param name="aNode"></param>
 /// <param name="bNode"></param>
 RBNode<CdtFrontElement> ShortcutTwoFrontElements(RBNode<CdtFrontElement> aNode, RBNode<CdtFrontElement> bNode) {
     var aElem = aNode.Item;
     var bElem = bNode.Item;
     Debug.Assert(aElem.RightSite == bElem.LeftSite);
     CdtTriangle t = new CdtTriangle(aElem.LeftSite, aElem.RightSite, bElem.RightSite, aElem.Edge, bElem.Edge,
                                     createEdgeDelegate);
     Triangles.Insert(t);
     front.DeleteNodeInternal(aNode); 
     //now bNode might b not valid anymore
     front.Remove(bElem);
     var newEdge = t.Edges[2];
     Debug.Assert(newEdge.IsAdjacent( aElem.LeftSite) && newEdge.IsAdjacent(bElem.RightSite));
     LegalizeEdge(aElem.LeftSite, t.OppositeEdge(aElem.LeftSite));
     t=newEdge.CcwTriangle ?? newEdge.CwTriangle;
     LegalizeEdge(bElem.RightSite, t.OppositeEdge(bElem.RightSite));
     return front.Insert(new CdtFrontElement(aElem.LeftSite, newEdge));          
 }
 protected abstract void ProcessVertexEvent(RBNode<BasicObstacleSide> lowSideNode,
             RBNode<BasicObstacleSide> highSideNode, BasicVertexEvent vertexEvent);
 void RemoveSideFromScanLine(RBNode<BasicObstacleSide> sideNode, Point scanPos) {
     scanLine.Remove(sideNode.Item, scanPos);
 }
 void TryTriangulateBasinToTheLeft(RBNode<CdtFrontElement> leftLegNode) {
     if (!DropsSharpEnoughToTheLeft(leftLegNode.Item))
         return;
     //ShowFrontWithSite(leftLegNode.Item.LeftSite);
     var stack = new Stack<CdtSite>();
     stack.Push(leftLegNode.Item.LeftSite);
     while (true) {
         var site = stack.Pop();
         leftLegNode = FindNodeInFrontBySite(front, site);
         var prev = front.Previous(leftLegNode);
         if (prev == null)
             return;
         if (Point.GetTriangleOrientationWithNoEpsilon(prev.Item.LeftSite.Point, leftLegNode.Item.LeftSite.Point, leftLegNode.Item.RightSite.Point) ==
             TriangleOrientation.Counterclockwise) {
             stack.Push(prev.Item.LeftSite);
             ShortcutTwoFrontElements(prev, leftLegNode);
       //      ShowFrontWithSite(site);
         } else {
             if (leftLegNode.Item.LeftSite.Point.Y > leftLegNode.Item.RightSite.Point.Y) {
                 stack.Push(prev.Item.LeftSite);
             } else {
                 if (prev.Item.LeftSite.Point.Y <= prev.Item.RightSite.Point.Y)
                     return;
                 stack.Push(prev.Item.LeftSite);
             }
         }
     }
 }
        // As described in the doc, we stop at the first neighbor of the appropriate side type that we touch 
        // the border of, even if that's just skimming along the extreme vertex of it, because those will
        // continue the chain of open/close+addSegment, and we don't want to follow the full length of the
        // segment each time if there are a lot of collinear obstacle open/close events.
        protected void FindNeighbors(BasicVertexEvent vertexEvent, RBNode<BasicObstacleSide> lowSideNode, RBNode<BasicObstacleSide> highSideNode) {
            LowNeighborSides.Clear();
            HighNeighborSides.Clear();

            // Find the first HighObstacleSide in the low (scanline-decreasing) direction (this may be the low
            // sentinel) and the lowest LowObstacleSide toward that that we cross *through*, if any.  Then do
            // the same thing in the high direction.  If we are not overlapped, then we'll jump out immediately
            // from SkipToNeighbor, so there won't be a lot of redundant effort in that case.
            FindNeighbors(vertexEvent, lowSideNode, LowNeighborSides);
            FindNeighbors(vertexEvent, highSideNode, HighNeighborSides);
        }
        void TriangulateEmptySpaceToTheRight(RBNode<CdtFrontElement> piNode) {
            var piSite=piNode.Item.LeftSite;
            var piPoint=piSite.Point;           
            var piNext = front.Next(piNode);
            while (piNext != null) {
                var frontElem=piNext.Item;
                var r=frontElem.LeftSite;
                var rp = frontElem.RightSite;
                if ((r.Point - piPoint) * (rp.Point - r.Point) < 0) {
//see figures 9(a) and 9(b) of the paper
                    piNode = ShortcutTwoFrontElements(piNode, piNext);
                    piNext = front.Next(piNode);
                } else {
                    TryTriangulateBasinToTheRight(piNode);
                    break;
                }
            }            
        }
        void SkipToNeighbor(Directions nborSearchDir, BasicObstacleSide side, Point sideReferencePoint,
                            RBNode<BasicObstacleSide> nborNode, NeighborSides neighborSides) {
            // Find the first neighbor side (LowObstacleSide if going high, HighObstacleSide if going low) and
            // the side of opposite type (which would potentially end overlap), that that we cross *through*, if any.
            RBNode<BasicObstacleSide> overlapSideNode = null;
            BasicObstacleSide interveningGroupSide = null;
            for (; ; nborNode = scanLine.Next(nborSearchDir, nborNode)) {
                // Ignore the opposite side of the current obstacle.
                if (nborNode.Item.Obstacle == side.Obstacle) {
                    continue;
                }

                if (nborNode.Item.Obstacle.IsGroup) {
                    if (ProcessGroupSideEncounteredOnTraversalToNeighbor(nborNode, sideReferencePoint, nborSearchDir)) {
                        // Keep the first one (outermost) encountered.
                        if (null == interveningGroupSide) {
                            interveningGroupSide = nborNode.Item;
                        }
                    }
                    continue;
                }

                // Check for overlap-ending obstacle.
                if ((nborNode.Item is HighObstacleSide) == StaticGraphUtility.IsAscending(nborSearchDir)) {
                    if (ScanLineCrossesObstacle(sideReferencePoint, nborNode.Item.Obstacle)) {
                        overlapSideNode = nborNode;
                        interveningGroupSide = null;
                    }
                    continue;
                }

                // If we're here, we found the neighbor we were looking for.
                break;
            }

            neighborSides.SetSides(nborSearchDir, nborNode, overlapSideNode, interveningGroupSide);
        }
 void TryTriangulateBasinToTheRight(RBNode<CdtFrontElement> piNode) {           
     if (!DropsSharpEnoughToTheRight(piNode.Item))
         return;
    // ShowFrontWithSite(piNode.Item.LeftSite);
     var stack = new Stack<CdtSite>();
     stack.Push(piNode.Item.LeftSite);
     while(true) {
         var site = stack.Pop();
         piNode = FindNodeInFrontBySite(front, site);      
         var next = front.Next(piNode);
         if (next == null)
             return;
         if (Point.GetTriangleOrientationWithNoEpsilon(piNode.Item.LeftSite.Point, piNode.Item.RightSite.Point, next.Item.RightSite.Point) == TriangleOrientation.Counterclockwise) {
             ShortcutTwoFrontElements(piNode, next);
             stack.Push(site);
         } else {
             if (piNode.Item.LeftSite.Point.Y > piNode.Item.RightSite.Point.Y) {
                 stack.Push(piNode.Item.RightSite);
             } else {
                 if (next.Item.LeftSite.Point.Y >= next.Item.RightSite.Point.Y)
                     return;
                 stack.Push(piNode.Item.RightSite);
             }
         }
     } 
 }
        void FindNeighborsAndProcessVertexEvent(RBNode<BasicObstacleSide> lowSideNode
                                                , RBNode<BasicObstacleSide> highSideNode
                                                , BasicVertexEvent vertexEvent) {
            CurrentGroupBoundaryCrossingMap.Clear();
            FindNeighbors(vertexEvent, lowSideNode, highSideNode);
            this.ProcessVertexEvent(lowSideNode, highSideNode, vertexEvent);

            // Clear this again because we don't want Reflections to access stale values.
            CurrentGroupBoundaryCrossingMap.Clear();
        }
 void ProjectToFront(CdtSite site, out RBNode<CdtFrontElement> frontElement) {
     frontElement = front.FindLast(s => s.X <= site.Point.X);
 }
 CdtSite LeftCase(CdtSite pi, RBNode<CdtFrontElement> hittedFrontElementNode, out CdtSite rightSite) {
     //left case
     //                if(db)ShowFrontWithSite(pi, new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.upperSite.Point), new LineSegment(pi.Point, hittedFrontElementNode.Item.Edge.lowerSite.Point));
     Debug.Assert(ApproximateComparer.Close(pi.Point.X, hittedFrontElementNode.Item.X));
     var hittedFrontElement = hittedFrontElementNode.Item;
     InsertAndLegalizeTriangle(pi, hittedFrontElement);
     var prevToHitted = front.Previous(hittedFrontElementNode);
     var leftSite = prevToHitted.Item.LeftSite;
     rightSite = hittedFrontElementNode.Item.RightSite;
     //                if(db)ShowFrontWithSite(pi, new LineSegment(pi.Point, leftSite.Point), new LineSegment(pi.Point, prevToHitted.Item.RightSite.Point));
     InsertAndLegalizeTriangle(pi, prevToHitted.Item);
     front.DeleteNodeInternal(prevToHitted);
     var d = front.Remove(hittedFrontElement);
     Debug.Assert(d != null);
     return leftSite;
 }
 RBNode<ConeSide> GetRbNodeEmergency(RBNode<ConeSide> rbNode, ConeSide leftConeSide) {
     for (var node = leftConeSides.TreeMinimum(); node != null; node = leftConeSides.Next(node))
         if (node.Item == leftConeSide) {
             rbNode = node;
             break;
         }
     return rbNode;
 }