001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint;
003
004/**
005 * An interval of the form "lower < x <= upper" where 0 <= lower < upper.
006 * (upper can be Double.POSITIVE_INFINITY)
007 * immutable class
008 */
009public class Range {
010    private double lower;
011    private double upper;
012
013    public Range() {
014        this.lower = 0;
015        this.upper = Double.POSITIVE_INFINITY;
016    }
017
018    public Range(double lower, double upper) {
019        if (lower < 0 || lower >= upper)
020            throw new IllegalArgumentException();
021        this.lower = lower;
022        this.upper = upper;
023    }
024
025    public boolean contains(double x) {
026        return lower < x && x <= upper;
027    }
028
029    /**
030     * provides the intersection of 2 overlapping ranges
031     */
032    public static Range cut(Range a, Range b) {
033        if (b.lower >= a.upper || b.upper <= a.lower)
034            throw new IllegalArgumentException();
035        return new Range(Math.max(a.lower, b.lower), Math.min(a.upper, b.upper));
036    }
037
038    /**
039     * under the premise, that x is within this range,
040     * and not within the other range, it shrinks this range in a way
041     * to exclude the other range, but still contain x.
042     *
043     * x                  |
044     *
045     * this   (------------------------------]
046     *
047     * other                   (-------]  or
048     *                         (-----------------]
049     *
050     * result (----------------]
051     */
052    public Range reduceAround(double x, Range other) {
053        if (!contains(x))
054            throw new IllegalArgumentException();
055        if (other.contains(x))
056            throw new IllegalArgumentException();
057
058        if (x < other.lower && other.lower < upper)
059            return new Range(lower, other.lower);
060
061        if (this.lower < other.upper && other.upper < x)
062            return new Range(other.upper, this.upper);
063
064        return this;
065    }
066
067    public double getLower() {
068        return lower;
069    }
070
071    public double getUpper() {
072        return upper;
073    }
074
075    @Override
076    public String toString() {
077        return String.format("|s%s-%s", lower, upper);
078    }
079}