# A numerical interval : Range « Collections Data Structure « Java

A numerical interval

```
//package com.ryanm.droid.rugl.util.math;

/**
* A numerical interval
*
* @author ryanm
*/
public class Range {
/**
* The lower value
*/
private float min = 0;

/**
* The upper value
*/
private float max = 0;

/**
* @param min
* @param max
*/
public Range(float min, float max) {
set(min, max);
}

/**
* @param r
* @param dest
* @return <code>true</code> if the intersection exists
*/
public boolean intersection(Range r, Range dest) {
if (intersects(r)) {
dest.set(Math.max(min, r.min), Math.min(max, r.max));
return true;
}

return false;
}

/**
* @param value
* @return true if the value lies between the min and max values,
*         inclusively
*/
public boolean contains(float value) {
return min <= value && max >= value;
}

/**
* @param min
* @param max
*/
public void set(float min, float max) {
this.min = min;
this.max = max;

sort();
}

/**
* @param r
*/
public void set(Range r) {
set(r.getMin(), r.getMax());
}

/**
* @return The difference between min and max
*/
public float getSpan() {
return max - min;
}

/**
* @return The lower range boundary
*/
public float getMin() {
return min;
}

/**
* @param min
*/
public void setMin(float min) {
this.min = min;

sort();
}

/**
* @return The upper range boundary
*/
public float getMax() {
return max;
}

/**
* @param max
*/
public void setMax(float max) {
this.max = max;

sort();
}

private void sort() {
if (min > max) {
float t = min;
min = max;
max = t;
}
}

/**
* Limits a value to lie within this range
*
* @param v
*            The value to limit
* @return min if v < min, max if v > max, otherwise v
*/
public float limit(float v) {
return limit(v, min, max);
}

/**
* Wraps a value into this range, modular arithmetic style
*
* @param v
* @return The wrapped value
*/
public float wrap(float v) {
return wrap(v, min, max);
}

/**
* @param value
* @return The proportion of the distance between min and max that value
*         lies from min
*/
public float toRatio(float value) {
}

/**
* @param ratio
* @return min + ratio * ( max - min )
*/
public float toValue(float ratio) {
}

/**
* @param r
* @return <code>true</code> if the ranges have values in common
*/
public boolean intersects(Range r) {
return overlaps(min, max, r.min, r.max);
}

/**
* Alters this range such that {@link #contains(float)} returns
* <code>true</code> for f
*
* @param f
*/
public void encompass(float f) {
if (f < min) {
min = f;
} else if (f > max) {
max = f;
}
}

/**
* Alters this range such that {@link #contains(float)} returns
* <code>true</code> for all values in r
*
* @param r
*/
public void encompass(Range r) {
encompass(r.min);
encompass(r.max);
}

@Override
public String toString() {
return "[ " + min + " : " + max + " ]";
}

/**
* Limits a value to lie within some range
*
* @param v
* @param min
* @param max
* @return min if v < min, max if v > max, otherwise v
*/
public static float limit(float v, float min, float max) {
if (v < min) {
v = min;
} else if (v > max) {
v = max;
}

return v;
}

/**
* Wraps a value into a range, in a modular arithmetic style (but it works
* for negatives too)
*
* @param v
* @param min
* @param max
* @return the wrapped value
*/
public static float wrap(float v, float min, float max) {
v -= min;
max -= min;

if (v < 0) {
v += max * ((int) (-v / max) + 1);
}

v %= max;

return v + min;
}

/**
* @param v
* @param min
* @param max
* @return The proportion of the distance between min and max that v lies
*         from min
*/
public static float toRatio(float v, float min, float max) {
float d = v - min;
float e = max - min;

return d / e;
}

/**
* @param ratio
* @param min
* @param max
* @return min + ratio * ( max - min )
*/
public static float toValue(float ratio, float min, float max) {
return min + ratio * (max - min);
}

/**
* @param value
* @param min
* @param max
* @return <code>true</code> if value lies within min and max, inclusively
*/
public static boolean inRange(float value, float min, float max) {
return value >= min && value <= max;
}

/**
* @param minA
* @param maxA
* @param minB
* @param maxB
* @return <code>true</code> if the ranges overlap
*/
public static boolean overlaps(float minA, float maxA, float minB,
float maxB) {
assert minA <= maxA;
assert minB <= maxB;

return !(minA > maxB || maxA < minB);
}

/**
* @param a
*            a static range
* @param b
*            a mobile range
* @param bv
*            The velocity of b
* @return The time period over which a and b intersect, or
*         <code>null</code> if they never do
*/
public static Range intersectionTime(Range a, Range b, float bv) {
if (bv == 0) { // nobody likes division by zero
if (a.intersects(b)) { // continual intersection
return new Range(-Float.MAX_VALUE, Float.MAX_VALUE);
} else { // no intersection
return null;
}
}

// time when low edge of a meets high edge of b
float t1 = (a.getMin() - b.getMax()) / bv;
// time when high edge of a meets low edge of b
float t2 = (a.getMax() - b.getMin()) / bv;

// constructor sorts the times into proper order
return new Range(t1, t2);
}

/**
* @param minA
* @param maxA
* @param minB
* @param maxB
* @return <code>true</code> if rangeA contains rangeB
*/
public static boolean contains(float minA, float maxA, float minB,
float maxB) {
return minA <= minB && maxA >= maxB;
}

/**
* @param minA
* @param maxA
* @param minB
* @param maxB
* @return The size of the intersection of the two ranges
*/
public static float intersection(float minA, float maxA, float minB,
float maxB) {
float highMin = Math.max(minA, minB);
float lowMax = Math.min(maxA, maxB);

if (lowMax > highMin) {
return lowMax - highMin;
}

return 0;
}

/**
* Shifts the range
*
* @param d
*/
public void translate(float d) {
min += d;
max += d;
}

/**
* Scales the range around the origin
*
* @param s
*/
public void scale(float s) {
min *= s;
max *= s;
}

/**
* Smooth interpolation between min and max. Copy the following into gnuplot
* to see the difference between {@link #smooth(float, float, float)} and
* {@link #smooth2(float, float, float)} <br>
* set xrange [0:1] <br>
* set yrange [0:1] <br>
* plot (x**2*(3-2*x)) title "smooth", x**3*(10+x*(-15+6*x)) title "smooth2"
*
* @param ratio
*            in range 0-1
* @param min
*            minimum output value
* @param max
*            maximum output value
* @return first-order continuous graduation between min and max
* @see #smooth2(float, float, float)
*/
public static final float smooth(float ratio, float min, float max) {
return toValue(ratio * ratio * (3.0f - (ratio + ratio)), min, max);
}

/**
* Smooth interpolation between min and max
*
* @param ratio
*            in range 0-1
* @param min
*            minimum output value
* @param max
*            maximum output value
* @return all-derivation continuous graduation between min and max
* @see Range#smooth(float, float, float)
*/
public static final float smooth2(float ratio, float min, float max) {
float t3 = ratio * ratio * ratio;

return toValue(t3 * (10.f + ratio * (-15.f + 6.f * ratio)), min, max);
}
}

```

### Related examples in the same category

 1 Represents a sequence of integer values, either ascending or descending. 2 This constructs an Iterator over each day in a date range defined by a focus date and range style. 3 Finds the value in the range (start,limit) of the largest element (rank) where the count of all smaller elements in that range is less than or equals target. 4 IntRange represents an inclusive range of ints. 5 LongRange represents an inclusive range of longs. 6 Byte Range 7 NumberRange represents an inclusive range of java.lang.Number objects of the same type. 8 Represents a range of Number objects. 9 A numeric range has a high, low, mean, root-mean-square, standard deviation, and the count of how many samples it contains. 10 A range of integers. 11 Value Range generic structure 12 Long Range 13 Class for storing start and end integer offsets. 14 Integer Sequence Generator