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 
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/math.h"
32 #include "pxr/base/gf/api.h"
33 
34 #include <boost/functional/hash.hpp>
35 
36 #include <float.h>
37 #include <iosfwd>
38 #include <limits>
39 
40 PXR_NAMESPACE_OPEN_SCOPE
41 
51 {
52 public:
55 
58  _min(0.0, false),
59  _max(0.0, false)
60  {}
61 
63  GfInterval(double val) :
64  _min(val, true),
65  _max(val, true)
66  {}
67 
69  GfInterval(double min, double max,
70  bool minClosed=true, bool maxClosed=true) :
71  _min(min, minClosed),
72  _max(max, maxClosed)
73  {}
74 
76 
78  bool operator==(const GfInterval &rhs) const {
79  return _min == rhs._min && _max == rhs._max;
80  }
81 
83  bool operator!=(const GfInterval &rhs) const {
84  return !(*this == rhs);
85  }
86 
88  bool operator<(const GfInterval &rhs) const {
89  // Compare min bound
90  if (_min != rhs._min)
91  return _min < rhs._min;
92 
93  // Compare max bound
94  if (_max != rhs._max)
95  return _max < rhs._max;
96 
97  // Equal
98  return false;
99  }
100 
103  size_t Hash() const { return hash_value(*this); }
104 
105  friend inline size_t hash_value(GfInterval const &i) {
106  size_t h = 0;
107  boost::hash_combine(h, i._min);
108  boost::hash_combine(h, i._max);
109  return h;
110  }
111 
113  double GetMin() const { return _min.value; }
114 
116  double GetMax() const { return _max.value; }
117 
119  void SetMin(double v) {
120  _min = _Bound(v, _min.closed);
121  }
122 
124  void SetMin(double v, bool minClosed ) {
125  _min = _Bound(v, minClosed);
126  }
127 
129  void SetMax(double v) {
130  _max = _Bound(v, _max.closed);
131  }
132 
134  void SetMax(double v, bool maxClosed ) {
135  _max = _Bound(v, maxClosed);
136  }
137 
139  bool IsMinClosed() const { return _min.closed; }
140 
142  bool IsMaxClosed() const { return _max.closed; }
143 
145  bool IsMinOpen() const { return ! _min.closed; }
146 
148  bool IsMaxOpen() const { return ! _max.closed; }
149 
151  bool IsMaxFinite() const {
152  return (_max.value != -std::numeric_limits<double>::infinity()
153  && _max.value != std::numeric_limits<double>::infinity());
154  }
155 
157  bool IsMinFinite() const {
158  return (_min.value != -std::numeric_limits<double>::infinity()
159  && _min.value != std::numeric_limits<double>::infinity());
160  }
161 
163  bool IsFinite() const {
164  return IsMaxFinite() && IsMinFinite();
165  }
166 
168  bool IsEmpty() const {
169  return (_min.value > _max.value) ||
170  ((_min.value == _max.value)
171  && (! _min.closed || !_max.closed));
172  }
173 
176  double GetSize() const {
177  return GfMax( 0.0, _max.value - _min.value );
178  }
179 
180  // For 2x compatibility
181  double Size() const { return GetSize(); }
182 
185  bool Contains(double d) const {
186  return ((d > _min.value) || (d == _min.value && _min.closed))
187  && ((d < _max.value) || (d == _max.value && _max.closed));
188  }
189 
190  // For 2x compatibility
191  bool In(double d) const { return Contains(d); }
192 
196  bool Contains(const GfInterval &i) const {
197  return (*this & i) == i;
198  }
199 
201  bool Intersects(const GfInterval &i) const {
202  return !(*this & i).IsEmpty();
203  }
204 
207 
210  if (IsEmpty()) {
211  // No change
212  } else if (rhs.IsEmpty()) {
213  // Intersection is empty
214  *this = GfInterval();
215  } else {
216  // Intersect min edge
217  if (_min.value < rhs._min.value)
218  _min = rhs._min;
219  else if (_min.value == rhs._min.value)
220  _min.closed &= rhs._min.closed;
221 
222  // Intersect max edge
223  if (_max.value > rhs._max.value)
224  _max = rhs._max;
225  else if (_max.value == rhs._max.value)
226  _max.closed &= rhs._max.closed;
227  }
228  return *this;
229  }
230 
233  if (IsEmpty()) {
234  *this = rhs;
235  } else if (rhs.IsEmpty()) {
236  // No change
237  } else {
238  // Expand min edge
239  if (_min.value > rhs._min.value)
240  _min = rhs._min;
241  else if (_min.value == rhs._min.value)
242  _min.closed |= rhs._min.closed;
243 
244  // Expand max edge
245  if (_max.value < rhs._max.value)
246  _max = rhs._max;
247  else if (_max.value == rhs._max.value)
248  _max.closed |= rhs._max.closed;
249  }
250  return *this;
251  }
252 
255  if (!rhs.IsEmpty()) {
256  _min.value += rhs._min.value;
257  _max.value += rhs._max.value;
258  _min.closed &= rhs._min.closed;
259  _max.closed &= rhs._max.closed;
260  }
261  return *this;
262  }
263 
266  return *this += -rhs;
267  }
268 
271  return GfInterval(-_max.value, -_min.value, _max.closed, _min.closed);
272  }
273 
276  const _Bound a = _min * rhs._min;
277  const _Bound b = _min * rhs._max;
278  const _Bound c = _max * rhs._min;
279  const _Bound d = _max * rhs._max;
280  _max = _Max( _Max(a,b), _Max(c,d) );
281  _min = _Min( _Min(a,b), _Min(c,d) );
282  return *this;
283  }
284 
286  bool operator>(const GfInterval& rhs) {
287  // Defined in terms of operator<()
288  return rhs < *this;
289  }
290 
292  bool operator<=(const GfInterval& rhs) {
293  // Defined in terms of operator<()
294  return !(rhs < *this);
295  }
296 
298  bool operator>=(const GfInterval& rhs) {
299  // Defined in terms of operator<()
300  return !(*this < rhs);
301  }
302 
304  GfInterval operator|(const GfInterval& rhs) const {
305  // Defined in terms of operator |=()
306  GfInterval tmp(*this);
307  tmp |= rhs;
308  return tmp;
309  }
310 
312  GfInterval operator&(const GfInterval& rhs) const {
313  // Defined in terms of operator &=()
314  GfInterval tmp(*this);
315  tmp &= rhs;
316  return tmp;
317  }
318 
320  GfInterval operator+(const GfInterval& rhs) const {
321  // Defined in terms of operator +=()
322  GfInterval tmp(*this);
323  tmp += rhs;
324  return tmp;
325  }
326 
328  GfInterval operator-(const GfInterval& rhs) const {
329  // Defined in terms of operator -=()
330  GfInterval tmp(*this);
331  tmp -= rhs;
332  return tmp;
333  }
334 
336  GfInterval operator*(const GfInterval& rhs) const {
337  // Defined in terms of operator *=()
338  GfInterval tmp(*this);
339  tmp *= rhs;
340  return tmp;
341  }
342 
344 
347  return GfInterval( -std::numeric_limits<double>::infinity(),
348  std::numeric_limits<double>::infinity(),
349  false, false );
350  }
351 
352 private:
353  // Helper struct to represent interval boundaries.
354  struct _Bound {
355  // Boundary value.
356  double value;
357  // Boundary condition. The boundary value is included in interval
358  // only if the boundary is closed.
359  bool closed;
360 
361  _Bound(double val, bool isClosed) :
362  value(val),
363  closed(isClosed)
364  {
365  // Closed boundaries on infinite values do not make sense so
366  // force the bound to be open
367  if (value == -std::numeric_limits<double>::infinity() ||
368  value == std::numeric_limits<double>::infinity()) {
369  closed = false;
370  }
371  }
372 
373  bool operator==(const _Bound &rhs) const {
374  return value == rhs.value && closed == rhs.closed;
375  }
376 
377  bool operator!=(const _Bound &rhs) const {
378  return !(*this == rhs);
379  }
380 
381  bool operator<(const _Bound &rhs) const {
382  return value < rhs.value || (value == rhs.value && closed && !rhs.closed);
383  }
384 
385  _Bound & operator=(const _Bound &rhs) {
386  value = rhs.value;
387  closed = rhs.closed;
388  return *this;
389  }
390  _Bound operator*(const _Bound &rhs) const {
391  return _Bound( value * rhs.value, closed & rhs.closed );
392  }
393  friend inline size_t hash_value(const _Bound &b) {
394  size_t h = 0;
395  boost::hash_combine(h, b.value);
396  boost::hash_combine(h, b.closed);
397  return h;
398  }
399  };
400 
401  // Return the lesser minimum bound, handling boundary conditions.
402  inline static const _Bound &
403  _Min( const _Bound &a, const _Bound &b ) {
404  return (a.value < b.value
405  || ((a.value == b.value) && a.closed && !b.closed)) ?
406  a : b;
407  }
408 
409  // Return the greater maximum bound, handling boundary conditions.
410  inline static const _Bound &
411  _Max( const _Bound &a, const _Bound &b ) {
412  return (a.value < b.value
413  || ((a.value == b.value) && !a.closed && b.closed)) ?
414  b : a;
415  }
416 
418  _Bound _min, _max;
419 };
420 
423 GF_API std::ostream &operator<<(std::ostream&, const GfInterval&);
424 
425 PXR_NAMESPACE_CLOSE_SCOPE
426 
427 #endif // PXR_BASE_GF_INTERVAL_H
GfInterval operator*(const GfInterval &rhs) const
Multiplication operator.
Definition: interval.h:336
GfInterval & operator*=(const GfInterval &rhs)
Interval multiplication.
Definition: interval.h:275
GfInterval()
Construct an empty open interval, (0,0).
Definition: interval.h:57
bool operator<(const GfInterval &rhs) const
Less-than operator.
Definition: interval.h:88
Assorted mathematical utility functions.
GfInterval & operator+=(const GfInterval &rhs)
Interval addition.
Definition: interval.h:254
GfInterval(double val)
Construct a closed interval representing the single point, as [val,val].
Definition: interval.h:63
bool IsMaxOpen() const
Maximum boundary condition.
Definition: interval.h:148
GfInterval operator-(const GfInterval &rhs) const
Subtraction operator.
Definition: interval.h:328
bool Contains(double d) const
Return true iff the value d is contained in the interval.
Definition: interval.h:185
void SetMin(double v)
Set minimum value.
Definition: interval.h:119
GfInterval operator-() const
Interval unary minus.
Definition: interval.h:270
void SetMin(double v, bool minClosed)
Set minimum value and boundary condition.
Definition: interval.h:124
bool Contains(const GfInterval &i) const
Return true iff the interval i is entirely contained in the interval.
Definition: interval.h:196
bool IsFinite() const
Returns true if both the maximum and minimum value are finite.
Definition: interval.h:163
bool Intersects(const GfInterval &i) const
Return true iff the given interval i intersects this interval.
Definition: interval.h:201
bool operator>(const GfInterval &rhs)
Greater than operator.
Definition: interval.h:286
double GetMin() const
Minimum value.
Definition: interval.h:113
void SetMax(double v, bool maxClosed)
Set maximum value and boundary condition.
Definition: interval.h:134
T GfMax(T a1, T a2)
Returns the largest of the given values.
Definition: math.h:219
A basic mathematical interval class.
Definition: interval.h:50
bool IsMinFinite() const
Returns true if the minimum value is finite.
Definition: interval.h:157
GfInterval & operator&=(const GfInterval &rhs)
Boolean intersection.
Definition: interval.h:209
static GfInterval GetFullInterval()
Returns the full interval (-inf, inf).
Definition: interval.h:346
bool IsEmpty() const
Return true iff the interval is empty.
Definition: interval.h:168
GfInterval(double min, double max, bool minClosed=true, bool maxClosed=true)
Construct an interval with the given arguments.
Definition: interval.h:69
bool IsMinClosed() const
Minimum boundary condition.
Definition: interval.h:139
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
GfInterval operator|(const GfInterval &rhs) const
Union operator.
Definition: interval.h:304
bool IsMaxFinite() const
Returns true if the maximum value is finite.
Definition: interval.h:151
bool operator<=(const GfInterval &rhs)
Less than or equal operator.
Definition: interval.h:292
GfInterval & operator|=(const GfInterval &rhs)
Returns the interval that bounds the union of this interval and rhs.
Definition: interval.h:232
GfInterval operator&(const GfInterval &rhs) const
Intersection operator.
Definition: interval.h:312
bool IsMaxClosed() const
Maximum boundary condition.
Definition: interval.h:142
size_t Hash() const
Hash value.
Definition: interval.h:103
void SetMax(double v)
Set maximum value.
Definition: interval.h:129
GfInterval & operator-=(const GfInterval &rhs)
Interval subtraction.
Definition: interval.h:265
double GetMax() const
Maximum value.
Definition: interval.h:116
bool IsMinOpen() const
Minimum boundary condition.
Definition: interval.h:145
bool operator!=(const GfInterval &rhs) const
Inequality operator.
Definition: interval.h:83
GfInterval operator+(const GfInterval &rhs) const
Addition operator.
Definition: interval.h:320
bool operator==(const GfInterval &rhs) const
Equality operator.
Definition: interval.h:78
double GetSize() const
Width of the interval.
Definition: interval.h:176
bool operator>=(const GfInterval &rhs)
Greater than or equal operator.
Definition: interval.h:298