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);
                }
            }
        }