001 // License: GPL. For details, see LICENSE file. 002 package 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 */ 009 public 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 }