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 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); } }