private void CreateOutOfBoundsFreePoint(FreePoint freePoint) { // For an out of bounds (OOB) point, we'll link one edge from it to the inbounds edge if it's // out of bounds in only one direction; if in two, we'll add a bend. Currently we don't need // to do any more because multiple waypoints are processed as multiple subpaths. var oobLocation = freePoint.Point; Point inboundsLocation = graphGenerator.MakeInBoundsLocation(oobLocation); Directions dirFromGraph = PointComparer.GetDirections(inboundsLocation, oobLocation); freePoint.OutOfBoundsDirectionFromGraph = dirFromGraph; if (!PointComparer.IsPureDirection(dirFromGraph)) { // It's OOB in two directions so will need a bend, but we know inboundsLocation // is a graph corner so it has a vertex already and we don't need to look up sides. StaticGraphUtility.Assert(null != VisGraph.FindVertex(inboundsLocation), "graph corner vertex not found", ObstacleTree, VisGraph); freePoint.AddOobEdgesFromGraphCorner(TransUtil, inboundsLocation); return; } // We know inboundsLocation is on the nearest graphBox border ScanSegment, so this won't return a // null edge, and we'll just do normal join-to-one-edge handling, extending in the direction to the graph. var inboundsVertex = this.VisGraph.FindVertex(inboundsLocation); var dirToGraph = CompassVector.OppositeDir(dirFromGraph); if (null != inboundsVertex) { freePoint.AddToAdjacentVertex(this.TransUtil, inboundsVertex, dirToGraph, this.portSpliceLimitRectangle); } else { var edge = this.FindorCreateNearestPerpEdge(oobLocation, inboundsLocation, dirFromGraph, ScanSegment.NormalWeight); if (null != edge) { inboundsVertex = freePoint.AddEdgeToAdjacentEdge(this.TransUtil, edge, dirToGraph, this.portSpliceLimitRectangle); } } // This may be an oob waypoint, in which case we want to add additional edges so we can // go outside graph, cross the waypoint, and come back in. Shortest-paths will do the // work of determining the optimal path, to avoid backtracking. var inboundsLeftVertex = StaticGraphUtility.FindNextVertex(inboundsVertex, CompassVector.RotateLeft(dirToGraph)); if (inboundsLeftVertex != null) { this.TransUtil.ConnectVertexToTargetVertex(freePoint.Vertex, inboundsLeftVertex, dirToGraph, ScanSegment.NormalWeight); } var inboundsRightVertex = StaticGraphUtility.FindNextVertex(inboundsVertex, CompassVector.RotateRight(dirToGraph)); if (inboundsRightVertex != null) { this.TransUtil.ConnectVertexToTargetVertex(freePoint.Vertex, inboundsRightVertex, dirToGraph, ScanSegment.NormalWeight); } }
private FreePoint FindOrCreateFreePoint(Point location) { FreePoint freePoint; if (!this.freePointMap.TryGetValue(location, out freePoint)) { freePoint = new FreePoint(TransUtil, location); this.freePointMap[location] = freePoint; } else { freePoint.GetVertex(TransUtil, location); } freePointsInGraph.Insert(freePoint); freePointLocationsUsedByRouteEdges.Insert(location); return freePoint; }
private void ConnectOobWaypointToEndpointVisibilityAtGraphBoundary(FreePoint oobWaypoint, Port port) { if ((oobWaypoint == null) || !oobWaypoint.IsOutOfBounds) { return; } // Connect to the graphbox side at points collinear with the vertices. The waypoint may be // OOB in two directions so call once for each axis. var endpointVertices = this.FindVertices(port); var dirFromGraph = oobWaypoint.OutOfBoundsDirectionFromGraph & (Directions.North | Directions.South); ConnectToGraphAtPointsCollinearWithVertices(oobWaypoint, dirFromGraph, endpointVertices); dirFromGraph = oobWaypoint.OutOfBoundsDirectionFromGraph & (Directions.East | Directions.West); ConnectToGraphAtPointsCollinearWithVertices(oobWaypoint, dirFromGraph, endpointVertices); }
private void ConnectToGraphAtPointsCollinearWithVertices(FreePoint oobWaypoint, Directions dirFromGraph, List<VisibilityVertex> endpointVertices) { if (Directions. None == dirFromGraph) { // Not out of bounds on this axis. return; } var dirToGraph = CompassVector.OppositeDir(dirFromGraph); foreach (var vertex in endpointVertices) { var graphBorderLocation = this.InBoundsGraphBoxIntersect(vertex.Point, dirFromGraph); var graphBorderVertex = this.VisGraph.FindVertex(graphBorderLocation); if (graphBorderVertex != null) { this.TransUtil.ConnectVertexToTargetVertex(oobWaypoint.Vertex, graphBorderVertex, dirToGraph, ScanSegment.NormalWeight); } } }
private void ConnectFreePointToLateralEdge(FreePoint freePoint, Directions lateralDir) { // Turn on pivot vertex to either side to find the next edge to connect to. If the freepoint is // overlapped (inside an obstacle), just find the closest ScanSegment outside the obstacle and // start extending from there; otherwise, we can have the FreePoint calculate its max visibility. var end = freePoint.IsOverlapped ? this.InBoundsGraphBoxIntersect(freePoint.Point, lateralDir) : freePoint.MaxVisibilityInDirectionForNonOverlappedFreePoint(lateralDir, this.TransUtil); var lateralEdge = this.FindorCreateNearestPerpEdge(end, freePoint.Point, lateralDir, freePoint.InitialWeight); // There may be no VisibilityEdge between the current point and any adjoining obstacle in that direction. if (null != lateralEdge) { freePoint.AddEdgeToAdjacentEdge(TransUtil, lateralEdge, lateralDir, this.portSpliceLimitRectangle); } }