private FIQueryIntervals() { this.intersect = false; this.numIntersections = 0; this.overlap = new[] { 0.0, 0.0 }; this.type = FIQueryIntervalsType.IsEmpty; this.firstTime = 0.0; this.lastTime = 0.0; }
// Static query. public FIQueryIntervals(double[] interval0, double[] interval1) : this() { if (interval0[1] < interval1[0] || interval0[0] > interval1[1]) { this.numIntersections = 0; this.overlap[0] = 0.0; this.overlap[1] = 0.0; this.type = FIQueryIntervalsType.IsEmpty; } else if (interval0[1] > interval1[0]) { if (interval0[0] < interval1[1]) { this.overlap[0] = (interval0[0] < interval1[0] ? interval1[0] : interval0[0]); this.overlap[1] = (interval0[1] > interval1[1] ? interval1[1] : interval0[1]); if (this.overlap[0] < this.overlap[1]) { this.numIntersections = 2; this.type = FIQueryIntervalsType.IsFinite; } else { this.numIntersections = 1; this.type = FIQueryIntervalsType.IsPoint; } } else // interval0[0] == interval1[1] { this.numIntersections = 1; this.overlap[0] = interval0[0]; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } } else // interval0[1] == interval1[0] { this.numIntersections = 1; this.overlap[0] = interval0[1]; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } this.intersect = this.numIntersections > 0; }
// Dynamic query. Current time is 0, maxTime > 0 is required. public FIQueryIntervals(double maxTime, double[] interval0, double speed0, double[] interval1, double speed1) : this() { this.type = FIQueryIntervalsType.IsDynamicQuery; if (interval0[1] < interval1[0]) { // interval0 initially to the left of interval1. double diffSpeed = speed0 - speed1; if (diffSpeed > 0.0) { // The intervals must move towards each other. 'intersect' // is true when the intervals will intersect by maxTime. double diffPos = interval1[0] - interval0[1]; this.intersect = (diffPos <= maxTime * diffSpeed); this.numIntersections = 1; this.firstTime = diffPos / diffSpeed; this.lastTime = (interval1[1] - interval0[0]) / diffSpeed; this.overlap[0] = interval0[0] + this.firstTime * speed0; this.overlap[1] = this.overlap[0]; } } else if (interval0[0] > interval1[1]) { // interval0 initially to the right of interval1. double diffSpeed = speed1 - speed0; if (diffSpeed > 0.0) { // The intervals must move towards each other. 'intersect' // is true when the intervals will intersect by maxTime. double diffPos = interval0[0] - interval1[1]; this.intersect = (diffPos <= maxTime * diffSpeed); this.numIntersections = 1; this.firstTime = diffPos / diffSpeed; this.lastTime = (interval0[1] - interval1[0]) / diffSpeed; this.overlap[0] = interval1[1] + this.firstTime * speed1; this.overlap[1] = this.overlap[0]; } } else { // The intervals are initially intersecting. this.intersect = true; this.firstTime = 0.0; if (speed1 > speed0) { this.lastTime = (interval0[1] - interval1[0]) / (speed1 - speed0); } else if (speed1 < speed0) { this.lastTime = (interval1[1] - interval0[0]) / (speed0 - speed1); } else { this.lastTime = double.MaxValue; } if (interval0[1] > interval1[0]) { if (interval0[0] < interval1[1]) { this.numIntersections = 2; this.overlap[0] = (interval0[0] < interval1[0] ? interval1[0] : interval0[0]); this.overlap[1] = (interval0[1] > interval1[1] ? interval1[1] : interval0[1]); } else // interval0[0] == interval1[1] { this.numIntersections = 1; this.overlap[0] = interval0[0]; this.overlap[1] = this.overlap[0]; } } else // interval0[1] == interval1[0] { this.numIntersections = 1; this.overlap[0] = interval0[1]; this.overlap[1] = this.overlap[0]; } } // The this constructor sets the correct state for no-intersection. }
public FIQueryIntervals(double a0, bool isPositiveInfinite0, double a1, bool isPositiveInfinite1) : this() { if (isPositiveInfinite0) { if (isPositiveInfinite1) { // overlap[1] is +infinity, but set it to +1 because double // might not have a representation for +infinity. The // type indicates the interval is positive-infinite, so // the +1 is a reminder that overlap[1] is +infinity. this.numIntersections = 1; this.overlap[0] = Math.Max(a0, a1); this.overlap[1] = 1.0; this.type = FIQueryIntervalsType.IsPositiveInfinite; } else // interval1 is negative-infinite { if (a0 > a1) { this.numIntersections = 0; this.overlap[0] = 0.0; this.overlap[1] = 0.0; this.type = FIQueryIntervalsType.IsEmpty; } else if (a0 < a1) { this.numIntersections = 2; this.overlap[0] = a0; this.overlap[1] = a1; this.type = FIQueryIntervalsType.IsFinite; } else // a0 == a1 { this.numIntersections = 1; this.overlap[0] = a0; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } } } else // interval0 is negative-infinite { if (isPositiveInfinite1) { if (a0 < a1) { this.numIntersections = 0; this.overlap[0] = 0.0; this.overlap[1] = 0.0; this.type = FIQueryIntervalsType.IsEmpty; } else if (a0 > a1) { this.numIntersections = 2; this.overlap[0] = a1; this.overlap[1] = a0; this.type = FIQueryIntervalsType.IsFinite; } else { this.numIntersections = 1; this.overlap[0] = a1; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } this.intersect = a0 >= a1; } else // interval1 is negative-infinite { // overlap[0] is -infinity, but set it to -1 because double // might not have a representation for -infinity. The // type indicates the interval is negative-infinite, so // the -1 is a reminder that overlap[0] is -infinity. this.numIntersections = 1; this.overlap[0] = -1.0; this.overlap[1] = Math.Min(a0, a1); this.type = FIQueryIntervalsType.IsNegativeInfinite; } } this.intersect = (this.numIntersections > 0); }
// Static queries where at least one interval is semiinfinite. The // two types of semiinfinite intervals are [a,+infinity), which I call // a positive-infinite interval, and (-infinity,a], which I call a // negative-infinite interval. public FIQueryIntervals(double[] finite, double a, bool isPositiveInfinite) : this() { if (isPositiveInfinite) { if (finite[1] > a) { this.overlap[0] = Math.Max(finite[0], a); this.overlap[1] = finite[1]; if (this.overlap[0] < this.overlap[1]) { this.numIntersections = 2; this.type = FIQueryIntervalsType.IsFinite; } else { this.numIntersections = 1; this.type = FIQueryIntervalsType.IsPoint; } } else if (Math.Abs(finite[1] - a) < double.Epsilon) { this.numIntersections = 1; this.overlap[0] = a; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } else { this.numIntersections = 0; this.overlap[0] = 0.0; this.overlap[1] = 0.0; this.type = FIQueryIntervalsType.IsEmpty; } } else // is negative-infinite { if (finite[0] < a) { this.overlap[0] = finite[0]; this.overlap[1] = Math.Min(finite[1], a); if (this.overlap[0] < this.overlap[1]) { this.numIntersections = 2; this.type = FIQueryIntervalsType.IsFinite; } else { this.numIntersections = 1; this.type = FIQueryIntervalsType.IsPoint; } } else if (Math.Abs(finite[0] - a) < double.Epsilon) { this.numIntersections = 1; this.overlap[0] = a; this.overlap[1] = this.overlap[0]; this.type = FIQueryIntervalsType.IsPoint; } else { this.numIntersections = 0; this.overlap[0] = 0.0; this.overlap[1] = 0.0; this.type = FIQueryIntervalsType.IsEmpty; } } this.intersect = (this.numIntersections > 0); }