internal Point MaxVisibilityInDirectionForNonOverlappedFreePoint(Directions dirToExtend, TransientGraphUtility transUtil) { Debug.Assert(!this.IsOverlapped, "Do not precalculate overlapped obstacle visibility as we should extend from the outer target vertex instead"); SegmentAndCrossings segmentAndCrossings = GetSegmentAndCrossings(this.Vertex, dirToExtend, transUtil); return(segmentAndCrossings.Item1.End); }
internal void ExtendEdgeChain(TransientGraphUtility transUtil, VisibilityVertex targetVertex, Directions dirToExtend, Rectangle limitRect) { // Extend the edge chain to the opposite side of the limit rectangle. StaticGraphUtility.Assert(PointComparer.Equal(this.Point, targetVertex.Point) || (PointComparer.GetPureDirection(this.Point, targetVertex.Point) == dirToExtend) , "input dir does not match with to-targetVertex direction", transUtil.ObstacleTree, transUtil.VisGraph); var extendOverlapped = IsOverlapped; if (extendOverlapped) { // The initial vertex we connected to may be on the border of the enclosing obstacle, // or of another also-overlapped obstacle. If the former, we turn off overlap now. extendOverlapped = transUtil.ObstacleTree.PointIsInsideAnObstacle(targetVertex.Point, dirToExtend); } // If we're inside an obstacle's boundaries we'll never extend past the end of the obstacle // due to encountering the boundary from the inside. So start the extension at targetVertex. SegmentAndCrossings segmentAndCrossings = GetSegmentAndCrossings(this.IsOverlapped ? targetVertex : this.Vertex, dirToExtend, transUtil); transUtil.ExtendEdgeChain(targetVertex, limitRect, segmentAndCrossings.Item1, segmentAndCrossings.Item2, extendOverlapped); }
private SegmentAndCrossings GetSegmentAndCrossings(VisibilityVertex startVertex, Directions dirToExtend, TransientGraphUtility transUtil) { var dirIndex = CompassVector.ToIndex(dirToExtend); var segmentAndCrossings = this.maxVisibilitySegmentsAndCrossings[dirIndex]; if (null == segmentAndCrossings) { PointAndCrossingsList pacList; var maxVisibilitySegment = transUtil.ObstacleTree.CreateMaxVisibilitySegment(startVertex.Point, dirToExtend, out pacList); segmentAndCrossings = new SegmentAndCrossings(maxVisibilitySegment, pacList); this.maxVisibilitySegmentsAndCrossings[dirIndex] = segmentAndCrossings; } else { // For a waypoint this will be a target and then a source, so there may be a different lateral edge to // connect to. In that case make sure we are consistent in directions - back up the start point if needed. if (PointComparer.GetDirections(startVertex.Point, segmentAndCrossings.Item1.Start) == dirToExtend) { segmentAndCrossings.Item1.Start = startVertex.Point; } } return(segmentAndCrossings); }
private SegmentAndCrossings GetSegmentAndCrossings(VisibilityVertex startVertex, Directions dirToExtend, TransientGraphUtility transUtil) { var dirIndex = CompassVector.ToIndex(dirToExtend); var segmentAndCrossings = this.maxVisibilitySegmentsAndCrossings[dirIndex]; if (null == segmentAndCrossings) { PointAndCrossingsList pacList; var maxVisibilitySegment = transUtil.ObstacleTree.CreateMaxVisibilitySegment(startVertex.Point, dirToExtend, out pacList); segmentAndCrossings = new SegmentAndCrossings(maxVisibilitySegment, pacList); this.maxVisibilitySegmentsAndCrossings[dirIndex] = segmentAndCrossings; } else { // For a waypoint this will be a target and then a source, so there may be a different lateral edge to // connect to. In that case make sure we are consistent in directions - back up the start point if needed. if (PointComparer.GetDirections(startVertex.Point, segmentAndCrossings.Item1.Start) == dirToExtend) { segmentAndCrossings.Item1.Start = startVertex.Point; } } return segmentAndCrossings; }