void CloseConesAtRightVertex(VertexEvent rightVertexEvent, PolylinePoint nextVertex) { Point prevSite = rightVertexEvent.Vertex.NextOnPolyline.Point; double prevZ = prevSite * SweepDirection; if (prevZ <= Z && Z - prevZ < ApproximateComparer.DistanceEpsilon) { RemoveConesClosedBySegment(prevSite, rightVertexEvent.Vertex.Point); } Point site = rightVertexEvent.Site; Point coneLp = site + ConeLeftSideDirection; Point coneRp = site + ConeRightSideDirection; Point nextSite = nextVertex.Point; //SugiyamaLayoutSettings.Show(new LineSegment(site, coneLP), new LineSegment(site, coneRP), new LineSegment(site, nextSite)); //try to remove the right side if ((site - prevSite) * SweepDirection > ApproximateComparer.DistanceEpsilon) { RemoveRightSide(new RightObstacleSide(rightVertexEvent.Vertex.NextOnPolyline)); } if (GetZ(nextSite) + ApproximateComparer.DistanceEpsilon < GetZ(rightVertexEvent)) { return; } if (!Point.PointToTheRightOfLineOrOnLine(nextSite, site, coneLp)) { //if (angle <= -coneAngle / 2) { // CreateConeOnVertex(rightVertexEvent); if (Point.PointToTheLeftOfLineOrOnLine(nextSite + DirectionPerp, nextSite, site)) { EnqueueEvent(new RightVertexEvent(nextVertex)); } // TryEnqueueRighVertexEvent(nextVertex); } else if (Point.PointToTheLeftOfLineOrOnLine(nextSite, site, coneRp)) { //if (angle < coneAngle / 2) { CaseToTheLeftOfLineOrOnLineConeRp(rightVertexEvent, nextVertex); } else { if ((nextSite - site) * SweepDirection > ApproximateComparer.DistanceEpsilon) { LookForIntersectionOfObstacleSideAndLeftConeSide(rightVertexEvent.Site, nextVertex); InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex)); } EnqueueEvent(new RightVertexEvent(nextVertex)); } }
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); RBNode <ConeSide> lnode = leftConeSides.FindFirst(side => PointIsToTheLeftOfSegment(rightVertexEvent.Site, side)); FixConeLeftSideIntersections(rightVertexEvent.Vertex, nextVertex, lnode); if ((nextVertex.Point - rightVertexEvent.Site) * SweepDirection > ApproximateComparer.DistanceEpsilon) { InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex)); } }
void AddConeAndEnqueueEvents(VertexEvent vertexEvent) { var leftVertexEvent = vertexEvent as LeftVertexEvent; if (leftVertexEvent != null) { PolylinePoint nextPoint = vertexEvent.Vertex.NextOnPolyline; CloseConesAtLeftVertex(leftVertexEvent, nextPoint); } else { var rightVertexEvent = vertexEvent as RightVertexEvent; if (rightVertexEvent != null) { PolylinePoint nextPoint = vertexEvent.Vertex.PrevOnPolyline; CloseConesAtRightVertex(rightVertexEvent, nextPoint); } else { CloseConesAtLeftVertex(vertexEvent, vertexEvent.Vertex.NextOnPolyline); CloseConesAtRightVertex(vertexEvent, vertexEvent.Vertex.PrevOnPolyline); } } }
void CloseConesAtLeftVertex(VertexEvent leftVertexEvent, PolylinePoint nextVertex) { //close segments first Point prevSite = leftVertexEvent.Vertex.PrevOnPolyline.Point; double prevZ = prevSite * SweepDirection; if (prevZ <= Z && Z - prevZ < ApproximateComparer.DistanceEpsilon) { //Show( // new Ellipse(1, 1, prevSite), // CurveFactory.CreateBox(2, 2, leftVertexEvent.Vertex.Point)); RemoveConesClosedBySegment(leftVertexEvent.Vertex.Point, prevSite); } Point site = leftVertexEvent.Site; Point coneLp = site + ConeLeftSideDirection; Point coneRp = site + ConeRightSideDirection; Point 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)); } if (Point.PointToTheRightOfLineOrOnLine(nextSite, site, site + DirectionPerp)) { //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)); RBNode <ConeSide> rbNode = rightConeSides.FindLast(s => PointIsToTheRightOfSegment(site, s)); FixConeRightSideIntersections(leftVertexEvent.Vertex, nextVertex, 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 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 ProcessVertexEvent(VertexEvent vertexEvent) { Z = GetZ(vertexEvent); GoOverConesSeeingVertexEvent(vertexEvent); AddConeAndEnqueueEvents(vertexEvent); }
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 CloseConesAddConeAtRightVertex(VertexEvent rightVertexEvent, PolylinePoint nextVertex) { var prevSite = rightVertexEvent.Vertex.NextOnPolyline.Point; var prevZ = prevSite*SweepDirection; if (ApproximateComparer.Close(prevZ, Z)) RemoveConesClosedBySegment(prevSite, rightVertexEvent.Vertex.Point); var site = rightVertexEvent.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)); //try to remove the right side if ((site - prevSite)*SweepDirection > ApproximateComparer.DistanceEpsilon) RemoveRightSide(new RightObstacleSide(rightVertexEvent.Vertex.NextOnPolyline)); if ((site - nextVertex.Point) * SweepDirection > ApproximateComparer.DistanceEpsilon) RemoveLeftSide(new LeftObstacleSide(nextVertex)); if (GetZ(nextSite) + ApproximateComparer.DistanceEpsilon < GetZ(rightVertexEvent)) CreateConeOnVertex(rightVertexEvent); if (!Point.PointToTheRightOfLineOrOnLine(nextSite, site, coneLp)) { //if (angle <= -coneAngle / 2) { CreateConeOnVertex(rightVertexEvent); if (Point.PointToTheLeftOfLineOrOnLine(nextSite + DirectionPerp, nextSite, site)) EnqueueEvent(new RightVertexEvent(nextVertex)); // TryEnqueueRighVertexEvent(nextVertex); } else if (Point.PointToTheLeftOfLineOrOnLine(nextSite, site, coneRp)) //if (angle < coneAngle / 2) { CaseToTheLeftOfLineOrOnLineConeRp(rightVertexEvent, nextVertex); else { if ((nextSite - site)*SweepDirection > ApproximateComparer.DistanceEpsilon) { LookForIntersectionOfObstacleSideAndLeftConeSide(rightVertexEvent.Site, nextVertex); InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex)); } EnqueueEvent(new RightVertexEvent(nextVertex)); } }
void AddConeAndEnqueueEvents(VertexEvent vertexEvent) { var leftVertexEvent = vertexEvent as LeftVertexEvent; if (leftVertexEvent != null) { PolylinePoint nextPoint = vertexEvent.Vertex.NextOnPolyline; CloseConesAddConeAtLeftVertex(leftVertexEvent, nextPoint); } else { var rightVertexEvent = vertexEvent as RightVertexEvent; if (rightVertexEvent != null) { PolylinePoint nextPoint = vertexEvent.Vertex.PrevOnPolyline; CloseConesAddConeAtRightVertex(rightVertexEvent, nextPoint); } else { CloseConesAddConeAtLeftVertex(vertexEvent, vertexEvent.Vertex.NextOnPolyline); CloseConesAddConeAtRightVertex(vertexEvent, vertexEvent.Vertex.PrevOnPolyline); } } }
void ProcessVertexEvent(VertexEvent vertexEvent) { // if (count == 872 && (vertexEvent.Site - new Point(-130.7368, -305.908)).Length < 1) // Show(EllipseOnVert(vertexEvent)); Z = GetZ(vertexEvent); //PrintOutLeftSegTree(); //PrintOutRightSegTree(); GoOverConesSeeingVertexEvent(vertexEvent); AddConeAndEnqueueEvents(vertexEvent); }
void ProcessVertexEvent(VertexEvent vertexEvent) { Z = GetZ(vertexEvent); GoOverConesSeeingVertexEvent(vertexEvent); AddConeAndEnqueueEvents(vertexEvent); }