Exemplo n.º 1
0
        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)); };
            }
        }