void AddIntersectionOfBothDirectionSweepsToTheResult(VisibilityGraph vg0, VisibilityGraph vg1) { foreach (var edge in vg0.Edges) if (vg1.FindEdge(edge.SourcePoint, edge.TargetPoint) != null) _visibilityGraph.AddEdge(edge.SourcePoint, edge.TargetPoint); }
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; }
static internal VisibilityEdge FindNextEdge(VisibilityGraph vg, VisibilityVertex vertex, Directions dir) { VisibilityVertex nextVertex = FindNextVertex(vertex, dir); return (null == nextVertex) ? null : vg.FindEdge(vertex.Point, nextVertex.Point); }
// Append a vertex before LowestVisibilityVertex or after HighestVisibilityVertex. internal void AppendVisibilityVertex(VisibilityGraph vg, VisibilityVertex newVertex) { Debug.Assert(null != newVertex, "newVertex must not be null"); Debug.Assert((null == LowestVisibilityVertex) == (null == HighestVisibilityVertex), "Mismatched null Lowest/HighestVisibilityVertex"); Debug.Assert(StaticGraphUtility.PointIsOnSegment(this, newVertex.Point), "newVertex is out of segment range"); if (null == HighestVisibilityVertex) { if (!AddGroupCrossingsBeforeHighestVisibilityVertex(vg, newVertex)) { SetInitialVisibilityVertex(newVertex); } } else { // In the event of overlaps where ScanSegments share a Start/End at a border, SegmentIntersector // may be appending the same Vertex twice. If that point is on the border of a group, // then we may have just added the border-crossing edge as well. if (PointComparer.IsPureLower(newVertex.Point, HighestVisibilityVertex.Point)) { Debug.Assert(null != vg.FindEdge(newVertex.Point, HighestVisibilityVertex.Point) , "unexpected low/middle insertion to ScanSegment"); return; } // Add the new edge. This will always be in the ascending direction. if (!AddGroupCrossingsBeforeHighestVisibilityVertex(vg, newVertex)) { AppendHighestVisibilityVertex(newVertex); } } }