Esempio n. 1
0
 internal static bool IsPureDirection(Directions dir)
 {
     return(CompassVector.IsPureDirection(dir));
 }
// ReSharper restore InconsistentNaming

        #region Direction_Utilities

        // These call through to CompassVector methods, assuming operands that use PointComparer rounding.
        internal static Directions GetDirections(Point a, Point b)
        {
            Assert_Rounded(a);
            Assert_Rounded(b);
            return(CompassVector.DirectionsFromPointToPoint(a, b));
        }
Esempio n. 3
0
 bool EdgeIsParallelToSweepDir(AxisEdge edge)
 {
     return(edge.Direction == SweepPole || edge.Direction == CompassVector.OppositeDir(SweepPole));
 }
Esempio n. 4
0
 internal static bool IsPureDirection(Point a, Point b)
 {
     Assert_Rounded(a);
     Assert_Rounded(b);
     return(CompassVector.IsPureDirection(GetDirections(a, b)));
 }
Esempio n. 5
0
 private int GetNumberOfBends(Directions entryDirToVertex, Directions dirToTarget)
 {
     return(CompassVector.IsPureDirection(dirToTarget)
                             ? GetNumberOfBendsForPureDirection(entryDirToVertex, dirToTarget)
                             : GetBendsForNotPureDirection(dirToTarget, entryDirToVertex, EntryDirectionsToTarget));
 }
Esempio n. 6
0
        bool IsSkippableSpliceSourceWithNullSpliceTarget(VisibilityVertex spliceSource, Directions extendDir)
        {
            if (IsSkippableSpliceSourceEdgeWithNullTarget(StaticGraphUtility.FindNextEdge(VisGraph, spliceSource, extendDir)))
            {
                return(true);
            }
            var spliceSourceEdge = StaticGraphUtility.FindNextEdge(this.VisGraph, spliceSource, CompassVector.OppositeDir(extendDir));

            // Since target is null, if this is a reflection, it is bouncing off an outer side of a group or
            // obstacle at spliceSource.  In that case, we don't want to splice from it because then we could
            // cut through the group and outside again; instead we should just stay outside it.
            return(IsSkippableSpliceSourceEdgeWithNullTarget(spliceSourceEdge) || IsReflectionEdge(spliceSourceEdge));
        }
Esempio n. 7
0
        private static bool GetNextSpliceSource(ref VisibilityVertex spliceSource, Directions spliceTargetDir, Directions extendDir)
        {
            VisibilityVertex nextSpliceSource = StaticGraphUtility.FindNextVertex(spliceSource, extendDir);

            if (null == nextSpliceSource)
            {
                // See if there is a source further away from the extension line - we might have
                // been on freePoint line (or another nearby PortEntry line) that dead-ended.
                // Look laterally from the previous spliceSource first.
                nextSpliceSource = spliceSource;
                for (;;)
                {
                    nextSpliceSource = StaticGraphUtility.FindNextVertex(nextSpliceSource, CompassVector.OppositeDir(spliceTargetDir));
                    if (null == nextSpliceSource)
                    {
                        return(false);
                    }
                    var nextSpliceSourceExtend = StaticGraphUtility.FindNextVertex(nextSpliceSource, extendDir);
                    if (null != nextSpliceSourceExtend)
                    {
                        nextSpliceSource = nextSpliceSourceExtend;
                        break;
                    }
                }
            }
            spliceSource = nextSpliceSource;
            return(true);
        }
Esempio n. 8
0
        // The return value is whether we should try a second pass if this is called on the first pass,
        // using spliceTarget to wrap up dead-ends on the target side.
        bool ExtendSpliceWorker(VisibilityVertex spliceSource, Directions extendDir, Directions spliceTargetDir
                                , LineSegment maxDesiredSegment, LineSegment maxVisibilitySegment
                                , bool isOverlapped, out VisibilityVertex spliceTarget)
        {
            // This is called after having created at least one extension vertex (initially, the
            // first one added outside the obstacle), so we know extendVertex will be there. spliceSource
            // is the vertex to the OppositeDir(spliceTargetDir) of that extendVertex.
            VisibilityVertex extendVertex = StaticGraphUtility.FindNextVertex(spliceSource, spliceTargetDir);

            spliceTarget = StaticGraphUtility.FindNextVertex(extendVertex, spliceTargetDir);
            for (; ;)
            {
                if (!GetNextSpliceSource(ref spliceSource, spliceTargetDir, extendDir))
                {
                    break;
                }

                // spliceSource is now on the correct edge relative to the desired nextExtendPoint.
                // spliceTarget is in the opposite direction of the extension-line-to-spliceSource.
                Point nextExtendPoint = StaticGraphUtility.FindBendPointBetween(extendVertex.Point
                                                                                , spliceSource.Point, CompassVector.OppositeDir(spliceTargetDir));

                // We test below for being on or past maxDesiredSegment; here we may be skipping
                // over maxDesiredSegmentEnd which is valid since we want to be sure to go to or
                // past limitRect, but be sure to stay within maxVisibilitySegment.
                if (IsPointPastSegmentEnd(maxVisibilitySegment, nextExtendPoint))
                {
                    break;
                }

                spliceTarget = GetSpliceTarget(ref spliceSource, spliceTargetDir, nextExtendPoint);

                //StaticGraphUtility.Test_DumpVisibilityGraph(ObstacleTree, VisGraph);

                if (null == spliceTarget)
                {
                    // This may be because spliceSource was created just for Group boundaries.  If so,
                    // skip to the next nextExtendVertex location.
                    if (this.IsSkippableSpliceSourceWithNullSpliceTarget(spliceSource, extendDir))
                    {
                        continue;
                    }

                    // We're at a dead-end extending from the source side, or there is an intervening obstacle, or both.
                    // Don't splice across lateral group boundaries.
                    if (ObstacleTree.SegmentCrossesAnObstacle(spliceSource.Point, nextExtendPoint))
                    {
                        return(false);
                    }
                }

                // We might be walking through a point where a previous chain dead-ended.
                VisibilityVertex nextExtendVertex = VisGraph.FindVertex(nextExtendPoint);
                if (null != nextExtendVertex)
                {
                    if ((null == spliceTarget) || (null != this.VisGraph.FindEdge(extendVertex.Point, nextExtendPoint)))
                    {
                        // We are probably along a ScanSegment so visibility in this direction has already been determined.
                        // Stop and don't try to continue extension from the opposite side.  If we continue splicing here
                        // it might go across an obstacle.
                        if (null == spliceTarget)
                        {
                            Debug_VerifyNonOverlappedExtension(isOverlapped, extendVertex, nextExtendVertex, spliceSource: null, spliceTarget: null);
                            FindOrAddEdge(extendVertex, nextExtendVertex, isOverlapped ? ScanSegment.OverlappedWeight : ScanSegment.NormalWeight);
                        }
                        return(false);
                    }

                    // This should always have been found in the find-the-next-target loop above if there is
                    // a vertex (which would be nextExtendVertex, which we just found) between spliceSource
                    // and spliceTarget.  Even for a sparse graph, an edge should not skip over a vertex.
                    StaticGraphUtility.Assert(spliceTarget == StaticGraphUtility.FindNextVertex(nextExtendVertex, spliceTargetDir)
                                              , "no edge exists between an existing nextExtendVertex and spliceTarget"
                                              , ObstacleTree, VisGraph);
                }
                else
                {
                    StaticGraphUtility.Assert((null == spliceTarget) ||
                                              spliceTargetDir == PointComparer.GetPureDirection(nextExtendPoint, spliceTarget.Point)
                                              , "spliceTarget is not to spliceTargetDir of nextExtendVertex"
                                              , ObstacleTree, VisGraph);
                    nextExtendVertex = this.AddVertex(nextExtendPoint);
                }
                FindOrAddEdge(extendVertex, nextExtendVertex, isOverlapped ? ScanSegment.OverlappedWeight : ScanSegment.NormalWeight);

                Debug_VerifyNonOverlappedExtension(isOverlapped, extendVertex, nextExtendVertex, spliceSource, spliceTarget);

                // This will split the edge if targetVertex is non-null; otherwise we are at a dead-end
                // on the target side so must not create a vertex as it would be inside an obstacle.
                FindOrAddEdge(spliceSource, nextExtendVertex, isOverlapped ? ScanSegment.OverlappedWeight : ScanSegment.NormalWeight);
                if (isOverlapped)
                {
                    isOverlapped = this.SeeIfSpliceIsStillOverlapped(extendDir, nextExtendVertex);
                }
                extendVertex = nextExtendVertex;

                // Test GetDirections because it may return Directions. None.
                if (0 == (extendDir & PointComparer.GetDirections(nextExtendPoint, maxDesiredSegment.End)))
                {
                    // At or past the desired max extension point, so we're done.
                    spliceTarget = null;
                    break;
                }
            }
            return(null != spliceTarget);
        }
Esempio n. 9
0
        static int CompareTwoPathEdges(PathEdge x, PathEdge y)
        {
            if (x == y)
            {
                return(0);
            }
            Debug.Assert(x.AxisEdge == y.AxisEdge);
            //Nudger.ShowOrderedPaths(null, new[] { x.Path, y.Path }, x.AxisEdge.SourcePoint, x.AxisEdge.TargetPoint);
            int r = CompareInDirectionStartingFromAxisEdge(x, y, x.AxisEdge, x.AxisEdge.Direction);

            return(r != 0 ? r : -CompareInDirectionStartingFromAxisEdge(x, y, x.AxisEdge, CompassVector.OppositeDir(x.AxisEdge.Direction)));
        }