/* * @(#)NumericRange.java * * 2002 - 2012 JIDE Software Incorporated. All rights reserved. * Copyright (c) 2005 - 2012 Catalysoft Limited. All rights reserved. */ package com.jidesoft.range; /** * Specifies upper and lower bounds for a range of values * * @author Simon */ public class NumericRange extends AbstractNumericRange<Double> { protected double _min; protected double _max; /** * Creates a numeric range with minimum 0.0 and maximum of 1.0 */ public NumericRange() { this(0.0, 1.0); } /** * Create a numeric range by supplying minimum and maximum values * * @param min the minumum * @param max the maximum */ public NumericRange(double min, double max) { super(); _min = Math.min(min, max); _max = Math.max(min, max); } /** * Creates a copy of the supplied NumericRange * * @param numericRange the NumericRange instance to copy */ public NumericRange(NumericRange numericRange) { this(numericRange.minimum(), numericRange.maximum()); } @Override public Range<Double> copy() { return new NumericRange(this); } /** * @return the minimum value */ public double minimum() { return _min; } /** * @return the maximum value */ public double maximum() { return _max; } /** * @return the minimum value */ public double getMin() { return _min; } /** * Sets the minimum value * * @param min the new minimum value. */ public void setMin(double min) { double old = _min; if (old == min) { return; } assert min <= _max; _min = min; firePropertyChange(PROPERTY_MIN, old, min); } /** * @return the maximum value */ public double getMax() { return _max; } /** * Sets the maximum value * * @param max the new maximum value. */ public void setMax(double max) { double old = _max; if (old == max) { return; } assert max >= _min; _max = max; firePropertyChange(PROPERTY_MAX, old, max); } /** * @return the size of the range */ public double size() { return _max - _min; } /** * @return the minimum() value for the range */ public Double lower() { return minimum(); } /** * Sets the minimum and maximum values of the range in a single call */ public void adjust(Double lower, Double upper) { double size = size(); // save it if (lower != null) { setMin(lower); } else if (upper != null) { setMin(upper - size); } if (upper != null) { setMax(upper); } else if (lower != null) { setMin(lower + size); } } /** * @return the maximum() value for the range */ public Double upper() { return maximum(); } /** * Determines whether the range contains the supplied value */ public boolean contains(Double x) { return x != null && x >= _min && x <= _max; } /** * Creates a new NumericRange by enlarging this numeric range about its mid-point. For example to make it 10% * bigger, use a stretch factor of 1.1. Note that this method can also be used to shrink a NumericRange. * * @param stretchFactor the multiplication factor for the enlargement * @return a new NumericRange */ public NumericRange stretch(double stretchFactor) { return stretch(stretchFactor, stretchFactor); } /** * Creates a new NumericRange by enlarging this numeric range about its mid-point. For example to make it 10% * bigger, use a stretch factor of 1.1. Note that this method can also be used to shrink a NumericRange. * * @param stretchFactorForLower the multiplication factor for the enlargement for the lower range * @param stretchFactorForUpper the multiplication factor for the enlargement for the upper range * @return a new NumericRange */ public NumericRange stretch(double stretchFactorForLower, double stretchFactorForUpper) { double mid = (_max + _min) / 2.0; double halfSize = size() / 2.0; return new NumericRange(mid - halfSize * stretchFactorForLower, mid + halfSize * stretchFactorForUpper); } public Range<Double> createIntermediate(Range<Double> target, double position) { double sourceMin = this.minimum(); double sourceMax = this.maximum(); double targetMin = target.minimum(); double targetMax = target.maximum(); double min = sourceMin + position * (targetMin - sourceMin); double max= sourceMax + position * (targetMax - sourceMax); return new NumericRange(min, max); } /** * Test for equality based on the values of min and max */ @Override public boolean equals(Object other) { if (other instanceof NumericRange) { NumericRange otherRange = (NumericRange) other; return _min == otherRange._min && _max == otherRange._max; } else { return false; } } @Override public int hashCode() { return (int)(_max * 29 + _min); } @Override public String toString() { return String.format("#<NumericRange min=%f max=%f>", _min, _max); } /** * Creates a new NumericRange as the union of two existing NumericRanges. The date format of the first time range is * retained in the returned result. * * @param r1 the first NumericRange * @param r2 the second NumericRange * @return the union of the supplied NumericRanges */ public static NumericRange union(NumericRange r1, NumericRange r2) { if (r1 == null) { return r2; } else if (r2 == null) { return r1; } double r1Min = r1._min; double r2Min = r2._min; double r1Max = r1._max; double r2Max = r2._max; double min = Math.min(r1Min, r2Min); double max = Math.max(r1Max, r2Max); return new NumericRange(min, max); } }