Example #1
0
        private static PolygonCrossing FindPreviousCrossingNotEqual(
            PolygonCrossing currentCrossing,
            PolygonCrossing[] crossingsOnRing,
            IComparer <PolygonCrossing> crossingComparer
            )
        {
            Contract.Requires(currentCrossing != null);
            Contract.Requires(crossingsOnRing != null);
            Contract.Requires(Contract.ForAll(crossingsOnRing, x => x != null));
            Contract.Requires(crossingComparer != null);

            var currentPoint         = currentCrossing.Point;
            int currentCrossingIndex = Array.BinarySearch(crossingsOnRing, currentCrossing, crossingComparer);

            if (currentCrossingIndex < 0)
            {
                return(null);
            }
            int crossingsCount = crossingsOnRing.Length;

            // find the first crossing before this one that has a different point location
            for (
                int i = IterationUtils.RetreatLoopingIndex(currentCrossingIndex, crossingsCount);
                i != currentCrossingIndex;
                i = IterationUtils.RetreatLoopingIndex(i, crossingsCount)
                )
            {
                var crossing = crossingsOnRing[i];
                if (crossing.Point != currentPoint)
                {
                    return(crossing);
                }
            }
            return(null);
        }
Example #2
0
        private static IEnumerable <PolygonCrossing> TraverseCrossings(
            PolygonCrossing fromCrossing,
            PolygonCrossing[] ringCrossings,
            int fromCrossingIndex
            )
        {
            Contract.Requires(fromCrossing != null);
            Contract.Requires(ringCrossings != null);
            //Contract.Requires(crossingComparer != null);
            Contract.Requires(fromCrossingIndex >= 0);
            Contract.Ensures(Contract.Result <IEnumerable <PolygonCrossing> >() != null);

            //var fromCrossingIndex = ringCrossings.BinarySearch(fromCrossing, crossingComparer);
            var ringCrossingsCount = ringCrossings.Length;

            Stack <PolygonCrossing> priorResults = null;
            var backTrackIndex = fromCrossingIndex;

            do
            {
                var priorIndex    = IterationUtils.RetreatLoopingIndex(backTrackIndex, ringCrossingsCount);
                var priorCrossing = ringCrossings[priorIndex];
                if (priorCrossing.Point != fromCrossing.Point)
                {
                    break;
                }

                backTrackIndex = priorIndex;
                (priorResults ?? (priorResults = new Stack <PolygonCrossing>()))
                .Push(priorCrossing);
            } while (backTrackIndex != fromCrossingIndex);

            if (null != priorResults)
            {
                while (priorResults.Count > 0)
                {
                    yield return(priorResults.Pop());
                }
            }

            for (
                int i = IterationUtils.AdvanceLoopingIndex(fromCrossingIndex, ringCrossingsCount);
                i != fromCrossingIndex;
                i = IterationUtils.AdvanceLoopingIndex(i, ringCrossingsCount)
                )
            {
                yield return(ringCrossings[i]);
            }
        }
Example #3
0
        private static Point2 FindPreviousRingPoint(
            PolygonCrossing currentCrossing,
            PolygonCrossing[] crossingsOnRing,
            Ring2 ring,
            Func <PolygonCrossing, PolygonBoundaryLocation> getLocation,
            IComparer <PolygonCrossing> crossingComparer
            )
        {
            Contract.Requires(currentCrossing != null);
            Contract.Requires(crossingsOnRing != null);
            Contract.Requires(Contract.ForAll(crossingsOnRing, x => x != null));
            Contract.Requires(ring != null);
            Contract.Requires(getLocation != null);
            Contract.Requires(crossingComparer != null);

            var currentLocation = getLocation(currentCrossing);
            var segmentCount    = ring.SegmentCount;

            Contract.Assume(currentLocation.SegmentIndex < segmentCount);
            var previousSegmentIndex = IterationUtils.RetreatLoopingIndex(currentLocation.SegmentIndex, segmentCount);
            var previousCrossing     = FindPreviousCrossingNotEqual(currentCrossing, crossingsOnRing, crossingComparer);

            if (null == previousCrossing)
            {
                return(ring[
                           currentLocation.SegmentRatio == 0
                    ? previousSegmentIndex
                    : currentLocation.SegmentIndex
                       ]);
            }
            var previousCrossingLocation = getLocation(previousCrossing);

            Contract.Assume(previousCrossingLocation != null);
            if (currentLocation.SegmentRatio == 0)
            {
                return(previousSegmentIndex == previousCrossingLocation.SegmentIndex
                    ? previousCrossing.Point
                    : ring[previousSegmentIndex]);
            }
            return(currentLocation.SegmentIndex == previousCrossingLocation.SegmentIndex &&
                   currentLocation.SegmentRatio > previousCrossingLocation.SegmentRatio
                ? previousCrossing.Point
                : ring[currentLocation.SegmentIndex]);
        }