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))); } } }
internal IntervalTree(IEnumerable <TItem> items, Func <TItem, Interval <T> > intervalFactory) { _root = new Node(items.Select(i => IntervalItem.Create(i, intervalFactory(i))).ToList()); }