void RemoveShortcuttedPolypoint(PolylinePoint pp, Dictionary <PointPair, Set <Metroline> > segsToPolylines) { var a = pp.Point; var b = pp.Next.Point; var c = pp.Next.Next.Point; Set <Metroline> abPolylines, bcPolylines, abcPolylines; FindPolylines(pp, segsToPolylines, out abPolylines, out bcPolylines, out abcPolylines); double ab = (a - b).Length; double bc = (b - c).Length; double ac = (a - c).Length; //fixing ink if (abPolylines.Count == abcPolylines.Count) { ink -= ab; } if (bcPolylines.Count == abcPolylines.Count) { ink -= bc; } if (!segsToPolylines.ContainsKey(new PointPair(a, c)) || segsToPolylines[new PointPair(a, c)].Count == 0) { ink += ac; } //fixing edge lengths foreach (var metroline in abcPolylines) { polylineLength[metroline] -= ab + bc - ac; } //fixing polylines foreach (var metroline in abcPolylines) { RemovePolypoint(metroline.Polyline.PolylinePoints.First(p => p.Point == b)); CollectionUtilities.RemoveFromMap(segsToPolylines, new PointPair(a, b), metroline); CollectionUtilities.RemoveFromMap(segsToPolylines, new PointPair(b, c), metroline); CollectionUtilities.AddToMap(segsToPolylines, new PointPair(a, c), metroline); } }
internal static void RoundVertices(Polyline polyline) { // Following creation of the padded border, round off the vertices for consistency // in later operations (intersections and event ordering). PolylinePoint ppt = polyline.StartPoint; do { ppt.Point = ApproximateComparer.Round(ppt.Point); ppt = ppt.NextOnPolyline; } while (ppt != polyline.StartPoint); RemoveCloseAndCollinearVerticesInPlace(polyline); // We've modified the points so the BoundingBox may have changed; force it to be recalculated. polyline.RequireInit(); // Verify that the polyline is still clockwise. Debug.Assert(polyline.IsClockwise(), "Polyline is not clockwise after RoundVertices"); }
double ComputeCostDeltaAfterNodeGluing(Station i, Station j, Dictionary <Station, Station> gluingMap) { double d = (i.Position - j.Position).Length; if (i.Radius >= d || j.Radius >= d) { return(1.0); } double gain = 0; //ink double oldInk = metroGraphData.Ink; double newInk = metroGraphData.Ink - (j.Position - i.Position).Length; foreach (var adj in i.Neighbors) { var k = Glued(adj, gluingMap); newInk -= (k.Position - i.Position).Length; newInk += (metroGraphData.RealEdgeCount(k, j) == 0 ? (k.Position - j.Position).Length : 0); } gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings); //path lengths foreach (var metroInfo in metroGraphData.MetroNodeInfosOfNode(i)) { double oldLength = metroInfo.Metroline.Length; double newLength = metroInfo.Metroline.Length; PolylinePoint pi = metroInfo.PolyPoint; PolylinePoint pa = pi.Prev; PolylinePoint pb = pi.Next; newLength -= (pa.Point - i.Position).Length + (pb.Point - i.Position).Length; newLength += (pa.Point - j.Position).Length + (pb.Point - j.Position).Length; gain += CostCalculator.PathLengthsError(oldLength, newLength, metroInfo.Metroline.IdealLength, bundlingSettings); } return(gain); }
static Point GetStickingVertexOnBisector(PolylinePoint pp, double p, out bool skip) { Point u = pp.Polyline.Prev(pp).Point; Point v = pp.Point; Point w = pp.Polyline.Next(pp).Point; var z = (v - u).Normalize() + (v - w).Normalize(); var zLen = z.Length; if (zLen < ApproximateComparer.Tolerance) { skip = true; } else { skip = false; z /= zLen; } return(p * z + v); }
private void RestrictEdgeContainerToTheRightOfEvent(PolylinePoint polylinePoint) { var site = polylinePoint.Point; var siteX = xProjection(site); var containerNode = edgeContainersTree.FindFirst (container => siteX <= xProjection(container.Source)); if (containerNode != null) { foreach (var edge in containerNode.Item) { if (!NotRestricting(edge, polylinePoint.Polyline)) { edge.BoundFromLeft(DirectionPerp * site); } } } }
internal static string Encode(PolylinePoint point) { var latitudeChars = Encode(point.Latitude); var longitudeChars = Encode(point.Longitude); int charsCount = latitudeChars.Count + longitudeChars.Count; var charsArray = new char[charsCount]; int index = charsCount - 1; while (longitudeChars.Count > 0) { charsArray[index--] = longitudeChars.Pop(); } while (latitudeChars.Count > 0) { charsArray[index--] = latitudeChars.Pop(); } return(new string(charsArray)); }
static object TryCreateFeatureWhichIsNotSite(PolylinePoint pp, CdtTriangle triangle) { Debug.Assert(!triangle.Sites.Any(s => ApproximateComparer.Close(pp.Point, s.Point))); var a0 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[0].Point, triangle.Sites[1].Point); if (a0 == TriangleOrientation.Clockwise) { return(null); } var a1 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[1].Point, triangle.Sites[2].Point); if (a1 == TriangleOrientation.Clockwise) { return(null); } var a2 = Point.GetTriangleOrientation(pp.Point, triangle.Sites[2].Point, triangle.Sites[3].Point); if (a2 == TriangleOrientation.Clockwise) { return(null); } if (a0 == TriangleOrientation.Counterclockwise && a1 == TriangleOrientation.Counterclockwise && a2 == TriangleOrientation.Counterclockwise) { return(triangle); } if (a0 == TriangleOrientation.Collinear) { return(triangle.Edges[0]); } if (a1 == TriangleOrientation.Collinear) { return(triangle.Edges[1]); } Debug.Assert(a2 == TriangleOrientation.Collinear); return(triangle.Edges[2]); }
int PolylinesIntersect(PolylinePoint a0, PolylinePoint b0, PolylinePoint a1, PolylinePoint b1, bool forwardOrderA, bool forwardOrderB) { PolylinePoint a0p = Prev(a0, forwardOrderA); PolylinePoint a0n = Next(a0, forwardOrderA); PolylinePoint a1n = Next(a1, forwardOrderA); PolylinePoint a1p = Prev(a1, forwardOrderA); PolylinePoint b0n = Next(b0, forwardOrderB); PolylinePoint b1p = Prev(b1, forwardOrderB); if (a0.Point == a1.Point) { Point bs = a0.Point; int left0 = Point.GetOrientationOf3Vectors(a1p.Point - bs, b1p.Point - bs, a0n.Point - bs); int left1 = Point.GetOrientationOf3Vectors(a1p.Point - bs, b0n.Point - bs, a0n.Point - bs); /* * if (left0 == 0 || left1 ==0) { * List<DebugCurve> dc = new List<DebugCurve>(); * Polyline pl = new Polyline(a0.Polyline); * Point sh = new Point(3, 0); * pl.Shift(sh); * dc.Add(new DebugCurve(100,1,"blue", a0.Polyline)); * dc.Add(new DebugCurve(100,1,"black", b0.Polyline)); * * dc.Add(new DebugCurve("blue", CurveFactory.CreateCircle(3, bs))); * * dc.Add(new DebugCurve(100,0.5, "blue", new LineSegment(a0p.Point, bs))); * dc.Add(new DebugCurve("red", CurveFactory.CreateCircle(5, b0.Point))); * dc.Add(new DebugCurve("red", CurveFactory.CreateCircle(10, b1.Point))); * LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(dc); * } */ Debug.Assert(left0 != 0 && left1 != 0); return(left0 == left1 ? 1 : 2); } else { int left0 = Point.GetOrientationOf3Vectors(a0p.Point - a0.Point, a0n.Point - a0.Point, b0n.Point - a0.Point); int left1 = Point.GetOrientationOf3Vectors(a1n.Point - a1.Point, b1p.Point - a1.Point, a1p.Point - a1.Point); Debug.Assert(left0 != 0 && left1 != 0); return(left0 == left1 ? 1 : 2); } }
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 LookForIntersectionOfObstacleSideAndRightConeSide(Point obstacleSideStart, PolylinePoint obstacleSideVertex) { RBNode <ConeSide> node = GetLastNodeToTheLeftOfPointInRightSegmentTree(obstacleSideStart); if (node != null) { var coneRightSide = node.Item as ConeRightSide; if (coneRightSide != null) { Point intersection; if (Point.IntervalIntersectsRay(obstacleSideStart, obstacleSideVertex.Point, coneRightSide.Start, ConeRightSideDirection, out intersection) && SegmentIsNotHorizontal(intersection, obstacleSideVertex.Point)) { EnqueueEvent(CreateRightIntersectionEvent(coneRightSide, intersection, obstacleSideVertex)); } } } }
internal static IEnumerable <Polyline> OrientHolesClockwise(IEnumerable <Polyline> holes) { #if TEST_MSAGL || VERIFY CheckThatPolylinesAreConvex(holes); #endif // TEST || VERIFY foreach (Polyline poly in holes) { for (PolylinePoint p = poly.StartPoint; ; p = p.Next) { // Find the first non-collinear segments and see which direction the triangle is. // If it's consistent with Clockwise, then return the polyline, else return its Reverse. var orientation = Point.GetTriangleOrientation(p.Point, p.Next.Point, p.Next.Next.Point); if (orientation != TriangleOrientation.Collinear) { yield return(orientation == TriangleOrientation.Clockwise ? poly : (Polyline)poly.Reverse()); break; } } } }
static bool CurveIsConvex(Polyline poly) { TriangleOrientation orientation = Point.GetTriangleOrientation(poly.EndPoint.Point, poly.StartPoint.Point, poly.StartPoint.Next.Point); if (Point.GetTriangleOrientation(poly.EndPoint.Prev.Point, poly.EndPoint.Point, poly.StartPoint.Point) != orientation) { return(false); } PolylinePoint pp = poly.StartPoint; while (pp.Next.Next != null) { if (Point.GetTriangleOrientation(pp.Point, pp.Next.Point, pp.Next.Next.Point) != orientation) { return(false); } pp = pp.Next; } return(true); }
Polyline FindFlip(Polyline poly) { var departed = new Dictionary <Polyline, PolylinePoint>(); for (PolylinePoint pp = poly.StartPoint.Next; pp != null; pp = pp.Next) { FillDepartedOnPrev(departed, pp); //look for a returning path foreach (PolylinePoint polyPoint in pathsThroughPoints[pp.Point]) { PolylinePoint pointOfDeparture; if (departed.TryGetValue(polyPoint.Polyline, out pointOfDeparture)) { return(pointOfDeparture.Polyline); } } } return(null); }
internal static Polyline RemoveCloseAndCollinearVerticesInPlace(Polyline polyline) { var epsilon = ApproximateComparer.IntersectionEpsilon * 10; for (PolylinePoint pp = polyline.StartPoint.Next; pp != null; pp = pp.Next) { if (ApproximateComparer.Close(pp.Prev.Point, pp.Point, epsilon)) { if (pp.Next == null) { polyline.RemoveEndPoint(); } else { pp.Prev.Next = pp.Next; pp.Next.Prev = pp.Prev; } } } if (ApproximateComparer.Close(polyline.Start, polyline.End, epsilon)) { polyline.RemoveStartPoint(); } InteractiveEdgeRouter.RemoveCollinearVertices(polyline); if ((polyline.EndPoint.Prev != null) && (Point.GetTriangleOrientation(polyline.EndPoint.Prev.Point, polyline.End, polyline.Start) == TriangleOrientation.Collinear)) { polyline.RemoveEndPoint(); } if ((polyline.StartPoint.Next != null) && (Point.GetTriangleOrientation(polyline.End, polyline.Start, polyline.StartPoint.Next.Point) == TriangleOrientation.Collinear)) { polyline.RemoveStartPoint(); } return(polyline); }
private static PolylinePoint FindConvexHullPolyPoint(Polyline polyline) { PolylinePoint convexHullPolyPoint = polyline.StartPoint; for (var p = polyline.StartPoint.Next; p != null; p = p.Next) { if (p.Point.Y < convexHullPolyPoint.Point.Y) { convexHullPolyPoint = p; } else if (p.Point.Y > convexHullPolyPoint.Point.Y) { continue; } if (p.Point.X < convexHullPolyPoint.Point.X) { convexHullPolyPoint = p; } } return(convexHullPolyPoint); }
private void FillRemovedForExternalTriangle(PolylinePoint a, PolylinePoint b, Set <CdtTriangle> removedTriangles, Cdt cdt) { CdtEdge e = FindEdge(a, b, cdt); if (e.CcwTriangle == null || e.CwTriangle == null) { return; } bool aligned = a.Point == e.upperSite.Point; if (aligned) { // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve(100, 0.1, "black", a.Polyline), new DebugCurve(100, 0.1, "red", new Polyline(e.CcwTriangle.Sites.Select(s => s.Point).ToArray()) { Closed = true })); FillRemovedConnectedRegion(e.CcwTriangle, removedTriangles); } else { // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve(100, 0.1, "black", a.Polyline), new DebugCurve(100,0.1,"red", new Polyline(e.CwTriangle.Sites.Select(s => s.Point).ToArray()) { Closed = true })); FillRemovedConnectedRegion(e.CwTriangle, removedTriangles); } }
private void ReadFlyText(string path) { StreamReader sr = new StreamReader(path, Encoding.Default); String line; List <IRouteWaypoint66> lr = new List <IRouteWaypoint66>(); List <double> lineArray = new List <double>(); sr.ReadLine(); int i = 0; while ((line = sr.ReadLine()) != null) { if (i % 2 == 0) { Console.WriteLine(line.ToString()); string[] val = System.Text.RegularExpressions.Regex.Split(line, @"\s"); double _lat = Double.Parse(val[1]); double _lon = Double.Parse(val[2]); double _alt = Double.Parse(val[3]) - 37.15; if (i % 4 == 0) { lineArray.Add(_lon); lineArray.Add(_lat); lineArray.Add(_alt); IRouteWaypoint66 iRWP = sgworld.Creator.CreateRouteWaypoint(_lon, _lat, _alt, 1); lr.Add(iRWP); } PolylinePoint pp = new PolylinePoint(); pp.X = _lon; pp.Y = _lat; pp.Z = _alt; ppf.Add(pp); } i++; } CreateDynamicFly(lr, lineArray); }
internal static void CheckThatPolylineIsConvex(Polyline polyline) { Debug.Assert(polyline.Closed, "Polyline is not closed"); PolylinePoint a = polyline.StartPoint; PolylinePoint b = a.Next; PolylinePoint c = b.Next; TriangleOrientation orient = Point.GetTriangleOrientation(a.Point, b.Point, c.Point); while (c != polyline.EndPoint) { a = a.Next; b = b.Next; c = c.Next; var currentOrient = Point.GetTriangleOrientation(a.Point, b.Point, c.Point); if (currentOrient == TriangleOrientation.Collinear) { continue; } if (orient == TriangleOrientation.Collinear) { orient = currentOrient; } else if (orient != currentOrient) { throw new InvalidOperationException(); } } var o = Point.GetTriangleOrientation(polyline.EndPoint.Point, polyline.StartPoint.Point, polyline.StartPoint.Next.Point); if (o != TriangleOrientation.Collinear && o != orient) { throw new InvalidOperationException(); } }
void FindFirstAndLast(Polyline a, out Point aFirst, out Point aLast, Dictionary <Point, PolylinePoint> bPoints) { aFirst = aLast = new Point(); for (PolylinePoint p = a.StartPoint; p != null; p = p.Next) { if (bPoints.ContainsKey(p.Point)) { aFirst = p.Point; break; } } for (PolylinePoint p = a.EndPoint; p != null; p = p.Prev) { if (bPoints.ContainsKey(p.Point)) { aLast = p.Point; return; } } throw new InvalidOperationException(); }
void CheckSite(Point end, Set <Polyline> obstaclesToIgnore, HashSet <CdtSite> checkedSites, CdtSite s, double upperBound, Dictionary <Polyline, double> obstacles) { if (!checkedSites.Add(s)) { return; } var poly = (Polyline)s.Owner; if (obstaclesToIgnore.Contains(poly)) { return; } //distance to the obstacle PolylinePoint pp = FindPolylinePoint(poly, s.Point); double par; double d12 = Point.DistToLineSegment(end, pp.Point, pp.NextOnPolyline.Point, out par); double d22 = Point.DistToLineSegment(end, pp.Point, pp.PrevOnPolyline.Point, out par); double dist = Math.Min(d12, d22); if (dist > upperBound) { return; } double currentValue; if (!obstacles.TryGetValue(poly, out currentValue)) { obstacles.Add(poly, dist); } else if (currentValue > dist) { obstacles[poly] = dist; } }
void LookForIntersectionOfObstacleSideAndLeftConeSide(Point obstacleSideStart, PolylinePoint obstacleSideVertex) { RBNode <ConeSide> node = GetFirstNodeToTheRightOfPoint(obstacleSideStart); // ShowLeftTree(Box(obstacleSideStart)); if (node == null) { return; } var coneLeftSide = node.Item as ConeLeftSide; if (coneLeftSide == null) { return; } Point intersection; if (Point.IntervalIntersectsRay(obstacleSideStart, obstacleSideVertex.Point, coneLeftSide.Start, ConeLeftSideDirection, out intersection)) { EnqueueEvent(new LeftIntersectionEvent(coneLeftSide, intersection, obstacleSideVertex)); } }
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); } } }
Polyline ProcessPolyline(Polyline polyline) { var departed = new Dictionary <Polyline, PolylinePoint>(); for (PolylinePoint pp = polyline.StartPoint.Next; pp != null; pp = pp.Next) { FillDepartedPolylinePoints(pp, departed); //find returning foreach (PolylinePoint polyPoint in pathsThroughPoints[pp.Point]) { if (departed.ContainsKey(polyPoint.Polyline)) { if (ProcessFlip(polyline, polyPoint.Polyline, departed[polyPoint.Polyline].Point, pp.Point)) { return(polyPoint.Polyline); } departed.Remove(polyPoint.Polyline); } } } return(null); }
void EnqueueLowestPointsOnObstacles(Polyline poly) { PolylinePoint candidate = GetLowestPoint(poly); EnqueueEvent(new LowestVertexEvent(candidate)); }
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)); } } }
static Ellipse EllipseOnPolylinePoint(PolylinePoint pp) { // ReSharper restore UnusedMember.Local return(new Ellipse(2, 2, pp.Point)); }
internal HighBendVertexEvent(Obstacle obstacle, PolylinePoint p) : base(obstacle, p) { }
//private Polyline CutCorners(Polyline loosePolyline, Polyline tightPolyline) { // Polyline ret = new Polyline(); // ret.Closed = true; // PolylinePoint pp = loosePolyline.StartPoint; // PolylinePoint tpp=tightPolyline.StartPoint; // do { // PolylinePoint furthestVisible = GetFurthestVisible(pp, ref tpp); // ret.AddPoint(furthestVisible.Point); // pp = furthestVisible; // } // while (pp != loosePolyline.StartPoint); // System.Diagnostics.Debug.Assert(pp == loosePolyline.StartPoint); // //distangle ret.StartPoint and ret.LastPoint // return ret; //} //static PolylinePoint GetFurthestVisible(PolylinePoint pp, ref PolylinePoint tpp) { // Point pivot = pp.Point; // Point blockingPoint = tpp.NextOnPolyline.Point; // while (Point.GetTriangleOrientation(pivot, blockingPoint, pp.NextOnPolyline.Point) == TriangleOrientation.Counterclockwise) { // pp = pp.NextOnPolyline; // tpp = tpp.NextOnPolyline; // } // return pp; //} static Polyline CreateLoosePolylineOnBisectors(Polyline tightPolyline, double p) { var ret = new Polyline(); ret.AddPoint(GetStickingVertexOnBisector(tightPolyline.StartPoint, p)); var blockingPoint = new Point(); //to silence the compiler var candidate = new Point(); bool justAdded = true; for (PolylinePoint pp = tightPolyline.StartPoint.Next; pp != null; pp = pp.Next) { Point currentSticking = GetStickingVertexOnBisector(pp, p); if (justAdded) { blockingPoint = pp.Point; candidate = currentSticking; justAdded = false; } else { if (ret.Count > 1) { // SugiyamaLayoutSettings.Show(tightPolyline, ret, new LineSegment(ret.StartPoint.Point, currentSticking)); } //SugiyamaLayoutSettings.Show(new LineSegment(ret.EndPoint.Point, blockingPoint), tightPolyline, new LineSegment(ret.EndPoint.Point, currentSticking)); if (Point.GetTriangleOrientation(ret.EndPoint.Point, blockingPoint, currentSticking) != TriangleOrientation.Counterclockwise) { ret.AddPoint(candidate); // SugiyamaLayoutSettings.Show(ret, tightPolyline); justAdded = true; pp = pp.Prev; } else { candidate = currentSticking; if (Point.GetTriangleOrientation(ret.EndPoint.Point, blockingPoint, pp.Point) == TriangleOrientation.Counterclockwise) { blockingPoint = pp.Point; } } } } //process the last point if (!justAdded) { if (Point.GetTriangleOrientation(ret.EndPoint.Point, blockingPoint, ret.StartPoint.Point) == TriangleOrientation.Counterclockwise) { //the first point is visible, but now can we cut it if (Point.GetTriangleOrientation(ret.EndPoint.Point, blockingPoint, ret.StartPoint.Next.Point) == TriangleOrientation.Counterclockwise) { ret.RemoveStartPoint(); } } else { ret.AddPoint(candidate); } } else { //trying to cut away the first point if ( Point.GetTriangleOrientation(ret.EndPoint.Point, tightPolyline.StartPoint.Point, ret.StartPoint.Next.Point) == TriangleOrientation.Counterclockwise) { ret.RemoveStartPoint(); } else { } } ret.Closed = true; // SugiyamaLayoutSettings.Show(tightPolyline, ret); return(ret); }
private bool IsClockwise(Polyline polyline) { PolylinePoint convexHullPolyPoint = FindConvexHullPolyPoint(polyline); return(Point.GetTriangleOrientation(convexHullPolyPoint.PrevOnPolyline.Point, convexHullPolyPoint.Point, convexHullPolyPoint.NextOnPolyline.Point) == TriangleOrientation.Clockwise); }
void UnregisterPolylinePointInPathsThrough(PolylinePoint pp) { CollectionUtilities.RemoveFromMap(pathsThroughPoints, pp.Point, pp); }