예제 #1
0
        void ProcessRightIntersectionEvent(RightIntersectionEvent rightIntersectionEvent)
        {
            //restore Z for the time being
            // Z = PreviousZ;
            if (rightIntersectionEvent.coneRightSide.Removed == false)
            {
                //it can happen that the cone side participating in the intersection is gone;
                //obstracted by another obstacle or because of a vertex found inside of the cone
                //PrintOutRightSegTree();
                RemoveSegFromRightTree(rightIntersectionEvent.coneRightSide);
                Z = SweepDirection * rightIntersectionEvent.Site;
                var rightSide = new BrokenConeSide(
                    rightIntersectionEvent.Site,
                    rightIntersectionEvent.EndVertex, rightIntersectionEvent.coneRightSide);
                InsertToTree(rightConeSides, rightSide);
                rightIntersectionEvent.coneRightSide.Cone.RightSide = rightSide;
                LookForIntersectionOfObstacleSideAndRightConeSide(rightIntersectionEvent.Site,
                                                                  rightIntersectionEvent.EndVertex);

                TryCreateConeClosureForRightSide(rightSide);
            }
            else
            {
                Z = SweepDirection * rightIntersectionEvent.Site;
            }
        }
예제 #2
0
 void ProcessLeftIntersectionEvent(LeftIntersectionEvent leftIntersectionEvent)
 {
     if (leftIntersectionEvent.coneLeftSide.Removed == false)
     {
         if (Math.Abs((leftIntersectionEvent.EndVertex.Point - leftIntersectionEvent.Site) * SweepDirection) <
             ApproximateComparer.DistanceEpsilon)
         {
             //the cone is totally covered by a horizontal segment
             RemoveCone(leftIntersectionEvent.coneLeftSide.Cone);
         }
         else
         {
             RemoveSegFromLeftTree(leftIntersectionEvent.coneLeftSide);
             Z = SweepDirection * leftIntersectionEvent.Site; //it is safe now to restore the order
             var leftSide = new BrokenConeSide(
                 leftIntersectionEvent.Site,
                 leftIntersectionEvent.EndVertex, leftIntersectionEvent.coneLeftSide);
             InsertToTree(leftConeSides, leftSide);
             leftIntersectionEvent.coneLeftSide.Cone.LeftSide = leftSide;
             LookForIntersectionOfObstacleSideAndLeftConeSide(leftIntersectionEvent.Site,
                                                              leftIntersectionEvent.EndVertex);
             TryCreateConeClosureForLeftSide(leftSide);
         }
     }
     else
     {
         Z = SweepDirection * leftIntersectionEvent.Site;
     }
 }
예제 #3
0
        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));
        }
예제 #4
0
        void TryIntersectionOfConeRightSideAndObstacleConeSide(ConeRightSide coneRightSide,
                                                               BrokenConeSide seg)
        {
            Point x;

            if (Point.IntervalIntersectsRay(seg.Start, seg.End, coneRightSide.Start,
                                            coneRightSide.Direction, out x))
            {
                EnqueueEvent(CreateRightIntersectionEvent(coneRightSide, x, seg.EndVertex));
                //Show(CurveFactory.CreateDiamond(3, 3, x));
            }
        }
예제 #5
0
        void TryCreateConeClosureForRightSide(BrokenConeSide rightSide)
        {
            var coneLeftSide = rightSide.Cone.LeftSide as ConeLeftSide;

            if (coneLeftSide != null)
            {
                if (
                    Point.GetTriangleOrientation(coneLeftSide.Start, coneLeftSide.Start + coneLeftSide.Direction,
                                                 rightSide.EndVertex.Point) == TriangleOrientation.Counterclockwise)
                {
                    CreateConeClosureEvent(rightSide, coneLeftSide);
                }
            }
        }
예제 #6
0
        int CompareBrokenSides(BrokenConeSide aObst, BrokenConeSide bObst)
        {
            if (aObst.EndVertex == bObst.EndVertex)
            {
                return(CompareNotIntersectingSegs(aObst.ConeSide, bObst.ConeSide));
            }

            if (Point.GetTriangleOrientation(x, bObst.Start, bObst.EndVertex.Point) ==
                TriangleOrientation.Counterclockwise)
            {
                return(-1);
            }
            return(1);
        }
예제 #7
0
        int CompareConeSideAndObstacleSide(ConeSide coneSide, BrokenConeSide brokenConeSide)
        {
            var orientation = Point.GetTriangleOrientation(x, brokenConeSide.Start, brokenConeSide.End);

            if (orientation == TriangleOrientation.Counterclockwise)
            {
                return(-1);
            }
            if (orientation == TriangleOrientation.Clockwise)
            {
                return(1);
            }

            //we have the case where x belongs to the cone side

            //      lineSweeper.Show(CurveFactory.CreateDiamond(5,5, brokenConeSide.EndVertex.Point));

            return(coneSide is ConeLeftSide ? 1 : -1);
        }
 /// <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 TryIntersectionOfConeLeftSideAndObstacleConeSide(ConeLeftSide coneLeftSide, BrokenConeSide seg) {
     Point x;
     if (Point.IntervalIntersectsRay(seg.Start, seg.End, coneLeftSide.Start, coneLeftSide.Direction, out x)) {
         EnqueueEvent(new LeftIntersectionEvent(coneLeftSide, x, seg.EndVertex));
         //Show(CurveFactory.CreateDiamond(3, 3, x));
     }
 }
 void CaseToTheLeftOfLineOrOnLineConeRp(VertexEvent rightVertexEvent, PolylinePoint nextVertex) {
     EnqueueEvent(new RightVertexEvent(nextVertex));
     //the obstacle side is inside of the cone
     //we need to create an obstacle left side segment instead of the left cone side
     var cone = new Cone(rightVertexEvent.Vertex.Point, this);
     var obstacleSideSeg = new BrokenConeSide(cone.Apex, nextVertex, new ConeLeftSide(cone));
     cone.LeftSide = obstacleSideSeg;
     cone.RightSide = new ConeRightSide(cone);
     var rnode = InsertToTree(rightConeSides, cone.RightSide);
     LookForIntersectionWithConeRightSide(rnode);
     var lnode = InsertToTree(leftConeSides, cone.LeftSide);
     FixConeLeftSideIntersections(obstacleSideSeg, lnode);
     if ((nextVertex.Point - rightVertexEvent.Site) * SweepDirection > ApproximateComparer.DistanceEpsilon)
         InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex));
 }
        void CloseConesAddConeAtLeftVertex(VertexEvent leftVertexEvent, PolylinePoint nextVertex) {
            //close segments first
            Point prevSite = leftVertexEvent.Vertex.PrevOnPolyline.Point;
            double prevZ = prevSite * SweepDirection;
            if (ApproximateComparer.Close(prevZ, Z) && (prevSite - leftVertexEvent.Site) * DirectionPerp > 0) {
                //Show(
                //    new Ellipse(1, 1, prevSite),
                //    CurveFactory.CreateBox(2, 2, leftVertexEvent.Vertex.Point));
                RemoveConesClosedBySegment(leftVertexEvent.Vertex.Point, prevSite);
            }

            var site = leftVertexEvent.Site;
            var coneLp = site + ConeLeftSideDirection;
            var coneRp = site + ConeRightSideDirection;
            var nextSite = nextVertex.Point;
            // SugiyamaLayoutSettings.Show(new LineSegment(site, coneLP), new LineSegment(site, coneRP), new LineSegment(site, nextSite));

            if ((site - prevSite) * SweepDirection > ApproximateComparer.DistanceEpsilon)
                RemoveLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex.PrevOnPolyline));
           

            var nextDelZ = GetZ(nextSite) - Z;
            if(nextDelZ<-ApproximateComparer.DistanceEpsilon)
                RemoveRightSide(new RightObstacleSide(nextVertex));

            if (nextDelZ < -ApproximateComparer.DistanceEpsilon ||
                ApproximateComparer.Close(nextDelZ, 0) && (nextSite - leftVertexEvent.Site) * DirectionPerp > 0) {
                //if (angle > Math.PI / 2)
                CreateConeOnVertex(leftVertexEvent); //it is the last left vertex on this obstacle
                
            } else if (!Point.PointToTheLeftOfLineOrOnLine(nextSite, site, coneRp)) {
                //if (angle >= coneAngle / 2) {
                CreateConeOnVertex(leftVertexEvent);
                EnqueueEvent(new LeftVertexEvent(nextVertex));
                //we schedule LeftVertexEvent for a vertex with horizontal segment to the left on the top of the obstace
            } else if (!Point.PointToTheLeftOfLineOrOnLine(nextSite, site, coneLp)) {
                //if (angle >= -coneAngle / 2) {
                //we cannot completely obscure the cone here
                EnqueueEvent(new LeftVertexEvent(nextVertex));
                //the obstacle side is inside of the cone
                //we need to create an obstacle right side segment instead of the cone side
                var cone = new Cone(leftVertexEvent.Vertex.Point, this);
                var rightSide = new BrokenConeSide(leftVertexEvent.Vertex.Point, nextVertex,
                                                   new ConeRightSide(cone));
                cone.RightSide = rightSide;
                cone.LeftSide = new ConeLeftSide(cone);
                LookForIntersectionWithConeLeftSide(InsertToTree(leftConeSides, cone.LeftSide));
                var rbNode = InsertToTree(rightConeSides, rightSide);
                FixConeRightSideIntersections(rightSide, rbNode);
                if ((nextVertex.Point - leftVertexEvent.Site) * SweepDirection > ApproximateComparer.DistanceEpsilon)
                    InsertLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex));
            } else {
                EnqueueEvent(new LeftVertexEvent(nextVertex));
                if ((nextVertex.Point - leftVertexEvent.Site) * SweepDirection > ApproximateComparer.DistanceEpsilon) {
                    //if( angle >- Pi/2
                    // Debug.Assert(angle > -Math.PI / 2);
                    LookForIntersectionOfObstacleSideAndRightConeSide(leftVertexEvent.Site, nextVertex);
                    InsertLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex));
                }
            }
        }
 void TryCreateConeClosureForRightSide(BrokenConeSide rightSide) {
     var coneLeftSide = rightSide.Cone.LeftSide as ConeLeftSide;
     if (coneLeftSide != null)
         if (
             Point.GetTriangleOrientation(coneLeftSide.Start, coneLeftSide.Start + coneLeftSide.Direction,
                                          rightSide.EndVertex.Point) == TriangleOrientation.Counterclockwise)
             CreateConeClosureEvent(rightSide, coneLeftSide);
 }
        void ProcessRightIntersectionEvent(RightIntersectionEvent rightIntersectionEvent) {
            //restore Z for the time being
            // Z = PreviousZ;
            if (rightIntersectionEvent.coneRightSide.Removed == false) {
                //it can happen that the cone side participating in the intersection is gone;
                //obstracted by another obstacle or because of a vertex found inside of the cone
                //PrintOutRightSegTree();
                RemoveSegFromRightTree(rightIntersectionEvent.coneRightSide);
                Z = SweepDirection * rightIntersectionEvent.Site;
                var rightSide = new BrokenConeSide(
                    rightIntersectionEvent.Site,
                    rightIntersectionEvent.EndVertex, rightIntersectionEvent.coneRightSide);
                InsertToTree(rightConeSides, rightSide);
                rightIntersectionEvent.coneRightSide.Cone.RightSide = rightSide;
                LookForIntersectionOfObstacleSideAndRightConeSide(rightIntersectionEvent.Site,
                                                                  rightIntersectionEvent.EndVertex);

                TryCreateConeClosureForRightSide(rightSide);
            } else
                Z = SweepDirection * rightIntersectionEvent.Site;
        }
        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));
        }
 void ProcessLeftIntersectionEvent(LeftIntersectionEvent leftIntersectionEvent) {
     if (leftIntersectionEvent.coneLeftSide.Removed == false) {
         if (Math.Abs((leftIntersectionEvent.EndVertex.Point - leftIntersectionEvent.Site) * SweepDirection) <
             ApproximateComparer.DistanceEpsilon) {
             //the cone is totally covered by a horizontal segment
             RemoveCone(leftIntersectionEvent.coneLeftSide.Cone);
         } else {
             RemoveSegFromLeftTree(leftIntersectionEvent.coneLeftSide);
             Z = SweepDirection * leftIntersectionEvent.Site; //it is safe now to restore the order
             var leftSide = new BrokenConeSide(
                 leftIntersectionEvent.Site,
                 leftIntersectionEvent.EndVertex, leftIntersectionEvent.coneLeftSide);
             InsertToTree(leftConeSides, leftSide);
             leftIntersectionEvent.coneLeftSide.Cone.LeftSide = leftSide;
             LookForIntersectionOfObstacleSideAndLeftConeSide(leftIntersectionEvent.Site,
                                                              leftIntersectionEvent.EndVertex);
             TryCreateConeClosureForLeftSide(leftSide);
         }
     } else
         Z = SweepDirection * leftIntersectionEvent.Site;
 }
 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));
 }