Collections Data Structure Java

//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 true 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) {
    return toRatio(value, min, max);
  }
  /**
   * @param ratio
   * @return min + ratio * ( max - min )
   */
  public float toValue(float ratio) {
    return toValue(ratio, min, max);
  }
  /**
   * @param r
   * @return true 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
   * true 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
   * true 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 true 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 true 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
   *         null 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 true 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)} 

   * set xrange [0:1] 

   * set yrange [0:1] 

   * 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);
  }
}