internal void AddToAdjacentVertex(TransientGraphUtility transUtil
             , VisibilityVertex targetVertex, Directions dirToExtend, Rectangle limitRect) {
     if (!PointComparer.Equal(this.Point, targetVertex.Point)) {
         transUtil.FindOrAddEdge(this.Vertex, targetVertex, InitialWeight);
     }
     ExtendEdgeChain(transUtil, targetVertex, dirToExtend, limitRect);
 }
 // Adds an edge from this.Vertex to a (possibly new) vertex at an intersection with an
 // existing Edge that adjoins the point.  We take 'dir' as an input parameter for edge
 // extension because we may be on the edge so can't calculate the direction.
 internal VisibilityVertex AddEdgeToAdjacentEdge(TransientGraphUtility transUtil
             , VisibilityEdge targetEdge, Directions dirToExtend, Rectangle limitRect) {
     Point targetIntersect = StaticGraphUtility.SegmentIntersection(targetEdge, this.Point);
     VisibilityVertex targetVertex = transUtil.VisGraph.FindVertex(targetIntersect);
     if (null != targetVertex) {
         AddToAdjacentVertex(transUtil, targetVertex, dirToExtend, limitRect);
     }
     else {
         targetVertex = transUtil.AddEdgeToTargetEdge(this.Vertex, targetEdge, targetIntersect);
     }
     ExtendEdgeChain(transUtil, targetVertex, dirToExtend, limitRect);
     return targetVertex;
 }
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
 internal void ExtendFromBorderVertex(TransientGraphUtility transUtil, VisibilityVertex borderVertex
                                      , Rectangle limitRect, bool routeToCenter)
 {
     ExtendEdgeChain(transUtil, borderVertex, borderVertex, limitRect, routeToCenter);
 }
 internal void GetVertex(TransientGraphUtility transUtil, Point point) {
     this.Vertex = transUtil.FindOrAddVertex(point);
 }
        internal void AddToAdjacentVertex(TransientGraphUtility transUtil, VisibilityVertex targetVertex
                            , Rectangle limitRect, bool routeToCenter) {
            VisibilityVertex borderVertex = transUtil.VisGraph.FindVertex(this.VisibilityBorderIntersect);
            if (null != borderVertex) {
                ExtendFromBorderVertex(transUtil, borderVertex, limitRect, routeToCenter);
                return;
            }

            // There is no vertex at VisibilityBorderIntersect, so create it and link it to targetVertex.
            // Note: VisibilityBorderIntersect may == targetIntersect if that is on our border, *and*
            // targetIntersect may be on the border of a touching obstacle, in which case this will splice
            // into or across the adjacent obstacle, which is consistent with "touching is overlapped".
            // So we don't use UnpaddedBorderIntersect as prevPoint when calling ExtendEdgeChain.

            // VisibilityBorderIntersect may be rounded just one Curve.DistanceEpsilon beyond the ScanSegment's
            // perpendicular coordinate; e.g. our X may be targetIntersect.X + Curve.DistanceEpsilon, thereby
            // causing the direction from VisibilityBorderIntersect to targetIntersect to be W instead of E.
            // So use the targetIntersect if they are close enough; they will be equal for flat borders, and
            // otherwise the exact value we use only needs be "close enough" to the border.  (We can't use
            // CenterVertex as the prevPoint because that could be an impure direction).
            // Update: With the change to carry MaxVisibilitySegment within the PortEntrance, PortManager finds
            // targetVertex between VisibilityBorderIntersect and MaxVisibilitySegment.End, so this should no longer
            // be able to happen.
            // See RectilinearTests.PaddedBorderIntersectMeetsIncomingScanSegment for an example of what happens
            // when VisibilityBorderIntersect is on the incoming ScanSegment (it jumps out above with borderVertex found).
            if (OutwardDirection == PointComparer.GetPureDirection(targetVertex.Point, this.VisibilityBorderIntersect)) {
                Debug.Assert(false, "Unexpected reversed direction between VisibilityBorderIntersect and targetVertex");
// ReSharper disable HeuristicUnreachableCode
                this.VisibilityBorderIntersect = targetVertex.Point;
                borderVertex = targetVertex;
// ReSharper restore HeuristicUnreachableCode
            }
            else {
                borderVertex = transUtil.FindOrAddVertex(this.VisibilityBorderIntersect);
                transUtil.FindOrAddEdge(borderVertex, targetVertex,  InitialWeight);
            }
            ExtendEdgeChain(transUtil, borderVertex, targetVertex, limitRect, routeToCenter);
        }
        internal void AddOobEdgesFromGraphCorner(TransientGraphUtility transUtil, Point cornerPoint) {
            Directions dirs = PointComparer.GetDirections(cornerPoint, Vertex.Point);
            VisibilityVertex cornerVertex = transUtil.VisGraph.FindVertex(cornerPoint);

            // For waypoints we want to be able to enter in both directions. 
            transUtil.ConnectVertexToTargetVertex(cornerVertex, this.Vertex, dirs & (Directions.North | Directions.South), ScanSegment.NormalWeight);
            transUtil.ConnectVertexToTargetVertex(cornerVertex, this.Vertex, dirs & (Directions.East | Directions.West), ScanSegment.NormalWeight);
        }
 // Called if we must create the vertex.
 internal FreePoint(TransientGraphUtility transUtil, Point point) {
     OutOfBoundsDirectionFromGraph = Directions. None;
     this.GetVertex(transUtil, point);
 }
 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;
 }
 // Splits an existing Edge to splice in this.Vertex.
 internal void SpliceIntoEdge(TransientGraphUtility transUtil, VisibilityEdge edge) {
     transUtil.SplitEdge(edge, this.Vertex);
 }
 internal void ExtendFromBorderVertex(TransientGraphUtility transUtil, VisibilityVertex borderVertex
                     , Rectangle limitRect, bool routeToCenter) {
     ExtendEdgeChain(transUtil, borderVertex, borderVertex, limitRect, routeToCenter);
 }
Пример #13
0
 // Splits an existing Edge to splice in this.Vertex.
 internal void SpliceIntoEdge(TransientGraphUtility transUtil, VisibilityEdge edge)
 {
     transUtil.SplitEdge(edge, this.Vertex);
 }
Пример #14
0
 internal void GetVertex(TransientGraphUtility transUtil, Point point)
 {
     this.Vertex = transUtil.FindOrAddVertex(point);
 }
Пример #15
0
 // Called if we must create the vertex.
 internal FreePoint(TransientGraphUtility transUtil, Point point)
 {
     OutOfBoundsDirectionFromGraph = Directions.None;
     this.GetVertex(transUtil, point);
 }
Пример #16
0
        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);
        }
Пример #17
0
        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);
        }
        internal void ExtendEdgeChain(TransientGraphUtility transUtil, VisibilityVertex paddedBorderVertex
                                , VisibilityVertex targetVertex, Rectangle limitRect, bool routeToCenter) {
            // Extend the edge chain to the opposite side of the limit rectangle.
            transUtil.ExtendEdgeChain(targetVertex, limitRect, this.MaxVisibilitySegment, this.pointAndCrossingsList, this.IsOverlapped);

            // In order for Nudger to be able to map from the (near-) endpoint vertex to a PortEntry, we must 
            // always connect a vertex at UnpaddedBorderIntersect to the paddedBorderVertex, even if routeToCenter.
            var unpaddedBorderVertex = transUtil.FindOrAddVertex(UnpaddedBorderIntersect);
            transUtil.FindOrAddEdge(unpaddedBorderVertex, paddedBorderVertex, this.unpaddedToPaddedBorderWeight);
            if (routeToCenter) {
                // Link the CenterVertex to the vertex at UnpaddedBorderIntersect.
                transUtil.ConnectVertexToTargetVertex(ObstaclePort.CenterVertex, unpaddedBorderVertex, OutwardDirection, InitialWeight);
            }
        }
 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;
 }
 internal void AddToGraph(TransientGraphUtility transUtil, bool routeToCenter) {
     // We use only border vertices if !routeToCenter.
     if (routeToCenter) {
         CenterVertex = transUtil.FindOrAddVertex(this.Location);
     }
 }