public EdgeInserter(CdtEdge edge, Set <CdtTriangle> triangles, RbTree <CdtFrontElement> front, Func <CdtSite, CdtSite, CdtEdge> createEdgeDelegate) { this.edge = edge; this.triangles = triangles; this.front = front; this.createEdgeDelegate = createEdgeDelegate; }
PerimeterEdge CreateDoubleLinkedListOfPerimeter() { CdtEdge firstEdge = this.triangles.SelectMany(t => t.Edges).FirstOrDefault(e => e.CwTriangle == null || e.CcwTriangle == null); var edge = firstEdge; PerimeterEdge pe, prevPe = null, listStart = null; do { pe = CreatePerimeterElementFromEdge(edge); edge = FindNextEdgeOnPerimeter(edge); if (prevPe != null) { pe.Prev = prevPe; prevPe.Next = pe; } else { listStart = pe; } prevPe = pe; } while (edge != firstEdge); listStart.Prev = pe; pe.Next = listStart; return(listStart); }
void StepFromEdgeInteriorPoint(CdtEdge edge) { var triangle = GetTriangleOnThePointSide(edge, segEnd.Point); if (triangle == null) { lastCrossedFeature = OutsideOfTriangulation; return; } if (PointBelongsToInteriorOfTriangle(segEnd.Point, triangle)) { lastCrossedFeature = triangle; return; } //we cross an edge for (int i = 0; i < 3; i++) { if (triangle.Edges[i] == edge) { continue; } if (PointIsInsideCone(segEnd.Point, segStart.Point, triangle.Sites[i + 1].Point, triangle.Sites[i].Point)) { CrossTriangleEdge(triangle.Edges[i]); return; } } }
static CdtTriangle GetTriangleOnThePointSide(CdtEdge edge, Point p) { return(Point.GetTriangleOrientation(edge.upperSite.Point, edge.lowerSite.Point, p) == TriangleOrientation.Counterclockwise ? edge.CcwTriangle : edge.CwTriangle); }
internal static bool EdgeIsPierced(CdtEdge e, Point source, Point target, CdtTriangle cdtTriangle) { var area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, source, target); var area1 = Point.SignedDoubledTriangleArea(e.lowerSite.Point, source, target); if (ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) > 0) { return(false); } area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, source); area1 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, target); if (ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) > 0) { return(false); } var otherT = e.GetOtherTriangle(cdtTriangle); if (otherT == null) { return(true); } var otherSite = otherT.OppositeSite(e); area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, otherSite.Point); return(ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) >= 0); }
void LegalizeEdgeForOtherCwTriangle(CdtSite pi, CdtEdge edge) { var i = edge.CwTriangle.Edges.Index(edge); // if (i == -1) // { // List<DebugCurve> ls = new List<DebugCurve>(); // ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); // for (int j = 0; j < 3; j++) // { // var ee = edge.CwTriangle.Edges[j]; // ls.Add(new DebugCurve(100,1, j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point))); // } // ls.Add(new DebugCurve("purple", new LineSegment(edge.upperSite.Point, edge.lowerSite.Point))); // // LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); // } Debug.Assert(i >= 0); if (IsIllegal(pi, edge.upperSite, edge.CwTriangle.Sites[i + 2], edge.lowerSite)) { //ShowIllegalEdge(edge, i, pi); CdtEdge e = Flip(pi, edge); LegalizeEdge(pi, e.CwTriangle.OppositeEdge(pi)); LegalizeEdge(pi, e.CcwTriangle.OppositeEdge(pi)); } }
bool EdgeSeparationIsOk(CdtEdge edge, Set <EdgeGeometry> paths, double separation) { double requiredWidth = paths.Select(v => v.LineWidth).Sum() + (paths.Count - 1) * separation; double availableWidth = edge.Capacity; return(requiredWidth <= availableWidth); }
internal CdtFrontElement(CdtSite leftSite, CdtEdge edge) { Debug.Assert(edge.upperSite.Point.X != edge.lowerSite.Point.X && edge.upperSite.Point.X < edge.lowerSite.Point.X && leftSite == edge.upperSite || edge.upperSite.Point.X > edge.lowerSite.Point.X && leftSite == edge.lowerSite); RightSite = edge.upperSite == leftSite ? edge.lowerSite : edge.upperSite; LeftSite = leftSite; Edge = edge; }
static DebugCurve GetDebugCurveOfCdtEdge(CdtEdge e) { if (e.CcwTriangle == null || e.CwTriangle == null) { return(new DebugCurve(255, 4, e.Constrained ? "brown" : "blue", new LineSegment(e.upperSite.Point, e.lowerSite.Point))); } return(new DebugCurve(100, e.Constrained?0.002:0.001, e.Constrained?"pink":"navy", new LineSegment(e.upperSite.Point, e.lowerSite.Point))); }
static DebugCurve GetDebugCurveOfCdtEdge(CdtEdge e) { if (e.CcwTriangle == null || e.CwTriangle == null) { return(new DebugCurve(100, 0.5, e.Constrained ? "pink" : "rose", new LineSegment(e.upperSite.Point, e.lowerSite.Point))); } return(new DebugCurve(100, e.Constrained?0.002:0.001, e.Constrained?"violet":"yellow", new LineSegment(e.upperSite.Point, e.lowerSite.Point))); }
bool RealCrossing(CdtEdge cdtEdge) { var segEndOrientation = Point.GetTriangleOrientation(segEnd.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); var segStartOrientation = Point.GetTriangleOrientation(segStart.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); return(segStartOrientation != TriangleOrientation.Collinear && segStartOrientation != segEndOrientation || SomePreviousPointIsOnOtherSiteOfEdge(cdtEdge, segEndOrientation)); }
public EdgeTracer(CdtEdge edge, Set<CdtTriangle> triangles, RbTree<CdtFrontElement> front, List<CdtSite> leftPolygon, List<CdtSite> rightPolygon) { this.edge = edge; this.triangles = triangles; this.front = front; this.leftPolygon = leftPolygon; this.rightPolygon = rightPolygon; a = edge.upperSite; b = edge.lowerSite; }
internal CdtFrontElement(CdtSite leftSite, CdtEdge edge) { Debug.Assert(edge.upperSite.Point.X != edge.lowerSite.Point.X && edge.upperSite.Point.X <edge.lowerSite.Point.X && leftSite == edge.upperSite || edge.upperSite.Point.X> edge.lowerSite.Point.X && leftSite == edge.lowerSite); RightSite = edge.upperSite == leftSite ? edge.lowerSite : edge.upperSite; LeftSite = leftSite; Edge = edge; }
bool RealCrossing(CdtEdge cdtEdge) { var segEndOrientation = Point.GetTriangleOrientation(segEnd.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); var segStartOrientation = Point.GetTriangleOrientation(segStart.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); return segStartOrientation != TriangleOrientation.Collinear && segStartOrientation != segEndOrientation || SomePreviousPointIsOnOtherSiteOfEdge(cdtEdge, segEndOrientation); }
bool SomePreviousPointIsOnOtherSiteOfEdge(CdtEdge cdtEdge, TriangleOrientation segEndOrientation) { foreach (PolylinePoint polylinePoint in polylineHead) { var orientation = Point.GetTriangleOrientation(polylinePoint.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); if (orientation != TriangleOrientation.Collinear) return orientation != segEndOrientation; } return false; }
public EdgeTracer(CdtEdge edge, Set <CdtTriangle> triangles, RbTree <CdtFrontElement> front, List <CdtSite> leftPolygon, List <CdtSite> rightPolygon) { this.edge = edge; this.triangles = triangles; this.front = front; this.leftPolygon = leftPolygon; this.rightPolygon = rightPolygon; a = edge.upperSite; b = edge.lowerSite; }
/// <summary> /// in the trianlge, which is always oriented counterclockwise, the edge starts at site /// </summary> /// <param name="site"></param> /// <param name="edge"></param> void BindEdgeToTriangle(CdtSite site, CdtEdge edge) { if (site == edge.upperSite) { edge.CcwTriangle = this; } else { edge.CwTriangle = this; } }
void LegalizeEdgeForOtherCcwTriangle(CdtSite pi, CdtEdge edge) { var i = edge.CcwTriangle.Edges.Index(edge); if (IsIllegal(pi, edge.lowerSite, edge.CcwTriangle.Sites[i + 2], edge.upperSite)) { CdtEdge e = Flip(pi, edge); LegalizeEdge(pi, e.CwTriangle.OppositeEdge(pi)); LegalizeEdge(pi, e.CcwTriangle.OppositeEdge(pi)); } }
// internal CdtTriangle(CdtSite aLeft, CdtSite aRight, CdtSite bRight, CdtEdge a, CdtEdge b, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) { // Debug.Assert(Point.GetTriangleOrientation(aLeft.Point, aRight.Point, bRight.Point) == TriangleOrientation.Counterclockwise); Sites[0] = aLeft; Sites[1] = aRight; Sites[2] = bRight; Edges[0] = a; Edges[1] = b; BindEdgeToTriangle(aLeft, a); BindEdgeToTriangle(aRight, b); CreateEdge(2, createEdgeDelegate); }
void TryInsertEdge(CdtEdge e) { if (crossedEdges.Contains(e)) { return; } if (e.upperSite.Owner != e.lowerSite.Owner && RealCrossing(e)) { crossedEdges.Insert(e); } }
void EdgeEvent(CdtEdge edge) { Debug.Assert(edge.Constrained); if (EdgeIsProcessed(edge)) { return; } var edgeInserter = new EdgeInserter(edge, Triangles, front, createEdgeDelegate); edgeInserter.Run(); }
static CdtEdge FindNextEdgeOnPerimeter(CdtEdge e) { var t = e.CwTriangle ?? e.CcwTriangle; e = t.Edges[t.Edges.Index(e) + 2]; while (e.CwTriangle != null && e.CcwTriangle != null) { t = e.GetOtherTriangle(t); e = t.Edges[t.Edges.Index(e) + 2]; } return(e); }
// internal CdtTriangle(CdtSite aLeft, CdtSite aRight, CdtSite bRight, CdtEdge a, CdtEdge b, Func <CdtSite, CdtSite, CdtEdge> createEdgeDelegate) { // Debug.Assert(Point.GetTriangleOrientation(aLeft.Point, aRight.Point, bRight.Point) == TriangleOrientation.Counterclockwise); Sites[0] = aLeft; Sites[1] = aRight; Sites[2] = bRight; Edges[0] = a; Edges[1] = b; BindEdgeToTriangle(aLeft, a); BindEdgeToTriangle(aRight, b); CreateEdge(2, createEdgeDelegate); }
void ShowIllegalEdge(CdtEdge edge, int i, CdtSite pi) { List <DebugCurve> ls = new List <DebugCurve>(); ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); for (int j = 0; j < 3; j++) { var ee = edge.CwTriangle.Edges[j]; ls.Add(new DebugCurve(j == i?"red":"blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point))); } LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); }
internal bool MoveNext() { if (currentPiercedEdge == null) { currentPiercedEdge = FindFirstPiercedEdge(); } else { FindNextPierced(); } return(currentPiercedEdge != null); }
bool SomePreviousPointIsOnOtherSiteOfEdge(CdtEdge cdtEdge, TriangleOrientation segEndOrientation) { foreach (PolylinePoint polylinePoint in polylineHead) { var orientation = Point.GetTriangleOrientation(polylinePoint.Point, cdtEdge.upperSite.Point, cdtEdge.lowerSite.Point); if (orientation != TriangleOrientation.Collinear) { return(orientation != segEndOrientation); } } return(false); }
List <DebugCurve> ShowIllegalEdge(CdtEdge edge, CdtSite pi, int i) { List <DebugCurve> ls = new List <DebugCurve>(); ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); for (int j = 0; j < 3; j++) { var ee = edge.CcwTriangle.Edges[j]; ls.Add(new DebugCurve(j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point))); } ls.Add(new DebugCurve(100, 1, "black", Circumcircle(edge.CcwTriangle.Sites[0].Point, edge.CcwTriangle.Sites[1].Point, edge.CcwTriangle.Sites[2].Point))); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); return(ls); }
static PerimeterEdge CreatePerimeterElementFromEdge(CdtEdge edge) { var pe = new PerimeterEdge(edge); if (edge.CwTriangle != null) { pe.Start = edge.upperSite; pe.End = edge.lowerSite; } else { pe.End = edge.upperSite; pe.Start = edge.lowerSite; } return(pe); }
void LegalizeEdge(CdtSite pi, CdtEdge edge) { Debug.Assert(pi != edge.upperSite && pi != edge.lowerSite); if (edge.Constrained || edge.CcwTriangle == null || edge.CwTriangle == null) { return; } if (edge.CcwTriangle.Contains(pi)) { LegalizeEdgeForOtherCwTriangle(pi, edge); } else { LegalizeEdgeForOtherCcwTriangle(pi, edge); } }
void FindPiercedTriangle(RBNode <CdtFrontElement> v) { var e = v.Item.Edge; var t = e.CcwTriangle ?? e.CwTriangle; var eIndex = t.Edges.Index(e); for (int i = 1; i <= 2; i++) { var ei = t.Edges[i + eIndex]; var signedArea0 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(ei.lowerSite.Point, a.Point, b.Point)); var signedArea1 = ApproximateComparer.Sign(Point.SignedDoubledTriangleArea(ei.upperSite.Point, a.Point, b.Point)); if (signedArea1 * signedArea0 <= 0) { piercedTriangle = t; piercedEdge = ei; break; } } }
static void CalculateCdtEdgeCapacityForEdge(CdtEdge e) { if (e.Constrained || e.CwTriangle == null || e.CcwTriangle == null) { return; //this is a convex hull edge or an obstacle edge } var startPoly = e.upperSite.Owner as Polyline; var endPoly = e.lowerSite.Owner as Polyline; if (startPoly != endPoly) { //e.Capacity = Polygon.Distance(new Polygon(startPoly), new Polygon(endPoly)); //todo: cache this //e.Capacity = (e.upperSite.Point - e.lowerSite.Point).Length; double distA = Polygon.Distance(new Polygon(startPoly), e.lowerSite.Point); double distB = Polygon.Distance(new Polygon(endPoly), e.upperSite.Point); e.Capacity = (distA + distB) / 2; } //else - it is a diagonal of an obstacle, do not care }
void Init() { // if (CdtSweeper.D) // CdtSweeper.ShowFront(triangles, front, new[] {new LineSegment(a.Point, b.Point)},null); //new[] {new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point)}); var frontElemNodeRightOfA = CdtSweeper.FindNodeInFrontBySite(front, a); var frontElemNodeLeftOfA = front.Previous(frontElemNodeRightOfA); if (Point.PointToTheLeftOfLine(b.Point, frontElemNodeLeftOfA.Item.LeftSite.Point, frontElemNodeLeftOfA.Item.RightSite.Point)) { piercedToTheLeftFrontElemNode = frontElemNodeLeftOfA; } else if (Point.PointToTheRightOfLine(b.Point, frontElemNodeRightOfA.Item.RightSite.Point, frontElemNodeRightOfA.Item.LeftSite.Point)) { piercedToTheRightFrontElemNode = frontElemNodeRightOfA; } else { foreach (var e in a.Edges) { var t = e.CcwTriangle; if (t == null) { continue; } if (Point.PointToTheLeftOfLine(b.Point, e.lowerSite.Point, e.upperSite.Point)) { continue; } var eIndex = t.Edges.Index(e); var site = t.Sites[eIndex + 2]; if (Point.PointToTheLeftOfLineOrOnLine(b.Point, site.Point, e.upperSite.Point)) { piercedEdge = t.Edges[eIndex + 1]; piercedTriangle = t; // CdtSweeper.ShowFront(triangles, front, new[] { new LineSegment(e.upperSite.Point, e.lowerSite.Point) }, // new[] { new LineSegment(piercedEdge.upperSite.Point, piercedEdge.lowerSite.Point) }); break; } } } }
CdtTriangle FindFirstPiercedTriangle(CdtSite startSite, Point target, out CdtEdge piercedEdge) { if (startSite != null) { foreach (var t in startSite.Triangles) { piercedEdge = GetPiercedEdgeInSiteTriangle(t, startSite, target); if (piercedEdge != null) { if (!PointIsInsideOfTriangle(target, t)) { return(t); } } } } piercedEdge = null; return(null); }
internal CdtTriangle(CdtSite pi, CdtEdge edge, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) { switch (Point.GetTriangleOrientationWithNoEpsilon(edge.upperSite.Point, edge.lowerSite.Point, pi.Point)) { case TriangleOrientation.Counterclockwise: edge.CcwTriangle = this; Sites[0] = edge.upperSite; Sites[1] = edge.lowerSite; break; case TriangleOrientation.Clockwise: edge.CwTriangle = this; Sites[0] = edge.lowerSite; Sites[1] = edge.upperSite; break; default: throw new InvalidOperationException(); } Edges[0] = edge; Sites[2] = pi; CreateEdge(1, createEdgeDelegate); CreateEdge(2, createEdgeDelegate); }
void CrossTriangleEdge(CdtEdge e) { TryInsertEdge(e); if (Point.GetTriangleOrientation(segStart.Point, e.upperSite.Point, segEnd.Point) == TriangleOrientation.Collinear) { lastCrossedFeature = e.upperSite; // PickupEdgesOfSite(e.upperSite); } else if (Point.GetTriangleOrientation(segStart.Point, e.lowerSite.Point, segEnd.Point) == TriangleOrientation.Collinear) { lastCrossedFeature = e.lowerSite; // PickupEdgesOfSite(e.lowerSite); } else { lastCrossedFeature = e; } }
Set <CdtEdge> ThreadBoneEdgeThroughCdt(SdBoneEdge boneEdge) { var start = boneEdge.SourcePoint; var currentTriangle = boneEdge.Source.Triangle; Debug.Assert(Cdt.PointIsInsideOfTriangle(start, currentTriangle)); var crossedEdges = new Set <CdtEdge>(); var end = boneEdge.TargetPoint; if (Cdt.PointIsInsideOfTriangle(end, currentTriangle)) { return(crossedEdges); } var threader = new CdtThreader(currentTriangle, start, end); while (threader.MoveNext()) { CdtEdge piercedEdge = threader.CurrentPiercedEdge; Debug.Assert(piercedEdge != null); if (Gates.Contains(piercedEdge)) { crossedEdges.Insert(piercedEdge); } } /* * CdtEdge piercedEdge = CdtIntersections.FindFirstPiercedEdge(currentTriangle, start, end, out negativeSign, out positiveSign, this.Cdt ); * Debug.Assert(piercedEdge != null); * * do { * if (Gates.Contains(piercedEdge)) * crossedEdges.Insert(piercedEdge); * } * while (CdtIntersections.FindNextPierced(start, end, ref currentTriangle, ref piercedEdge, ref negativeSign, ref positiveSign)); */ //if(ddd(boneEdge)) //CdtSweeper.ShowFront(Cdt.GetTriangles(),null,new []{new LineSegment(boneEdge.SourcePoint,boneEdge.TargetPoint)}, crossedEdges.Select(e=>new LineSegment(e.upperSite.Point,e.lowerSite.Point))); return(crossedEdges); }
bool EdgeSeparationIsOk(CdtEdge edge, Set<EdgeGeometry> paths, double separation) { double requiredWidth = paths.Select(v => v.LineWidth).Sum() + (paths.Count - 1) * separation; double availableWidth = edge.Capacity; return (requiredWidth <= availableWidth); }
static CdtEdge FindNextEdgeOnPerimeter(CdtEdge e) { var t = e.CwTriangle ?? e.CcwTriangle; e = t.Edges[t.Edges.Index(e) + 2]; while(e.CwTriangle != null && e.CcwTriangle != null) { t = e.GetOtherTriangle(t); e = t.Edges[t.Edges.Index(e) + 2]; } return e; }
void LegalizeEdge(CdtSite pi, CdtEdge edge) { Debug.Assert(pi!=edge.upperSite && pi!=edge.lowerSite); if (edge.Constrained || edge.CcwTriangle == null || edge.CwTriangle == null) return; if (edge.CcwTriangle.Contains(pi)) LegalizeEdgeForOtherCwTriangle(pi, edge); else LegalizeEdgeForOtherCcwTriangle(pi, edge); }
double SavedCapacityPenaltyOnCdtEdge(CdtEdge cdtEdge, EdgeGeometry edgeGeometry) { if (cdtEdge.ResidualCapacity > 0) return 0; double savedDelta; double width = edgeGeometry.LineWidth; if (cdtEdge.ResidualCapacity == cdtEdge.Capacity - width) savedDelta = width; else savedDelta = width + bundlingSettings.EdgeSeparation; if (savedDelta > -cdtEdge.ResidualCapacity) savedDelta = -cdtEdge.ResidualCapacity; return savedDelta * SdShortestPath.CapacityOverflowPenaltyMultiplier(bundlingSettings); }
/// <summary> /// in the trianlge, which is always oriented counterclockwise, the edge starts at site /// </summary> /// <param name="site"></param> /// <param name="edge"></param> void BindEdgeToTriangle(CdtSite site, CdtEdge edge) { if (site == edge.upperSite) edge.CcwTriangle = this; else edge.CwTriangle = this; }
public EdgeInserter(CdtEdge edge, Set<CdtTriangle> triangles, RbTree<CdtFrontElement> front, Func<CdtSite, CdtSite, CdtEdge> createEdgeDelegate) { this.edge = edge; this.triangles = triangles; this.front = front; this.createEdgeDelegate = createEdgeDelegate; }
IEnumerable<CdtEdge> ThreadThroughTriangles(Point start, Point end, CdtTriangle triangle, CdtEdge piercedEdge) { var ret = new List<CdtEdge>(); do { if (piercedEdge.upperSite.Owner != piercedEdge.lowerSite.Owner) ret.Add(piercedEdge); } while (FindNextPierced(start, end, ref triangle, ref piercedEdge)); return ret; }
void EdgeEvent(CdtEdge edge) { Debug.Assert(edge.Constrained); if(EdgeIsProcessed(edge)) return; var edgeInserter = new EdgeInserter(edge, Triangles, front, createEdgeDelegate); edgeInserter.Run(); }
void LegalizeEdgeForOtherCwTriangle(CdtSite pi, CdtEdge edge) { var i=edge.CwTriangle.Edges.Index(edge); // if (i == -1) // { // List<DebugCurve> ls = new List<DebugCurve>(); // ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); // for (int j = 0; j < 3; j++) // { // var ee = edge.CwTriangle.Edges[j]; // ls.Add(new DebugCurve(100,1, j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point))); // } // ls.Add(new DebugCurve("purple", new LineSegment(edge.upperSite.Point, edge.lowerSite.Point))); // // LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); // } Debug.Assert(i>=0); if (IsIllegal(pi, edge.upperSite, edge.CwTriangle.Sites[i + 2], edge.lowerSite)) { //ShowIllegalEdge(edge, i, pi); CdtEdge e = Flip(pi, edge); LegalizeEdge(pi, e.CwTriangle.OppositeEdge(pi) ); LegalizeEdge(pi, e.CcwTriangle.OppositeEdge(pi)); } }
List<DebugCurve> ShowIllegalEdge(CdtEdge edge, CdtSite pi, int i) { List<DebugCurve> ls = new List<DebugCurve>(); ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); for (int j = 0; j < 3; j++) { var ee = edge.CcwTriangle.Edges[j]; ls.Add(new DebugCurve(j == i ? "red" : "blue", new LineSegment(ee.upperSite.Point, ee.lowerSite.Point))); } ls.Add(new DebugCurve(100,1, "black", Circumcircle(edge.CcwTriangle.Sites[0].Point,edge.CcwTriangle.Sites[1].Point,edge.CcwTriangle.Sites[2].Point))); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); return ls; }
static bool EdgeIsProcessed(CdtEdge edge) { return edge.CwTriangle != null || edge.CcwTriangle != null; }
static DebugCurve GetDebugCurveOfCdtEdge(CdtEdge e) { if(e.CcwTriangle==null || e.CwTriangle==null) return new DebugCurve(255, 4, e.Constrained ? "brown" : "blue", new LineSegment(e.upperSite.Point, e.lowerSite.Point)); return new DebugCurve(100, e.Constrained?0.002:0.001, e.Constrained?"pink":"navy", new LineSegment(e.upperSite.Point, e.lowerSite.Point)); }
void AddEdgeToFront(CdtEdge e) { var leftSite=e.upperSite.Point.X<e.lowerSite.Point.X?e.upperSite:e.lowerSite; front.Insert(new CdtFrontElement(leftSite, e)); }
bool FindNextPierced(Point start, Point end, ref CdtTriangle t, ref CdtEdge piercedEdge) { t = piercedEdge.GetOtherTriangle(t); if (t == null) return false; var i = t.Edges.Index(piercedEdge); for (int j = i + 1; j <= i + 2; j++) { var pe = t.Edges[j]; piercedEdge = PiercedEdgeQuery(pe, start, end, t); if (piercedEdge != null) { // CdtSweeper.ShowFront(trs, null, // new []{new LineSegment(e.SourcePoint,e.TargetPoint)}, new []{new LineSegment(pe.upperSite.Point,pe.lowerSite.Point)}); break; } } return !PointIsInsideOfTriangle(end, t); }
internal CdtSite OppositeSite(CdtEdge cdtEdge) { var i = Edges.Index(cdtEdge); return Sites[i + 2]; }
CdtTriangle FindFirstPiercedTriangle(CdtSite startSite, Point target, out CdtEdge piercedEdge) { if (startSite != null) { foreach (var t in startSite.Triangles) { piercedEdge = GetPiercedEdgeInSiteTriangle(t, startSite, target); if (piercedEdge != null) if (!PointIsInsideOfTriangle(target, t)) return t; } } piercedEdge = null; return null; }
double AddedCapacityPenaltyForCdtEdge(CdtEdge cdtEdge, EdgeGeometry edgeGeometry) { double capacityOverflowMultiplier = SdShortestPath.CapacityOverflowPenaltyMultiplier(bundlingSettings); return SdShortestPath.CostOfCrossingCdtEdge(capacityOverflowMultiplier, bundlingSettings, edgeGeometry, cdtEdge); }
void ShowIllegalEdge(CdtEdge edge, int i, CdtSite pi) { List<DebugCurve> ls=new List<DebugCurve>(); ls.Add(new DebugCurve(new Ellipse(2, 2, pi.Point))); for(int j=0;j<3;j++) { var ee=edge.CwTriangle.Edges[j]; ls.Add(new DebugCurve(j==i?"red":"blue", new LineSegment(ee.upperSite.Point,ee.lowerSite.Point))); } LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ls); }
internal bool EdgeIsReversed(CdtEdge edge) { return edge.CwTriangle == this; }
static PerimeterEdge CreatePerimeterElementFromEdge(CdtEdge edge) { var pe = new PerimeterEdge(edge); if (edge.CwTriangle != null) { pe.Start=edge.upperSite; pe.End = edge.lowerSite; } else { pe.End = edge.upperSite; pe.Start = edge.lowerSite; } return pe; }
internal static bool EdgeIsPierced(CdtEdge e, Point source, Point target, CdtTriangle cdtTriangle) { var area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, source, target); var area1 = Point.SignedDoubledTriangleArea(e.lowerSite.Point, source, target); if (ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) > 0) return false; area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, source); area1 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, target); if (ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) > 0) return false; var otherT = e.GetOtherTriangle(cdtTriangle); if (otherT == null) return true; var otherSite = otherT.OppositeSite(e); area0 = Point.SignedDoubledTriangleArea(e.upperSite.Point, e.lowerSite.Point, otherSite.Point); return (ApproximateComparer.Sign(area0) * ApproximateComparer.Sign(area1) >= 0); }
CdtEdge PiercedEdgeQuery(CdtEdge e, Point source, Point target, CdtTriangle cdtTriangle) { return EdgeIsPierced(e, source, target, cdtTriangle) ? e : null; }
static CdtEdge Flip(CdtSite pi, CdtEdge edge) { Debug.Assert(!edge.IsAdjacent(pi)); Debug.Assert(edge.CcwTriangle.Contains(pi) || edge.CwTriangle.Contains(pi)); //get surrounding data CdtTriangle t, ot; if (edge.CcwTriangle.Contains(pi)) { t = edge.CcwTriangle; ot = edge.CwTriangle; } else { t = edge.CwTriangle; ot = edge.CcwTriangle; } Debug.Assert(t.Contains(pi)); var eIndex = t.Edges.Index(edge); var eOtherIndex = ot.Edges.Index(edge); Debug.Assert(eIndex > -1 && eOtherIndex > -1); var pl = ot.Sites[eOtherIndex + 2]; var edgeBeforPi = t.Edges[eIndex + 1]; var edgeBeforPl = ot.Edges[eOtherIndex + 1]; //changing t var newEdge = Cdt.GetOrCreateEdge(pi, pl); t.Sites[eIndex + 1] = pl; t.Edges[eIndex] = edgeBeforPl; t.Edges[eIndex + 1] = newEdge; //changing ot ot.Sites[eOtherIndex + 1] = pi; ot.Edges[eOtherIndex] = edgeBeforPi; ot.Edges[eOtherIndex + 1] = newEdge; //orient the new edge and the two edges that move from one triangle to another if (edgeBeforPl.lowerSite == pl) edgeBeforPl.CcwTriangle = t; else edgeBeforPl.CwTriangle = t; if (edgeBeforPi.lowerSite == pi) edgeBeforPi.CcwTriangle = ot; else edgeBeforPi.CwTriangle = ot; if (newEdge.upperSite == pi) { newEdge.CcwTriangle = ot; newEdge.CwTriangle = t; } else { newEdge.CcwTriangle = t; newEdge.CwTriangle = ot; } Debug.Assert(CheckTriangle(t)); Debug.Assert(CheckTriangle(t)); //ShowFlip(pi, t, ot); edge.upperSite.Edges.Remove(edge); //forget the edge return newEdge; }