Exemplo n.º 1
0
        private void SpliceGroupBoundaryCrossings(PointAndCrossingsList crossingList, VisibilityVertex startVertex, LineSegment maxSegment)
        {
            if ((null == crossingList) || (0 == crossingList.Count))
            {
                return;
            }

            crossingList.Reset();
            var start = maxSegment.Start;
            var end   = maxSegment.End;
            var dir   = PointComparer.GetPureDirection(start, end);

            // Make sure we are going in the ascending direction.
            if (!StaticGraphUtility.IsAscending(dir))
            {
                start = maxSegment.End;
                end   = maxSegment.Start;
                dir   = CompassVector.OppositeDir(dir);
            }

            // We need to back up to handle group crossings that are between a VisibilityBorderIntersect on a sloped border and the
            // incoming startVertex (which is on the first ScanSegment in Perpendicular(dir) that is outside that padded border).
            startVertex = TraverseToFirstVertexAtOrAbove(startVertex, start, CompassVector.OppositeDir(dir));

            // Splice into the Vertices between and including the start/end points.
            for (var currentVertex = startVertex; null != currentVertex; currentVertex = StaticGraphUtility.FindNextVertex(currentVertex, dir))
            {
                bool isFinalVertex = (PointComparer.Compare(currentVertex.Point, end) >= 0);
                while (crossingList.CurrentIsBeforeOrAt(currentVertex.Point))
                {
                    PointAndCrossings pac = crossingList.Pop();

                    // If it's past the start and at or before the end, splice in the crossings in the descending direction.
                    if (PointComparer.Compare(pac.Location, startVertex.Point) > 0)
                    {
                        if (PointComparer.Compare(pac.Location, end) <= 0)
                        {
                            SpliceGroupBoundaryCrossing(currentVertex, pac, CompassVector.OppositeDir(dir));
                        }
                    }

                    // If it's at or past the start and before the end, splice in the crossings in the descending direction.
                    if (PointComparer.Compare(pac.Location, startVertex.Point) >= 0)
                    {
                        if (PointComparer.Compare(pac.Location, end) < 0)
                        {
                            SpliceGroupBoundaryCrossing(currentVertex, pac, dir);
                        }
                    }
                }

                if (isFinalVertex)
                {
                    break;
                }
            }
        }
Exemplo n.º 2
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 SpliceGroupBoundaryCrossings(PointAndCrossingsList crossingList, VisibilityVertex startVertex, LineSegment maxSegment) {
            if ((null == crossingList) || (0 == crossingList.Count)) {
                return;
            }
            crossingList.Reset();
            var start = maxSegment.Start;
            var end = maxSegment.End;
            var dir = PointComparer.GetPureDirection(start, end);

            // Make sure we are going in the ascending direction.
            if (!StaticGraphUtility.IsAscending(dir)) {
                start = maxSegment.End;
                end = maxSegment.Start;
                dir = CompassVector.OppositeDir(dir);
            } 

            // We need to back up to handle group crossings that are between a VisibilityBorderIntersect on a sloped border and the
            // incoming startVertex (which is on the first ScanSegment in Perpendicular(dir) that is outside that padded border).
            startVertex = TraverseToFirstVertexAtOrAbove(startVertex, start, CompassVector.OppositeDir(dir));

            // Splice into the Vertices between and including the start/end points.
            for (var currentVertex = startVertex; null != currentVertex; currentVertex = StaticGraphUtility.FindNextVertex(currentVertex, dir)) {
                bool isFinalVertex = (PointComparer.Compare(currentVertex.Point, end) >= 0);
                while (crossingList.CurrentIsBeforeOrAt(currentVertex.Point)) {
                    PointAndCrossings pac = crossingList.Pop();

                    // If it's past the start and at or before the end, splice in the crossings in the descending direction.
                    if (PointComparer.Compare(pac.Location, startVertex.Point) > 0) {
                        if (PointComparer.Compare(pac.Location, end) <= 0) {
                            SpliceGroupBoundaryCrossing(currentVertex, pac, CompassVector.OppositeDir(dir));
                        }
                    }

                    // If it's at or past the start and before the end, splice in the crossings in the descending direction.
                    if (PointComparer.Compare(pac.Location, startVertex.Point) >= 0)
                    {
                        if (PointComparer.Compare(pac.Location, end) < 0) {
                            SpliceGroupBoundaryCrossing(currentVertex, pac, dir);
                        }
                    }
                }

                if (isFinalVertex) {
                    break;
                }
            }
        }