package org.chartsy.main.utils;
import java.io.Serializable;
/**
*
* @author viorel.gheba
*/
public strictfp class Range implements Serializable {
private static final long serialVersionUID = SerialVersion.APPVERSION;
private double lower;
private double upper;
public Range() {
this(0, 1);
}
public Range(double lower, double upper) {
this.lower = Math.min(lower, upper);
this.upper = Math.max(lower, upper);
}
public double getLowerBound() {
return this.lower;
}
public double getUpperBound() {
return this.upper;
}
public double getLength() {
if (lower >= 0 && upper >= 0) return upper - lower;
else if (lower < 0 && upper >= 0) return upper + Math.abs(lower);
else return Math.abs(lower) - Math.abs(upper);
}
public boolean contains(double value) {
return (value >= this.lower && value <= this.upper);
}
public boolean intersects(double b0, double b1) {
if (b0 <= this.lower) {
return (b1 > this.lower);
} else {
return (b0 <= this.upper && b1 >= b0);
}
}
public boolean intersects(Range range) {
return this.intersects(range.getLowerBound(), range.getUpperBound());
}
public double constrain(double value) {
double result = value;
if (!contains(value)) {
if (value > this.upper) {
result = this.upper;
} else if (value < this.lower) {
result = this.lower;
}
}
return result;
}
public static Range combine(Range r1, Range r2) {
if (r1 == null) {
return r2;
} else {
if (r2 == null) {
return r1;
} else {
double l = Math.min(r1.getLowerBound(), r2.getLowerBound());
double u = Math.max(r1.getUpperBound(), r2.getUpperBound());
return new Range(l, u);
}
}
}
public static Range combineNotZero(Range r1, Range r2)
{
if (r1 == null) {
return r2;
} else {
if (r2 == null) {
return r1;
} else {
if (r2.getLowerBound() > 0) {
double l = Math.min(r1.getLowerBound(), r2.getLowerBound());
double u = Math.max(r1.getUpperBound(), r2.getUpperBound());
return new Range(
Math.min(l, u),
Math.max(l, u));
} else {
double l = r1.getLowerBound();
double u = Math.max(r1.getUpperBound(), r2.getUpperBound());
return new Range(
Math.min(l, u),
Math.max(l, u));
}
}
}
}
public static Range expandToInclude(Range range, double value) {
if (range == null) {
return new Range(value, value);
}
if (value < range.getLowerBound()) {
return new Range(value, range.getUpperBound());
} else if (value > range.getUpperBound()) {
return new Range(range.getLowerBound(), value);
} else {
return range;
}
}
public static Range expand(Range range, double lowerMargin, double upperMargin) {
if (range == null) {
throw new IllegalArgumentException("Null 'range' argument.");
}
double length = range.getLength();
double lower = range.getLowerBound() - length * lowerMargin;
double upper = range.getUpperBound() + length * upperMargin;
if (lower > upper) {
lower = lower / 2.0 + upper / 2.0;
upper = lower;
}
return new Range(lower, upper);
}
public static Range shift(Range base, double delta) {
return shift(base, delta, false);
}
public static Range shift(Range base, double delta, boolean allowZeroCrossing) {
if (base == null) {
throw new IllegalArgumentException("Null 'base' argument.");
}
if (allowZeroCrossing) {
return new Range(base.getLowerBound() + delta, base.getUpperBound() + delta);
} else {
return new Range(shiftWithNoZeroCrossing(base.getLowerBound(), delta), shiftWithNoZeroCrossing(base.getUpperBound(), delta));
}
}
private static double shiftWithNoZeroCrossing(double value, double delta) {
if (value > 0.0) {
return Math.max(value + delta, 0.0);
} else if (value < 0.0) {
return Math.min(value + delta, 0.0);
} else {
return value + delta;
}
}
public static Range scale(Range base, double factor) {
if (base == null) {
throw new IllegalArgumentException("Null 'base' argument.");
}
if (factor < 0) {
throw new IllegalArgumentException("Negative 'factor' argument.");
}
return new Range(base.getLowerBound() * factor, base.getUpperBound() * factor);
}
public boolean equals(Object obj) {
if (!(obj instanceof Range)) {
return false;
}
Range range = (Range) obj;
if (!(this.lower == range.lower)) {
return false;
}
if (!(this.upper == range.upper)) {
return false;
}
return true;
}
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(this.lower);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(this.upper);
result = 29 * result + (int) (temp ^ (temp >>> 32));
return result;
}
public String toString() {
return ("Range[" + this.lower + "," + this.upper + "]");
}
}