Beispiel #1
0
        // For a single vertex point, split its List of crossings in both directions into an array in each (opposite)
        // direction.  CLR Array iteration is much faster than List.
        static internal GroupBoundaryCrossing[] ToCrossingArray(List <GroupBoundaryCrossing> crossings, Directions dirToInside)
        {
            // First find the number in each (opposite) direction, then create the arrays.
            // We expect a very small number of groups to share a boundary point so this is not optimized.
            int numInDir       = 0;
            var crossingsCount = crossings.Count;       // cache for perf

            for (int ii = 0; ii < crossingsCount; ++ii)
            {
                if (crossings[ii].DirectionToInside == dirToInside)
                {
                    ++numInDir;
                }
            }
            if (0 == numInDir)
            {
                return(null);
            }

            var vector = new GroupBoundaryCrossing[numInDir];
            int jj     = 0;

            for (int ii = 0; ii < crossingsCount; ++ii)
            {
                if (crossings[ii].DirectionToInside == dirToInside)
                {
                    vector[jj++] = crossings[ii];
                }
            }
            return(vector);
        }
        internal GroupBoundaryCrossing AddIntersection(Point intersection, Obstacle group, Directions dirToInside)
        {
            List <GroupBoundaryCrossing> crossings;

            if (!pointCrossingMap.TryGetValue(intersection, out crossings))
            {
                crossings = new List <GroupBoundaryCrossing>();
                pointCrossingMap[intersection] = crossings;
            }

            // We may hit the same point on neighbor traversal in multiple directions.  We will have more than one item
            // in this list only if there are multiple group boundaries at this point, which should be unusual.
            var crossingsCount = crossings.Count;       // cache for perf

            for (int ii = 0; ii < crossingsCount; ++ii)
            {
                var crossing = crossings[ii];
                if (crossing.Group == group)
                {
                    // At a given location for a given group, there is only one valid dirToInside.
                    Debug.Assert(dirToInside == crossing.DirectionToInside, "Mismatched dirToInside");
                    return(crossing);
                }
            }
            var newCrossing = new GroupBoundaryCrossing(group, dirToInside);

            crossings.Add(newCrossing);
            return(newCrossing);
        }
Beispiel #3
0
        private static VisibilityVertex GetCrossingInteriorVertex(VisibilityGraph vg, VisibilityVertex crossingVertex,
                                                                  GroupBoundaryCrossing crossing)
        {
            Point interiorPoint = crossing.GetInteriorVertexPoint(crossingVertex.Point);

            return(vg.FindVertex(interiorPoint) ?? vg.AddVertex(interiorPoint));
        }
        internal GroupBoundaryCrossing AddIntersection(Point intersection, Obstacle group, Directions dirToInside) {
            List<GroupBoundaryCrossing> crossings;
            if (!pointCrossingMap.TryGetValue(intersection, out crossings)) {
                crossings = new List<GroupBoundaryCrossing>();
                pointCrossingMap[intersection] = crossings;
            }

            // We may hit the same point on neighbor traversal in multiple directions.  We will have more than one item
            // in this list only if there are multiple group boundaries at this point, which should be unusual.
            var crossingsCount = crossings.Count;       // cache for perf
            for (int ii = 0; ii < crossingsCount; ++ii) {
                var crossing = crossings[ii];
                if (crossing.Group == group) {
                    // At a given location for a given group, there is only one valid dirToInside.
                    Debug.Assert(dirToInside == crossing.DirectionToInside, "Mismatched dirToInside");
                    return crossing;
                }
            }
            var newCrossing = new GroupBoundaryCrossing(group, dirToInside);
            crossings.Add(newCrossing);
            return newCrossing;
        }
        // For a single vertex point, split its List of crossings in both directions into an array in each (opposite)
        // direction.  CLR Array iteration is much faster than List.
        static internal GroupBoundaryCrossing[] ToCrossingArray(List<GroupBoundaryCrossing> crossings, Directions dirToInside){

            // First find the number in each (opposite) direction, then create the arrays. 
            // We expect a very small number of groups to share a boundary point so this is not optimized.
            int numInDir = 0;
            var crossingsCount = crossings.Count;       // cache for perf
            for (int ii = 0; ii < crossingsCount; ++ii) {
                if (crossings[ii].DirectionToInside == dirToInside) {
                    ++numInDir;
                }
            }
            if (0 == numInDir) {
                return null;
            }

            var vector = new GroupBoundaryCrossing[numInDir];
            int jj = 0;
            for (int ii = 0; ii < crossingsCount; ++ii) {
                if (crossings[ii].DirectionToInside == dirToInside) {
                    vector[jj++] = crossings[ii];
                }
            }
            return vector;
        }
 private void AddHighCrossings(VisibilityGraph vg, VisibilityVertex crossingVertex, GroupBoundaryCrossing[] crossings) {
     if (null != crossings) {
         VisibilityVertex interiorVertex = GetCrossingInteriorVertex(vg, crossingVertex, crossings[0]);
         this.AddCrossingEdge(vg, crossingVertex, interiorVertex, crossings); // low-to-high
     }
 }
        private void AddCrossingEdge(VisibilityGraph vg, VisibilityVertex lowVertex, VisibilityVertex highVertex, GroupBoundaryCrossing[] crossings) {
            VisibilityEdge edge = null;
            if (null != HighestVisibilityVertex) {
                // We may have a case where point xx.xxxxx8 has added an ascending-direction crossing, and now we're on
                // xx.xxxxx9 adding a descending-direction crossing.  In that case there should already be a VisibilityEdge 
                // in the direction we want.
                if (PointComparer.Equal(this.HighestVisibilityVertex.Point, highVertex.Point)) {
                    edge = vg.FindEdge(lowVertex.Point, highVertex.Point);
                    Debug.Assert(edge != null, "Inconsistent forward-backward sequencing in HighVisibilityVertex");
                } else {
                    AppendHighestVisibilityVertex(lowVertex);
                }
            }
            if (edge == null) {
                edge = AddVisibilityEdge(lowVertex, highVertex);
            }

            var crossingsArray = crossings.Select(c => c.Group.InputShape).ToArray();
            var prevIsPassable = edge.IsPassable;
            if (prevIsPassable == null) {
                edge.IsPassable = delegate { return crossingsArray.Any(s => s.IsTransparent); };
            } else {
                // Because we don't have access to the previous delegate's internals, we have to chain.  Fortunately this
                // will never be more than two deep.  File Test: Groups_Forward_Backward_Between_Same_Vertices.
                edge.IsPassable = delegate { return crossingsArray.Any(s => s.IsTransparent) || prevIsPassable(); };
            }
            if (null == LowestVisibilityVertex) {
                SetInitialVisibilityVertex(lowVertex);
            }
            HighestVisibilityVertex = highVertex;
        }
 private static VisibilityVertex GetCrossingInteriorVertex(VisibilityGraph vg, VisibilityVertex crossingVertex,
         GroupBoundaryCrossing crossing) {
     Point interiorPoint = crossing.GetInteriorVertexPoint(crossingVertex.Point);
     return vg.FindVertex(interiorPoint) ?? vg.AddVertex(interiorPoint);
 }