void MapPathToItsObstacles(Path path) { var startNode = HierarchyOfObstacles.FirstHitNode(path.PathPoints.First(),ObstacleTest); var endNode = HierarchyOfObstacles.FirstHitNode(path.PathPoints.Last(), ObstacleTest); if ((null != startNode) && (null != endNode)) { PathToObstacles[path] = new Tuple<Polyline, Polyline>(startNode.UserData, endNode.UserData); } }
void FillTheVisibilityGraphByWalkingPath(Path path){ var pathEdgesEnum = CreatePathEdgesFromPoints(path.PathPoints, path.Width).GetEnumerator(); if (pathEdgesEnum.MoveNext()) path.SetFirstEdge(pathEdgesEnum.Current); while(pathEdgesEnum.MoveNext()) path.AddEdge(pathEdgesEnum.Current); }
// bool Correct() { // foreach (var kv in verticesToPathOffsets) { // Point p = kv.Key; // Dictionary<Path, LinkedPoint> pathOffs = kv.Value; // foreach (var pathOff in pathOffs) { // var path = pathOff.Key; // var linkedPoint = pathOff.Value; // if (linkedPoint.Point != p) // return false; // if (FindLinkedPointInPath(path, p) == null) { // return false; // } // } // } // return true; // } void CollapseLoopingPath(Path loopingPath, LinkedPoint departureFromLooping, LinkedPoint arrivalToLooping, Path stemPath, LinkedPoint arrivalToStem){ var departurePointOnStem = FindLinkedPointInPath(stemPath, departureFromLooping.Point); IEnumerable<Point> pointsToInsert = GetPointsInBetween(departurePointOnStem, arrivalToStem); if(Before(departureFromLooping, arrivalToLooping)){ CleanDisappearedPiece(departureFromLooping, arrivalToLooping, loopingPath); ReplacePiece(departureFromLooping, arrivalToLooping, pointsToInsert,loopingPath); }else{ CleanDisappearedPiece(arrivalToLooping, departureFromLooping, loopingPath); ReplacePiece(arrivalToLooping, departureFromLooping, pointsToInsert.Reverse(),loopingPath); } }
bool ProcessPath(Path path) { var pts = (Point[])path.PathPoints; bool canHaveStaircase; if (ProcessPoints(ref pts, out canHaveStaircase)) { path.PathPoints = pts; return true; } if (!canHaveStaircase) crossedOutPaths.Insert(path); return false; }
void ProcessPath(Path path) { var departedPaths = new Dictionary<Path, LinkedPoint>(); Dictionary<Path, LinkedPoint> prevLocationPathOffsets = null; for (var linkedPoint = (LinkedPoint) path.PathPoints; linkedPoint != null; linkedPoint = linkedPoint.Next) { var pathOffsets = verticesToPathOffsets[linkedPoint.Point]; if (prevLocationPathOffsets != null) { //handle returning paths if (departedPaths.Count > 0) foreach (var pair in pathOffsets) { LinkedPoint departerLinkedPoint; var path0 = pair.Key; if (departedPaths.TryGetValue(path0, out departerLinkedPoint)) {//returned! CollapseLoopingPath(path0, departerLinkedPoint, pair.Value, path, linkedPoint); departedPaths.Remove(path0); } } //find departed paths foreach (var pair in prevLocationPathOffsets.Where(pair => !pathOffsets.ContainsKey(pair.Key))) departedPaths.Add(pair.Key, pair.Value); } prevLocationPathOffsets = pathOffsets; } }
internal virtual void SpliceVisibilityAndGeneratePath(MsmtRectilinearPath shortestPathRouter, Path edgePath) { this.PortManager.AddControlPointsToGraph(edgePath.EdgeGeometry, this.ShapeToObstacleMap); this.PortManager.TransUtil.DevTrace_VerifyAllVertices(this.VisibilityGraph); this.PortManager.TransUtil.DevTrace_VerifyAllEdgeIntersections(this.VisibilityGraph); if (!this.GeneratePath(shortestPathRouter, edgePath)) { this.RetryPathsWithAdditionalGroupsEnabled(shortestPathRouter, edgePath); } this.PortManager.RemoveControlPointsFromGraph(); }
internal virtual void GeneratePathThroughVisibilityIntersection(Path edgePath, Point[] intersectPoints) { edgePath.PathPoints = intersectPoints; }
static IEnumerable<DebugCurve> PathDebugCurves(Path path, string color) { var d = path.PathEdges.Select(e => new DebugCurve(70, 0.5, color, new LineSegment(e.Source, e.Target))); return d.Concat(MarkPathVerts(path)); }
void CleanDisappearedPiece(LinkedPoint a, LinkedPoint b, Path loopingPath){ foreach (var point in GetPointsInBetween(a, b)) { var pathOffset = verticesToPathOffsets[point]; Debug.Assert(pathOffset.ContainsKey(loopingPath)); pathOffset.Remove(loopingPath); } }
private static void EnsureNonNullPath(Path edgePath) { if (null == edgePath.PathPoints) { // Probably a fully-landlocked obstacle such as RectilinearTests.Route_Between_Two_Separately_Landlocked_Obstacles // or disconnected subcomponents due to excessive overlaps, such as Rectilinear(File)Tests.*Disconnected*. In this // case, just put the single-bend path in there, even though it most likely cuts across unrelated obstacles. if (PointComparer.IsPureDirection(edgePath.EdgeGeometry.SourcePort.Location, edgePath.EdgeGeometry.TargetPort.Location)) { edgePath.PathPoints = new[] { edgePath.EdgeGeometry.SourcePort.Location, edgePath.EdgeGeometry.TargetPort.Location }; return; } edgePath.PathPoints = new[] { edgePath.EdgeGeometry.SourcePort.Location, new Point(edgePath.EdgeGeometry.SourcePort.Location.X, edgePath.EdgeGeometry.TargetPort.Location.Y), edgePath.EdgeGeometry.TargetPort.Location }; } }
private static bool GetSingleStagePath(Path edgePath, MsmtRectilinearPath shortestPathRouter, List<VisibilityVertex> sourceVertices, List<VisibilityVertex> targetVertices, bool lastChance) { edgePath.PathPoints = shortestPathRouter.GetPath(sourceVertices, targetVertices); if (lastChance) { EnsureNonNullPath(edgePath); } return (edgePath.PathPoints != null); }
void CreateLongestNudgedSegmentsForPath(Path path, PointProjection projectionToPerp) { //ShowEdgesOfEdgePath(path); GoOverPathAndCreateLongSegs(path); CalculateIdealPositionsForLongestSegs(path, projectionToPerp); }
void BoundAxisEdgesAdjacentToSourceAndTargetOnEdge(Path path) { BoundAxisEdgeAdjacentToObstaclePort(path.EdgeGeometry.SourcePort, path.FirstEdge.AxisEdge); BoundAxisEdgeAdjacentToObstaclePort(path.EdgeGeometry.TargetPort, path.LastEdge.AxisEdge); }
static IEnumerable<DebugCurve> GetTestPathAsDebugCurve(double startWidth, double endWidth, string color, Path path) { if (path.PathEdges.Count() > 0) { int count = path.PathEdges.Count(); double deltaW = count > 1 ? (endWidth - startWidth)/(count - 1) : 1; //if count ==1 the value of deltaW does not matter int i = 0; foreach (var e in path.PathEdges) yield return new DebugCurve(150, startWidth + deltaW*(i++), color, new LineSegment(e.Source, e.Target)); }else { int count = path.PathPoints.Count(); var pts = path.PathPoints.ToArray(); var deltaW = count > 1 ? (endWidth - startWidth) / (count - 1) : 1; //if count ==1 the value of deltaW does not matter for (int i = 0; i < count - 1;i++ ) yield return new DebugCurve(150, startWidth+deltaW*i, color, new LineSegment(pts[i], pts[i+1])); } }
void BoundPathByMinCommonAncestors(Path path) { foreach (var rect in GetMinCommonAncestors(path.EdgeGeometry).Select(sh => sh.BoundingBox)) foreach ( var edge in path.PathEdges.Select(e => e.AxisEdge).Where( axisEdge => axisEdge.Direction == NudgingDirection) ) BoundAxisEdgeByRect(rect, edge); }
static internal IEnumerable<DebugCurve> PathDebugCurvesFromPoint(Path path) { var l = new List<Point>(path.PathPoints); for (int i = 0; i < l.Count - 1; i++) yield return new DebugCurve(4, "red", new LineSegment(l[i], l[i + 1])); }
private static IEnumerable<DebugCurve> MarkPathVerts(Path path) { bool first = true; var p = new Point(); foreach (var p0 in path.PathPoints) { if (first) { yield return new DebugCurve(200, 1, "violet", CurveFactory.CreateDiamond(5, 5, p0)); first = false; } else yield return new DebugCurve(100, 0.5, "brown", CurveFactory.CreateEllipse(1.5, 1.5, p0)); p = p0; } yield return new DebugCurve(200, 1, "green", CurveFactory.CreateDiamond(3, 3, p)); }
private void ShowEdgePath(Path path) { // ReSharper restore UnusedMember.Local List<DebugCurve> dd = Nudger.GetObstacleBoundaries(PaddedObstacles, "black"); dd.AddRange(Nudger.PathDebugCurvesFromPoint(path)); dd.AddRange(VisibilityGraph.Edges.Select(e => new DebugCurve(0.5, "blue", new LineSegment(e.SourcePoint, e.TargetPoint)))); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(dd); }
internal virtual bool GeneratePath(MsmtRectilinearPath shortestPathRouter, Path edgePath, bool lastChance = false) { var sourceVertices = PortManager.FindVertices(edgePath.EdgeGeometry.SourcePort); var targetVertices = PortManager.FindVertices(edgePath.EdgeGeometry.TargetPort); return edgePath.EdgeGeometry.HasWaypoints ? this.GetMultiStagePath(edgePath, shortestPathRouter, sourceVertices, targetVertices, lastChance) : GetSingleStagePath(edgePath, shortestPathRouter, sourceVertices, targetVertices, lastChance); }
static void CalculateIdealPositionsForLongestSegs(Path path, PointProjection projectionToPerp) { LongestNudgedSegment currentLongSeg = null; LongestNudgedSegment ret = null; double prevOffset = projectionToPerp(path.Start); foreach (var edge in path.PathEdges) { if (edge.LongestNudgedSegment != null) { currentLongSeg = edge.LongestNudgedSegment; if (ret != null) { double t; SetIdealPositionForSeg(ret, t = projectionToPerp(ret.Start), prevOffset, projectionToPerp(currentLongSeg.Start)); prevOffset = t; ret = null; } } else if (currentLongSeg != null) { ret = currentLongSeg; currentLongSeg = null; } } if (ret != null) SetIdealPositionForSeg(ret, projectionToPerp(ret.Start), prevOffset, projectionToPerp(path.End)); else if (currentLongSeg != null) currentLongSeg.IdealPosition = projectionToPerp(currentLongSeg.Start); }
private bool GetMultiStagePath(Path edgePath, MsmtRectilinearPath shortestPathRouter, List<VisibilityVertex> sourceVertices, List<VisibilityVertex> targetVertices, bool lastChance) { var waypointVertices = PortManager.FindWaypointVertices(edgePath.EdgeGeometry.Waypoints); var paths = shortestPathRouter.GetPath(sourceVertices, waypointVertices, targetVertices); if (paths == null) { if (!lastChance) { return false; } // Get each stage individually. They won't necessarily be ideal but this should be very rare and // with at least one stage being "forced" through obstacles, the path is not good anyway. foreach (var stagePath in this.edgeGeomsToSplittedEdgePaths[edgePath.EdgeGeometry]) { var stageGeom = stagePath.EdgeGeometry; GetSingleStagePath(stagePath, shortestPathRouter, this.PortManager.FindVertices(stageGeom.SourcePort), this.PortManager.FindVertices(stageGeom.TargetPort), lastChance:true); } return true; } // Record the path for each state. var pathsEnum = paths.GetEnumerator(); foreach (var stagePath in this.edgeGeomsToSplittedEdgePaths[edgePath.EdgeGeometry]) { pathsEnum.MoveNext(); stagePath.PathPoints = pathsEnum.Current; } return true; }
void GoOverPathAndCreateLongSegs(Path path) { LongestNudgedSegment currentLongestSeg = null; var oppositeDir = CompassVector.OppositeDir(NudgingDirection); foreach (var edge in path.PathEdges) { var edgeDir = edge.Direction; if (edgeDir == NudgingDirection || edgeDir == oppositeDir) { if (currentLongestSeg == null) #if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=368 { edge.LongestNudgedSegment = currentLongestSeg = new LongestNudgedSegment(LongestNudgedSegs.Count); LongestNudgedSegs.Add(edge.LongestNudgedSegment); } #else LongestNudgedSegs.Add( edge.LongestNudgedSegment = currentLongestSeg = new LongestNudgedSegment(LongestNudgedSegs.Count)); #endif else edge.LongestNudgedSegment = currentLongestSeg; if (edge.IsFixed) currentLongestSeg.IsFixed = true; } else { //the edge is perpendicular to "direction" edge.LongestNudgedSegment = null; currentLongestSeg = null; } }
internal virtual void RetryPathsWithAdditionalGroupsEnabled(MsmtRectilinearPath shortestPathRouter, Path edgePath) { // Insert any spatial parent groups that are not in our hierarchical parent tree and retry, // if we haven't already done this. if (!PortManager.SetAllAncestorsActive(edgePath.EdgeGeometry, ShapeToObstacleMap) || !GeneratePath(shortestPathRouter, edgePath)) { // Last chance: enable all groups (if we have any). Only do this on a per-path basis so a single degenerate // path won't make the entire graph look bad. PortManager.SetAllGroupsActive(); GeneratePath(shortestPathRouter, edgePath, lastChance:true); } }
void InsertPathSegs(Path path) { InsertSegs((Point[])path.PathPoints); }
static LinkedPoint FindLinkedPointInPath(Path path, Point point) { //this function is supposed to always succeed. it will throw a null reference exception otherwise for (var linkedPoint = (LinkedPoint) path.PathPoints;; linkedPoint = linkedPoint.Next) if (linkedPoint.Point == point) return linkedPoint; }
void ReplacePiece(LinkedPoint a, LinkedPoint b, IEnumerable<Point> points, Path loopingPath){ var prevPoint = a; foreach (var point in points){ var lp = new LinkedPoint(point); prevPoint.Next = lp; prevPoint = lp; var pathOffset = verticesToPathOffsets[point]; Debug.Assert(!pathOffset.ContainsKey(loopingPath)); pathOffset[loopingPath] = prevPoint; } prevPoint.Next = b; }
static IEnumerable<DebugCurve> PathDebugCurvesFromPoints(Path path, string color) { const double startWidth = 0.01; const double endWidth = 3; var pts = path.PathPoints.ToArray(); double delta = (endWidth - startWidth) / (pts.Length - 1); for (int i = 0; i < pts.Length - 1; i++) yield return new DebugCurve(startWidth + delta * i, color, new LineSegment(pts[i], pts[i + 1])); }
static IEnumerable<DebugCurve> GetEdgePathFromPathEdgesAsDebugCurves(double startWidth, double endWidth, string color, Path path) { var points = path.PathPoints.ToArray(); int count = points.Length; double deltaW = count > 1 ? (endWidth - startWidth) / (count - 1) : 1; //if count ==1 the value of deltaW does not matter for (int i = 0; i < points.Length - 1; i++) yield return new DebugCurve(120, startWidth + deltaW * i, color, new LineSegment(points[i], points[i + 1])); }
static LinkedPoint CreateLinkedVertexOfEdgePath(Path path) { var pathPoint = new LinkedPoint(path.PathPoints.First()); var first = pathPoint; #if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=368 path.PathPoints.Skip(1).Aggregate(pathPoint, (lp, p) => { lp.Next = new LinkedPoint(p); return lp.Next; }); #else path.PathPoints.Skip(1).Aggregate(pathPoint, (lp, p) => lp.Next = new LinkedPoint(p)); #endif return first; }
private void AddControlPointsAndGeneratePath(MsmtRectilinearPath shortestPathRouter, Path edgePath) { if (!edgePath.EdgeGeometry.HasWaypoints) { Point[] intersectPoints = PortManager.GetPortVisibilityIntersection(edgePath.EdgeGeometry); if (intersectPoints != null) { GeneratePathThroughVisibilityIntersection(edgePath, intersectPoints); return; } } this.SpliceVisibilityAndGeneratePath(shortestPathRouter, edgePath); }