Esempio n. 1
0
        internal static IEnumerable <IntervalItem <TRangeItem, T> > Split <TRangeItem, T>(IntervalItem <TRangeItem, T> first, IntervalItem <TRangeItem, T> second) where T : IComparable <T>
        {
            if (first.Interval.Equals(second.Interval))
            {
                yield return(first);

                yield return(second);

                yield break;
            }

            SortEndPoints(first.Interval, second.Interval, out var leftMin, out var rightMin, out var leftMax, out var rightMax);

            var minMaxCompare = rightMin.Value.CompareTo(leftMax.Value);

            if (minMaxCompare > 0)
            {
                yield return(first);

                yield return(second);
            }
            else
            {
                var leftMinItem  = leftMin.RangeIndex == 0 ? first.Item : second.Item;
                var rightMinItem = rightMin.RangeIndex == 0 ? first.Item : second.Item;

                if (leftMin.RangeIndex == rightMax.RangeIndex)
                {
                    // Outer
                    yield return(new IntervalItem <TRangeItem, T>(leftMinItem, new Interval <T>(leftMin.Value, leftMin.EndPoint, rightMin.Value, InverseEndPoint(rightMin.EndPoint))));

                    yield return(new IntervalItem <TRangeItem, T>(leftMinItem, new Interval <T>(rightMin.Value, rightMin.EndPoint, leftMax.Value, leftMax.EndPoint)));

                    yield return(new IntervalItem <TRangeItem, T>(leftMinItem, new Interval <T>(leftMax.Value, InverseEndPoint(leftMax.EndPoint), rightMax.Value, rightMax.EndPoint)));

                    // Inner
                    yield return(new IntervalItem <TRangeItem, T>(rightMinItem, new Interval <T>(rightMin.Value, rightMin.EndPoint, leftMax.Value, leftMax.EndPoint)));
                }
                else
                {
                    // Left
                    yield return(new IntervalItem <TRangeItem, T>(leftMinItem, new Interval <T>(leftMin.Value, leftMin.EndPoint, rightMin.Value, InverseEndPoint(rightMin.EndPoint))));

                    yield return(new IntervalItem <TRangeItem, T>(leftMinItem, new Interval <T>(rightMin.Value, rightMin.EndPoint, leftMax.Value, leftMax.EndPoint)));

                    // Right
                    yield return(new IntervalItem <TRangeItem, T>(rightMinItem, new Interval <T>(rightMin.Value, rightMin.EndPoint, leftMax.Value, leftMax.EndPoint)));

                    yield return(new IntervalItem <TRangeItem, T>(rightMinItem, new Interval <T>(leftMax.Value, InverseEndPoint(leftMax.EndPoint), rightMax.Value, rightMax.EndPoint)));
                }
            }
        }
Esempio n. 2
0
 internal IntervalTree(IEnumerable <TItem> items, Func <TItem, Interval <T> > intervalFactory)
 {
     _root = new Node(items.Select(i => IntervalItem.Create(i, intervalFactory(i))).ToList());
 }