void RemoveCone(Cone cone)
 {
     Debug.Assert(cone.Removed == false);
     cone.Removed = true;
     RemoveSegFromLeftTree(cone.LeftSide);
     RemoveSegFromRightTree(cone.RightSide);
 }
        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);
        }
 internal ConeRightSide(Cone cone)
 {
     this.Cone = cone;
 }
        PolylinePoint GetPolylinePointInsideOfConeAndRemoveCones(PolylinePoint p, Cone cone) {
            var pn = p.NextOnPolyline;
            Point insidePoint = FindInsidePoint(p.Point, pn.Point, cone);

            if (ApproximateComparer.Close(insidePoint, p.Point)) {
                AddEdgeAndRemoveCone(cone, p.Point);
                AddEdgesAndRemoveRemainingConesByPoint(p.Point);
                //we don't move p forward here. In the next iteration we just cross [p,pn] with the new leftmost cone right side
            } else if (ApproximateComparer.Close(insidePoint, pn.Point)) {
                AddEdgeAndRemoveCone(cone, pn.Point);
                AddEdgesAndRemoveRemainingConesByPoint(pn.Point);
                p = pn;
            } else {
                p = InsertPointIntoPolylineAfter(BorderPolyline, p, insidePoint);
                AddEdgeAndRemoveCone(cone, p.Point);
                AddEdgesAndRemoveRemainingConesByPoint(p.Point);
            }
            return p;
        }
        void CreateConeOnVertex(SweepEvent sweepEvent) {
            var cone = new Cone(sweepEvent.Site, this);
#if SHARPKIT //http://code.google.com/p/sharpkit/issues/detail?id=368
            //SharpKit/Colin - property assignment values not retained
            cone.LeftSide = new ConeLeftSide(cone);
            cone.RightSide = new ConeRightSide(cone);

            var leftNode = InsertToTree(leftConeSides, cone.LeftSide);
            var rightNode = InsertToTree(rightConeSides, cone.RightSide);
#else
            var leftNode = InsertToTree(leftConeSides, cone.LeftSide = new ConeLeftSide(cone));
            var rightNode = InsertToTree(rightConeSides, cone.RightSide = new ConeRightSide(cone));
#endif       
            LookForIntersectionWithConeRightSide(rightNode);
            LookForIntersectionWithConeLeftSide(leftNode);
        }
 void RemoveCone(Cone cone)
 {
     // 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(cone.Removed == false);
     cone.Removed = true;
     RemoveSegFromLeftTree(cone.LeftSide);
     RemoveSegFromRightTree(cone.RightSide);
 }
        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 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);
 }
 void AddEdgeAndRemoveCone(Cone cone, Point p) {
     if (Ports != null && Ports.Contains(cone.Apex))
         CreatePortEdge(cone, p);
     else
         visibilityGraph.AddEdge(cone.Apex, p);
     RemoveCone(cone);
 }
 PolylinePoint FindPolylineSideIntersectingConeRightSide(PolylinePoint p, Cone cone) {
     var startPoint = p;
     var a = cone.Apex;
     var b = cone.Apex + ConeRightSideDirection;
     var pSign = GetSign(p, a, b);
     do {
         var pn = p.NextOnPolyline;
         var pnSigh = GetSign(pn, a, b);
         if (pnSigh - pSign > 0)
             return p;
         p = pn;
         pSign = pnSigh;
         if (p == startPoint)
             throw new InvalidOperationException();
     } while (true);
     /*
                 throw new InvalidOleVariantTypeException();
     */
 }
 static Point FindInsidePoint(Point leftPoint, Point rightPoint, Cone cone) {
     //            if (debug)
     //                LayoutAlgorithmSettings.Show(CurveFactory.CreateCircle(3, leftPoint),
     //                                             CurveFactory.CreateDiamond(3, 3, rightPoint),
     //                                             BorderPolyline, ExtendSegmentToZ(cone.LeftSide),
     //                                             ExtendSegmentToZ(cone.RightSide));
     return FindInsidePointBool(leftPoint, rightPoint, cone.Apex, cone.Apex + cone.LeftSideDirection,
                                cone.Apex + cone.RightSideDirection);
 }
 internal ConeClosureEvent(Point site, Cone cone) {
     this.site = site;
     this.coneToClose = cone;
 }
 internal ConeClosureEvent(Point site, Cone cone)
 {
     this.site        = site;
     this.coneToClose = cone;
 }
 internal ConeRightSide(Cone cone) {
     this.Cone = cone; 
 }
 void RemoveCone(Cone cone) {
     Debug.Assert(cone.Removed == false);
     cone.Removed = true;
     RemoveSegFromLeftTree(cone.LeftSide);
     RemoveSegFromRightTree(cone.RightSide);
 }
Exemple #16
0
 internal ConeLeftSide(Cone cone)
 {
     Cone = cone;
 }
        /*********************
            A complication arises when we have overlaps. Loose obstacles become large enough to contain several
            ports. We need to avoid a situation when a port has degree more than one. 
            To avoid this situation we redirect to p every edge incoming into cone.Apex. 
            Notice that we create a new graph to keep port edges for ever 
            direction of the sweep and the above procedure just alignes the edges better.
            In the resulting graph, which contains the sum of the graphs passed to AddDirection, of course
            a port can have an incoming and outcoming edge at the same time
            *******************/

        void CreatePortEdge(Cone cone, Point p) {
            if (portEdgesGraph == null) portEdgesGraph = new VisibilityGraph();
            var coneApexVert = portEdgesGraph.FindVertex(cone.Apex);
            //all previous edges adjacent to cone.Apex 
            var edgesToFix = (coneApexVert != null)
                                 ? coneApexVert.InEdges.Concat(coneApexVert.OutEdges).ToArray()
                                 : null;
            if (edgesToFix != null)
                foreach (var edge in edgesToFix) {
                    var otherPort = (edge.Target == coneApexVert ? edge.Source : edge.Target).Point;
                    VisibilityGraph.RemoveEdge(edge);
                    portEdgesGraph.AddEdge(otherPort, p);
                }
            portEdgesGraph.AddEdge(cone.Apex, p);
        }
 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));
 }
        //        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);
            }
        }
 internal ConeLeftSide(Cone cone) { Cone = cone; }