HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
interval.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_GF_INTERVAL_H
8 #define PXR_BASE_GF_INTERVAL_H
9 
10 /// \file gf/interval.h
11 /// \ingroup group_gf_BasicMath
12 
13 #include "pxr/pxr.h"
14 #include "pxr/base/gf/math.h"
15 #include "pxr/base/gf/api.h"
16 #include "pxr/base/tf/hash.h"
17 
18 #include <float.h>
19 #include <iosfwd>
20 #include <limits>
21 
23 
24 /// \class GfInterval
25 /// \ingroup group_gf_BasicMath
26 ///
27 /// A basic mathematical interval class.
28 ///
29 /// Can represent intervals with either open or closed boundary
30 /// conditions.
31 ///
33 {
34 public:
35  /// \name Constructors
36  ///@{
37 
38  /// Construct an empty open interval, (0,0).
40  _min(0.0, false),
41  _max(0.0, false)
42  {}
43 
44  /// Construct a closed interval representing the single point, as [val,val].
45  GfInterval(double val) :
46  _min(val, true),
47  _max(val, true)
48  {}
49 
50  /// Construct an interval with the given arguments.
51  GfInterval(double min, double max,
52  bool minClosed=true, bool maxClosed=true) :
53  _min(min, minClosed),
54  _max(max, maxClosed)
55  {}
56 
57  ///@}
58 
59  /// Equality operator.
60  bool operator==(const GfInterval &rhs) const {
61  return _min == rhs._min && _max == rhs._max;
62  }
63 
64  /// Inequality operator.
65  bool operator!=(const GfInterval &rhs) const {
66  return !(*this == rhs);
67  }
68 
69  /// Less-than operator.
70  bool operator<(const GfInterval &rhs) const {
71  // Compare min bound
72  if (_min != rhs._min)
73  return _min < rhs._min;
74 
75  // Compare max bound
76  if (_max != rhs._max)
77  return _max < rhs._max;
78 
79  // Equal
80  return false;
81  }
82 
83  /// Hash value.
84  /// Just a basic hash function, not particularly high quality.
85  size_t Hash() const { return hash_value(*this); }
86 
87  friend inline size_t hash_value(GfInterval const &i) {
88  return TfHash::Combine(i._min, i._max);
89  }
90 
91  /// Minimum value
92  double GetMin() const { return _min.value; }
93 
94  /// Maximum value
95  double GetMax() const { return _max.value; }
96 
97  /// Set minimum value
98  void SetMin(double v) {
99  _min = _Bound(v, _min.closed);
100  }
101 
102  /// Set minimum value and boundary condition
103  void SetMin(double v, bool minClosed ) {
104  _min = _Bound(v, minClosed);
105  }
106 
107  /// Set maximum value
108  void SetMax(double v) {
109  _max = _Bound(v, _max.closed);
110  }
111 
112  /// Set maximum value and boundary condition
113  void SetMax(double v, bool maxClosed ) {
114  _max = _Bound(v, maxClosed);
115  }
116 
117  /// Minimum boundary condition
118  bool IsMinClosed() const { return _min.closed; }
119 
120  /// Maximum boundary condition
121  bool IsMaxClosed() const { return _max.closed; }
122 
123  /// Minimum boundary condition
124  bool IsMinOpen() const { return ! _min.closed; }
125 
126  /// Maximum boundary condition
127  bool IsMaxOpen() const { return ! _max.closed; }
128 
129  /// Returns true if the maximum value is finite.
130  bool IsMaxFinite() const {
131  return (_max.value != -std::numeric_limits<double>::infinity()
132  && _max.value != std::numeric_limits<double>::infinity());
133  }
134 
135  /// Returns true if the minimum value is finite.
136  bool IsMinFinite() const {
137  return (_min.value != -std::numeric_limits<double>::infinity()
138  && _min.value != std::numeric_limits<double>::infinity());
139  }
140 
141  /// Returns true if both the maximum and minimum value are finite.
142  bool IsFinite() const {
143  return IsMaxFinite() && IsMinFinite();
144  }
145 
146  /// Return true iff the interval is empty.
147  bool IsEmpty() const {
148  return (_min.value > _max.value) ||
149  ((_min.value == _max.value)
150  && (! _min.closed || !_max.closed));
151  }
152 
153  /// Width of the interval.
154  /// An empty interval has size 0.
155  double GetSize() const {
156  return GfMax( 0.0, _max.value - _min.value );
157  }
158 
159  // For 2x compatibility
160  double Size() const { return GetSize(); }
161 
162  /// Return true iff the value d is contained in the interval.
163  /// An empty interval contains no values.
164  bool Contains(double d) const {
165  return ((d > _min.value) || (d == _min.value && _min.closed))
166  && ((d < _max.value) || (d == _max.value && _max.closed));
167  }
168 
169  // For 2x compatibility
170  bool In(double d) const { return Contains(d); }
171 
172  /// Return true iff the interval i is entirely contained in the interval.
173  /// An empty interval contains no intervals, not even other
174  /// empty intervals.
175  bool Contains(const GfInterval &i) const {
176  return (*this & i) == i;
177  }
178 
179  /// Return true iff the given interval i intersects this interval.
180  bool Intersects(const GfInterval &i) const {
181  return !(*this & i).IsEmpty();
182  }
183 
184  /// \name Math operations
185  ///@{
186 
187  /// Boolean intersection.
189  if (IsEmpty()) {
190  // No change
191  } else if (rhs.IsEmpty()) {
192  // Intersection is empty
193  *this = GfInterval();
194  } else {
195  // Intersect min edge
196  if (_min.value < rhs._min.value)
197  _min = rhs._min;
198  else if (_min.value == rhs._min.value)
199  _min.closed &= rhs._min.closed;
200 
201  // Intersect max edge
202  if (_max.value > rhs._max.value)
203  _max = rhs._max;
204  else if (_max.value == rhs._max.value)
205  _max.closed &= rhs._max.closed;
206  }
207  return *this;
208  }
209 
210  /// Returns the interval that bounds the union of this interval and rhs.
212  if (IsEmpty()) {
213  *this = rhs;
214  } else if (rhs.IsEmpty()) {
215  // No change
216  } else {
217  // Expand min edge
218  if (_min.value > rhs._min.value)
219  _min = rhs._min;
220  else if (_min.value == rhs._min.value)
221  _min.closed |= rhs._min.closed;
222 
223  // Expand max edge
224  if (_max.value < rhs._max.value)
225  _max = rhs._max;
226  else if (_max.value == rhs._max.value)
227  _max.closed |= rhs._max.closed;
228  }
229  return *this;
230  }
231 
232  /// Interval addition.
234  if (!rhs.IsEmpty()) {
235  _min.value += rhs._min.value;
236  _max.value += rhs._max.value;
237  _min.closed &= rhs._min.closed;
238  _max.closed &= rhs._max.closed;
239  }
240  return *this;
241  }
242 
243  /// Interval subtraction.
245  return *this += -rhs;
246  }
247 
248  /// Interval unary minus.
250  return GfInterval(-_max.value, -_min.value, _max.closed, _min.closed);
251  }
252 
253  /// Interval multiplication.
255  const _Bound a = _min * rhs._min;
256  const _Bound b = _min * rhs._max;
257  const _Bound c = _max * rhs._min;
258  const _Bound d = _max * rhs._max;
259  _max = _Max( _Max(a,b), _Max(c,d) );
260  _min = _Min( _Min(a,b), _Min(c,d) );
261  return *this;
262  }
263 
264  /// Greater than operator
265  bool operator>(const GfInterval& rhs) {
266  // Defined in terms of operator<()
267  return rhs < *this;
268  }
269 
270  /// Less than or equal operator
271  bool operator<=(const GfInterval& rhs) {
272  // Defined in terms of operator<()
273  return !(rhs < *this);
274  }
275 
276  /// Greater than or equal operator
277  bool operator>=(const GfInterval& rhs) {
278  // Defined in terms of operator<()
279  return !(*this < rhs);
280  }
281 
282  /// Union operator
283  GfInterval operator|(const GfInterval& rhs) const {
284  // Defined in terms of operator |=()
285  GfInterval tmp(*this);
286  tmp |= rhs;
287  return tmp;
288  }
289 
290  /// Intersection operator
291  GfInterval operator&(const GfInterval& rhs) const {
292  // Defined in terms of operator &=()
293  GfInterval tmp(*this);
294  tmp &= rhs;
295  return tmp;
296  }
297 
298  /// Addition operator
299  GfInterval operator+(const GfInterval& rhs) const {
300  // Defined in terms of operator +=()
301  GfInterval tmp(*this);
302  tmp += rhs;
303  return tmp;
304  }
305 
306  /// Subtraction operator
307  GfInterval operator-(const GfInterval& rhs) const {
308  // Defined in terms of operator -=()
309  GfInterval tmp(*this);
310  tmp -= rhs;
311  return tmp;
312  }
313 
314  /// Multiplication operator
315  GfInterval operator*(const GfInterval& rhs) const {
316  // Defined in terms of operator *=()
317  GfInterval tmp(*this);
318  tmp *= rhs;
319  return tmp;
320  }
321 
322  ///@}
323 
324  /// Returns the full interval (-inf, inf).
326  return GfInterval( -std::numeric_limits<double>::infinity(),
327  std::numeric_limits<double>::infinity(),
328  false, false );
329  }
330 
331 private:
332  // Helper struct to represent interval boundaries.
333  struct _Bound {
334  // Boundary value.
335  double value;
336  // Boundary condition. The boundary value is included in interval
337  // only if the boundary is closed.
338  bool closed;
339 
340  _Bound(double val, bool isClosed) :
341  value(val),
342  closed(isClosed)
343  {
344  // Closed boundaries on infinite values do not make sense so
345  // force the bound to be open
346  if (value == -std::numeric_limits<double>::infinity() ||
347  value == std::numeric_limits<double>::infinity()) {
348  closed = false;
349  }
350  }
351 
352  bool operator==(const _Bound &rhs) const {
353  return value == rhs.value && closed == rhs.closed;
354  }
355 
356  bool operator!=(const _Bound &rhs) const {
357  return !(*this == rhs);
358  }
359 
360  bool operator<(const _Bound &rhs) const {
361  return value < rhs.value || (value == rhs.value && closed && !rhs.closed);
362  }
363 
364  _Bound & operator=(const _Bound &rhs) {
365  value = rhs.value;
366  closed = rhs.closed;
367  return *this;
368  }
369  _Bound operator*(const _Bound &rhs) const {
370  return _Bound( value * rhs.value, closed & rhs.closed );
371  }
372  friend inline size_t hash_value(const _Bound &b) {
373  return TfHash::Combine(b.value, b.closed);
374  }
375  };
376 
377  // Return the lesser minimum bound, handling boundary conditions.
378  inline static const _Bound &
379  _Min( const _Bound &a, const _Bound &b ) {
380  return (a.value < b.value
381  || ((a.value == b.value) && a.closed && !b.closed)) ?
382  a : b;
383  }
384 
385  // Return the greater maximum bound, handling boundary conditions.
386  inline static const _Bound &
387  _Max( const _Bound &a, const _Bound &b ) {
388  return (a.value < b.value
389  || ((a.value == b.value) && !a.closed && b.closed)) ?
390  b : a;
391  }
392 
393  /// Data
394  _Bound _min, _max;
395 };
396 
397 /// Output a GfInterval using the format (x, y).
398 /// \ingroup group_gf_DebuggingOutput
399 GF_API std::ostream &operator<<(std::ostream&, const GfInterval&);
400 
402 
403 #endif // PXR_BASE_GF_INTERVAL_H
GfInterval & operator-=(const GfInterval &rhs)
Interval subtraction.
Definition: interval.h:244
GF_API std::ostream & operator<<(std::ostream &, const GfInterval &)
void SetMin(double v)
Set minimum value.
Definition: interval.h:98
bool IsMinClosed() const
Minimum boundary condition.
Definition: interval.h:118
bool IsMinFinite() const
Returns true if the minimum value is finite.
Definition: interval.h:136
bool operator>(const GfInterval &rhs)
Greater than operator.
Definition: interval.h:265
const GLdouble * v
Definition: glcorearb.h:837
bool Contains(double d) const
Definition: interval.h:164
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GfInterval & operator&=(const GfInterval &rhs)
Boolean intersection.
Definition: interval.h:188
double GetMin() const
Minimum value.
Definition: interval.h:92
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
static GfInterval GetFullInterval()
Returns the full interval (-inf, inf).
Definition: interval.h:325
bool IsMaxClosed() const
Maximum boundary condition.
Definition: interval.h:121
bool In(double d) const
Definition: interval.h:170
GfInterval(double min, double max, bool minClosed=true, bool maxClosed=true)
Construct an interval with the given arguments.
Definition: interval.h:51
bool operator>=(const GfInterval &rhs)
Greater than or equal operator.
Definition: interval.h:277
double GetSize() const
Definition: interval.h:155
GfInterval operator+(const GfInterval &rhs) const
Addition operator.
Definition: interval.h:299
bool IsMaxOpen() const
Maximum boundary condition.
Definition: interval.h:127
GfInterval operator|(const GfInterval &rhs) const
Union operator.
Definition: interval.h:283
bool operator<=(const GfInterval &rhs)
Less than or equal operator.
Definition: interval.h:271
bool operator<(const GfInterval &rhs) const
Less-than operator.
Definition: interval.h:70
bool IsFinite() const
Returns true if both the maximum and minimum value are finite.
Definition: interval.h:142
GfInterval()
Construct an empty open interval, (0,0).
Definition: interval.h:39
GfInterval operator&(const GfInterval &rhs) const
Intersection operator.
Definition: interval.h:291
void SetMax(double v)
Set maximum value.
Definition: interval.h:108
T GfMax(T a1, T a2)
Definition: math.h:326
GfInterval operator-(const GfInterval &rhs) const
Subtraction operator.
Definition: interval.h:307
GfInterval(double val)
Construct a closed interval representing the single point, as [val,val].
Definition: interval.h:45
void SetMin(double v, bool minClosed)
Set minimum value and boundary condition.
Definition: interval.h:103
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GfInterval & operator*=(const GfInterval &rhs)
Interval multiplication.
Definition: interval.h:254
size_t Hash() const
Definition: interval.h:85
friend size_t hash_value(GfInterval const &i)
Definition: interval.h:87
GfInterval & operator|=(const GfInterval &rhs)
Returns the interval that bounds the union of this interval and rhs.
Definition: interval.h:211
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
bool Intersects(const GfInterval &i) const
Return true iff the given interval i intersects this interval.
Definition: interval.h:180
GfInterval operator*(const GfInterval &rhs) const
Multiplication operator.
Definition: interval.h:315
LeafData & operator=(const LeafData &)=delete
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool IsEmpty() const
Return true iff the interval is empty.
Definition: interval.h:147
void SetMax(double v, bool maxClosed)
Set maximum value and boundary condition.
Definition: interval.h:113
GfInterval & operator+=(const GfInterval &rhs)
Interval addition.
Definition: interval.h:233
bool IsMaxFinite() const
Returns true if the maximum value is finite.
Definition: interval.h:130
double GetMax() const
Maximum value.
Definition: interval.h:95
bool Contains(const GfInterval &i) const
Definition: interval.h:175
double Size() const
Definition: interval.h:160
bool operator==(const GfInterval &rhs) const
Equality operator.
Definition: interval.h:60
GfInterval operator-() const
Interval unary minus.
Definition: interval.h:249
#define GF_API
Definition: api.h:23
bool operator!=(const GfInterval &rhs) const
Inequality operator.
Definition: interval.h:65
bool IsMinOpen() const
Minimum boundary condition.
Definition: interval.h:124