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) {
    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 <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