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