void RemoveSegFromRightTree(ConeSide coneSide)
        {
            //   ShowRightTree();
            Debug.Assert(coneSide.Removed == false);
            coneSideComparer.SetOperand(coneSide);
            RBNode <ConeSide> b = rightConeSides.Remove(coneSide);

            coneSide.Removed = true;
            if (b == null)
            {
                double tmpZ = Z;
                Z = Math.Max(GetZ(coneSide.Start), Z - 0.01);
                //we need to return to the past a little bit when the order was still correc
                coneSideComparer.SetOperand(coneSide);
#if TEST_MSAGL
                b =
#endif
                rightConeSides.Remove(coneSide);
                Z = tmpZ;

#if TEST_MSAGL
                if (b == null)
                {
                    PrintOutRightSegTree();
                    Debug.WriteLine(coneSide);
                    ShowRightTree(CurveFactory.CreateDiamond(3, 4, coneSide.Start));
                    GeometryGraph gg = CreateGraphFromObstacles(Obstacles);
                    // FIXME GeometryGraphWriter.Write(gg, "c:\\tmp\\bug1");
                }
#endif
            }
            Debug.Assert(b != null);
        }
        void RemoveSegFromLeftTree(ConeSide coneSide)
        {
            Debug.Assert(coneSide.Removed == false);
            coneSide.Removed = true;
            coneSideComparer.SetOperand(coneSide);
            RBNode <ConeSide> b = leftConeSides.Remove(coneSide);

            if (b == null)
            {
                double tmpZ = Z;
                Z = Math.Max(GetZ(coneSide.Start), Z - 0.01);
                coneSideComparer.SetOperand(coneSide);

#if TEST_MSAGL
                b =
#endif
                leftConeSides.Remove(coneSide);
                Z = tmpZ;
#if TEST_MSAGL
                if (b == null)
                {
                    PrintOutLeftSegTree();
                    Debug.WriteLine(coneSide);
                    ShowLeftTree(new Ellipse(2, 2, coneSide.Start));
                }
#endif
            }

            Debug.Assert(b != null);
        }
        ICurve ExtendSegmentToZ(ConeSide segment)
        {
            double den = segment.Direction * SweepDirection;

            Debug.Assert(Math.Abs(den) > ApproximateComparer.DistanceEpsilon);
            double t = (Z - segment.Start * SweepDirection) / den;

            return(new LineSegment(segment.Start, segment.Start + segment.Direction * t));
        }
        void CreateConeClosureEvent(BrokenConeSide brokenConeSide, ConeSide otherSide)
        {
            Point x;
            bool  r = Point.RayIntersectsRayInteriors(brokenConeSide.start, brokenConeSide.Direction, otherSide.Start,
                                                      otherSide.Direction, out x);

            Debug.Assert(r);
            EnqueueEvent(new ConeClosureEvent(x, brokenConeSide.Cone));
        }
        // ReSharper disable UnusedMember.Global
        internal ICurve ExtendSegmentToZPlus1(ConeSide segment)
        {
            // ReSharper restore UnusedMember.Global
            double den = segment.Direction * SweepDirection;

            Debug.Assert(Math.Abs(den) > ApproximateComparer.DistanceEpsilon);
            double t = (Z + 1 - segment.Start * SweepDirection) / den;

            return(new LineSegment(segment.Start, segment.Start + segment.Direction * t));
        }
 static bool VertexIsToTheRightOfSegment(SweepEvent vertexEvent, ConeSide seg)
 {
     return(Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction,
                                         vertexEvent.Site) == TriangleOrientation.Clockwise);
 }
 internal BrokenConeSide(Point start, PolylinePoint end, ConeSide coneSide)
 {
     this.start = start;
     EndVertex  = end;
     ConeSide   = coneSide;
 }
 RBNode<ConeSide> InsertToTree(RbTree<ConeSide> tree, ConeSide coneSide) {
     Debug.Assert(coneSide.Direction*SweepDirection > ApproximateComparer.DistanceEpsilon);
     coneSideComparer.SetOperand(coneSide);
     return tree.Insert(coneSide);
 }
 RBNode <ConeSide> InsertToTree(RbTree <ConeSide> tree, ConeSide coneSide)
 {
     Debug.Assert(coneSide.Direction * SweepDirection > ApproximateComparer.DistanceEpsilon);
     coneSideComparer.SetOperand(coneSide);
     return(tree.Insert(coneSide));
 }
 static bool PointIsToTheRightOfSegment(Point p, ConeSide seg) {
     return (Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction, p) ==
             TriangleOrientation.Clockwise);
 }
        void CreateConeClosureEvent(BrokenConeSide brokenConeSide, ConeSide otherSide) {
            Point x;
#if DEBUG && TEST_MSAGL
            var r =
#endif
 Point.RayIntersectsRayInteriors(brokenConeSide.start, brokenConeSide.Direction, otherSide.Start,
                                                otherSide.Direction, out x);
#if DEBUG && TEST_MSAGL
            if (!r)
                LayoutAlgorithmSettings.ShowDebugCurves(
                    new DebugCurve(100, 0.1, "red",new LineSegment(brokenConeSide.Start, brokenConeSide.start + brokenConeSide.Direction)),
                    new DebugCurve(100,0.1, "black", new Ellipse(0.1,0.1, brokenConeSide.Start)),
                    new DebugCurve(100, 0.1, "blue",new LineSegment(otherSide.Start, otherSide.Start + otherSide.Direction)));
            Debug.Assert(r);
#endif
            EnqueueEvent(new ConeClosureEvent(x, brokenConeSide.Cone));
        }
 static bool VertexIsToTheRightOfSegment(SweepEvent vertexEvent, ConeSide seg) {
     return (Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction,
                                          vertexEvent.Site) == TriangleOrientation.Clockwise);
 }
 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;
 }
        internal ICurve ExtendSegmentToZPlus1(ConeSide segment) {
            double den = segment.Direction * SweepDirection;
            Debug.Assert(Math.Abs(den) > ApproximateComparer.DistanceEpsilon);
            double t = (Z + 1 - segment.Start * SweepDirection) / den;

            return new LineSegment(segment.Start, segment.Start + segment.Direction * t);
        }
 internal BrokenConeSide(Point start, PolylinePoint end, ConeSide coneSide) {
     this.start = start;
     EndVertex = end;
     ConeSide = coneSide;
 }
        void RemoveSegFromRightTree(ConeSide coneSide) {
            //   ShowRightTree();
            Debug.Assert(coneSide.Removed == false);
            coneSideComparer.SetOperand(coneSide);
            RBNode<ConeSide> b = rightConeSides.Remove(coneSide);
            coneSide.Removed = true;
            if (b == null) {
                double tmpZ = Z;
                Z = Math.Max(GetZ(coneSide.Start), Z - 0.01);
                //we need to return to the past a little bit when the order was still correc
                coneSideComparer.SetOperand(coneSide);
#if TEST_MSAGL
                b =
#endif
                rightConeSides.Remove(coneSide);
                Z = tmpZ;

#if TEST_MSAGL
                if (b == null) {
                    PrintOutRightSegTree();
                    Console.WriteLine(coneSide);
                    ShowRightTree(CurveFactory.CreateDiamond(3, 4, coneSide.Start));
                    GeometryGraph gg = CreateGraphFromObstacles(Obstacles);
                    GeometryGraphWriter.Write(gg, "c:\\tmp\\bug1");
                }
#endif
            }
            Debug.Assert(b != null);
        }
 static bool PointIsToTheRightOfSegment(Point p, ConeSide seg)
 {
     return(Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction, p) ==
            TriangleOrientation.Clockwise);
 }
 RBNode<ConeSide> InsertToTree(RbTree<ConeSide> tree, ConeSide coneSide) {
     Debug.Assert(coneSide.Direction * SweepDirection > 0);
     coneSideComparer.SetOperand(coneSide);
     return tree.Insert(coneSide);
 }
        void RemoveSegFromRightTree(ConeSide coneSide) {
            //   ShowRightTree();
            Debug.Assert(coneSide.Removed == false);
            coneSideComparer.SetOperand(coneSide);
            var b = rightConeSides.Remove(coneSide);
            coneSide.Removed = true;
            if (b == null) {
                var tmpZ = Z;
                Z = Math.Max(GetZ(coneSide.Start), Z - 0.01);
                //we need to return to the past a little bit when the order was still correc
                coneSideComparer.SetOperand(coneSide);
                b = rightConeSides.Remove(coneSide);
                Z = tmpZ;

#if TEST_MSAGL
                if (b == null) {
                    PrintOutRightSegTree();
                    Console.WriteLine(coneSide);
                   // ShowBothTrees(new DebugCurve("red", CurveFactory.CreateDiamond(3, 4, coneSide.Start)));
                    // GeometryGraph gg = CreateGraphFromObstacles(Obstacles);
                    //gg.Save("c:\\tmp\\bug1");
                }
#endif
            }
            // the following should not happen if the containment hierarchy is correct.  
            // If containment is not correct it still should not result in a fatal error, just a funny looking route.
            // Debug.Assert(b != null);
        }
        void RemoveSegFromLeftTree(ConeSide coneSide) {
            Debug.Assert(coneSide.Removed == false);
            coneSide.Removed = true;
            coneSideComparer.SetOperand(coneSide);
            var b = leftConeSides.Remove(coneSide);

            if (b == null) {
                var tmpZ = Z;
                Z = Math.Max(GetZ(coneSide.Start), Z - 0.01);
                coneSideComparer.SetOperand(coneSide);
#if TEST_MSAGL
                b =
#endif
 leftConeSides.Remove(coneSide);
                Z = tmpZ;
#if TEST_MSAGL
                if (b == null) {
                    PrintOutLeftSegTree();
                    Console.WriteLine(coneSide);
                    ShowLeftTree(new Ellipse(2, 2, coneSide.Start));
                }
#endif
            }

            Debug.Assert(b != null);
        }
        //        static int count;
        void GoOverConesSeeingVertexEvent(SweepEvent vertexEvent)
        {
            RBNode <ConeSide> rbNode = FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(vertexEvent);

            if (rbNode == null)
            {
                return;
            }
            ConeSide coneRightSide = rbNode.Item;
            Cone     cone          = coneRightSide.Cone;
            ConeSide leftConeSide  = cone.LeftSide;

            if (VertexIsToTheLeftOfSegment(vertexEvent, leftConeSide))
            {
                return;
            }
            var visibleCones = new List <Cone> {
                cone
            };

            coneSideComparer.SetOperand(leftConeSide);
            rbNode = leftConeSides.Find(leftConeSide);

            if (rbNode == null)
            {
                double tmpZ = Z;

                Z = Math.Max(GetZ(leftConeSide.Start), PreviousZ);
                //we need to return to the past when the order was still correct
                coneSideComparer.SetOperand(leftConeSide);
                rbNode = leftConeSides.Find(leftConeSide);
                Z      = tmpZ;


#if TEST_MSAGL
                if (rbNode == null)
                {
                    //GeometryGraph gg = CreateGraphFromObstacles();
                    //gg.Save("c:\\tmp\\bug");


                    PrintOutLeftSegTree();
                    Debug.WriteLine(leftConeSide);
                    ShowLeftTree(new Ellipse(3, 3, vertexEvent.Site));
                    ShowRightTree(new Ellipse(3, 3, vertexEvent.Site));
                }
#endif
            }

            rbNode = leftConeSides.Next(rbNode);
            while (rbNode != null && !VertexIsToTheLeftOfSegment(vertexEvent, rbNode.Item))
            {
                visibleCones.Add(rbNode.Item.Cone);
                rbNode = leftConeSides.Next(rbNode);
            }

            //Show(new Ellipse(1, 1, vertexEvent.Site));

            foreach (Cone c in visibleCones)
            {
                AddEdge(c.Apex, vertexEvent.Site);
                RemoveCone(c);
            }
        }
 void CreateConeClosureEvent(BrokenConeSide brokenConeSide, ConeSide otherSide) {
     Point x;
     bool r = Point.RayIntersectsRayInteriors(brokenConeSide.start, brokenConeSide.Direction, otherSide.Start,
                                              otherSide.Direction, out x);
     Debug.Assert(r);
     EnqueueEvent(new ConeClosureEvent(x, brokenConeSide.Cone));
 }