private bool AppendGroupCrossingsThroughPoint(VisibilityGraph vg, Point lastPoint) { if (null == GroupBoundaryPointAndCrossingsList) { return(false); } bool found = false; while (GroupBoundaryPointAndCrossingsList.CurrentIsBeforeOrAt(lastPoint)) { // We will only create crossing Edges that the segment actually crosses, not those it ends before crossing. // For those terminal crossings, the adjacent segment creates the interior vertex and crossing edge. PointAndCrossings pac = GroupBoundaryPointAndCrossingsList.Pop(); GroupBoundaryCrossing[] lowDirCrossings = null; GroupBoundaryCrossing[] highDirCrossings = null; if (PointComparer.Compare(pac.Location, Start) > 0) { lowDirCrossings = PointAndCrossingsList.ToCrossingArray(pac.Crossings, ScanDirection.OppositeDirection); } if (PointComparer.Compare(pac.Location, End) < 0) { highDirCrossings = PointAndCrossingsList.ToCrossingArray(pac.Crossings, ScanDirection.Direction); } found = true; VisibilityVertex crossingVertex = vg.FindVertex(pac.Location) ?? vg.AddVertex(pac.Location); if ((null != lowDirCrossings) || (null != highDirCrossings)) { AddLowCrossings(vg, crossingVertex, lowDirCrossings); AddHighCrossings(vg, crossingVertex, highDirCrossings); } else { // This is at this.Start with only lower-direction toward group interior(s), or at this.End with only // higher-direction toward group interior(s). Therefore an adjacent ScanSegment will create the crossing // edge, so create the crossing vertex here and we'll link to it. if (null == LowestVisibilityVertex) { SetInitialVisibilityVertex(crossingVertex); } else { Debug.Assert(PointComparer.Equal(End, crossingVertex.Point), "Expected this.End crossingVertex"); AppendHighestVisibilityVertex(crossingVertex); } } } return(found); }
private void SpliceGroupBoundaryCrossing(VisibilityVertex currentVertex, PointAndCrossings pac, Directions dirToInside) { GroupBoundaryCrossing[] crossings = PointAndCrossingsList.ToCrossingArray(pac.Crossings, dirToInside); if (null != crossings) { var outerVertex = VisGraph.FindVertex(pac.Location) ?? AddVertex(pac.Location); if (currentVertex.Point != outerVertex.Point) { FindOrAddEdge(currentVertex, outerVertex); } var interiorPoint = crossings[0].GetInteriorVertexPoint(pac.Location); var interiorVertex = VisGraph.FindVertex(interiorPoint) ?? AddVertex(interiorPoint); // FindOrAddEdge splits an existing edge so may not return the portion bracketed by outerVertex and interiorVertex. FindOrAddEdge(outerVertex, interiorVertex); var edge = VisGraph.FindEdge(outerVertex.Point, interiorVertex.Point); var crossingsArray = crossings.Select(c => c.Group.InputShape).ToArray(); edge.IsPassable = delegate { return(crossingsArray.Any(s => s.IsTransparent)); }; } }