예제 #1
0
        public List <Region> GetClipped(Region clipToRegion, List <Region> excludeRegions = null)
        {
            var clippedIntervals = new List <Region>();

            if (!clipToRegion.IsValid())
            {
                throw new ArgumentException(string.Format("Region {0} is not valid.", clipToRegion));
            }

            for (var i = _lastIndexCleared + 1; i < Intervals.Count; i++)
            {
                var interval = Intervals[i];
                if (interval.StartPosition > clipToRegion.EndPosition)
                {
                    break;
                }

                if (!clipToRegion.Overlaps(interval))
                {
                    continue;
                }

                var clippedInterval = new Region(Math.Max(clipToRegion.StartPosition, interval.StartPosition),
                                                 Math.Min(clipToRegion.EndPosition, interval.EndPosition));

                if (excludeRegions == null)
                {
                    clippedIntervals.Add(clippedInterval);
                }
                else
                {
                    clippedIntervals.AddRange(GetMinus(clippedInterval, excludeRegions));
                }
            }

            return(clippedIntervals);
        }
예제 #2
0
        /// <summary>
        /// Get intervals for a region, minus an overlaps with the exclude regions.
        /// </summary>
        /// <param name="keepRegion">Region to keep</param>
        /// <param name="excludeRegions">List of regions to exclude from the final result.  Assumes regions are sorted.</param>
        /// <returns></returns>
        public static List <Region> GetMinus(Region keepRegion, List <Region> excludeRegions)
        {
            var regions = new List <Region>();

            if (keepRegion == null || !keepRegion.IsValid())
            {
                throw new ArgumentException(string.Format("Region {0} is not valid.", keepRegion));
            }

            if (excludeRegions == null)
            {
                regions.Add(keepRegion);
                return(regions);
            }

            var remainingRegion = new Region(keepRegion.StartPosition, keepRegion.EndPosition);

            foreach (var excludeRegion in excludeRegions)
            {
                if (excludeRegion == null || !excludeRegion.IsValid())
                {
                    throw new ArgumentException(string.Format("Region {0} is not valid.", excludeRegion));
                }

                if (!remainingRegion.Overlaps(excludeRegion))
                {
                    continue;  // no overlap, keep checking other excluded regions
                }
                if (excludeRegion.FullyContains(remainingRegion))
                {
                    remainingRegion = null;  // done, fully excluded
                    break;
                }

                if (remainingRegion.FullyContains(excludeRegion))
                {
                    // need to break up remaining region!
                    var leftRegion  = new Region(remainingRegion.StartPosition, excludeRegion.StartPosition - 1, false);
                    var rightRegion = new Region(excludeRegion.EndPosition + 1, remainingRegion.EndPosition, false);

                    if (leftRegion.IsValid())
                    {
                        regions.Add(leftRegion);
                    }

                    if (!rightRegion.IsValid())
                    {
                        remainingRegion = null; // done, nothing left on right side
                        break;
                    }

                    remainingRegion = rightRegion; // pass right region on for more processing
                }
                else
                {
                    remainingRegion = excludeRegion.ContainsPosition(remainingRegion.StartPosition)
                        ? new Region(excludeRegion.EndPosition + 1, remainingRegion.EndPosition) // clip on left side
                        : new Region(remainingRegion.StartPosition, excludeRegion.StartPosition - 1);
                }
            }

            if (remainingRegion != null)
            {
                regions.Add(remainingRegion);
            }

            return(regions);
        }