/// <summary> /// Determines the intersection of an <see cref="IntervalCollection<T>"/>. /// </summary> /// <typeparam name="T">The value type of the intervals.</typeparam> /// <param name="collection">A collection of <see cref="Interval<T>"/>.</param> /// <returns>An <see cref="Interval<T>"/> that contains elements belonging to all intervals in the <paramref name="collection"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="collection"/> is <c>null</c>.</exception> internal static Interval <T> IntersectionOf <T>(IntervalCollection <T> collection) { if (collection == null) { throw new ArgumentNullException("collection"); } if (collection.Count == 0) { return(Interval.Empty <T>()); } var a = collection[0]; for (int i = 1; i < collection.Count; i++) { var b = collection[i]; a = Interval.IntersectionOf(a, b); } return(a); }
/// <summary> /// Determines the intersection of two intervals. /// </summary> /// <typeparam name="T">The value type of the intervals.</typeparam> /// <param name="a">The first interval.</param> /// <param name="b">The second interval.</param> /// <returns>An <see cref="Interval<T>"/> that contains all elements of <paramref name="a"/> /// that also belong to <paramref name="b"/> (or equivalently, all elements of <paramref name="b"/> /// that also belong to <paramref name="a"/>), but no other elements.</returns> /// <seealso href="http://en.wikipedia.org/wiki/Intersection_(set_theory)">Intersection (set theory)</seealso> private static Interval <T> IntersectionOf <T>(Interval <T> a, Interval <T> b) { if (Interval.IsNullOrEmpty(a)) { return(a); } if (Interval.IsNullOrEmpty(b)) { return(b); } var lowestBound = Bound.Min(a.LowerBound, b.LowerBound); var upmostValue = Bound.Max(a.UpperBound, b.UpperBound); var lowerBound = default(Bound <T>); var upperBound = default(Bound <T>); // a //------------- // b // --------- if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, a.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } // a // --------- // b //------------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, b.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } // a //--------- // b // ------------- else if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, b.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } // a // ------------- // b //--------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, a.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } else { return(Interval.Empty <T>()); } Interval <T> result; return(TryParse(lowerBound, upperBound, out result) ? result : Interval.Empty <T>()); }