All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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
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
22PXR_NAMESPACE_OPEN_SCOPE
23
33{
34public:
37
40 _min(0.0, false),
41 _max(0.0, false)
42 {}
43
45 GfInterval(double val) :
46 _min(val, true),
47 _max(val, true)
48 {}
49
51 GfInterval(double min, double max,
52 bool minClosed=true, bool maxClosed=true) :
53 _min(min, minClosed),
54 _max(max, maxClosed)
55 {}
56
58
60 bool operator==(const GfInterval &rhs) const {
61 return _min == rhs._min && _max == rhs._max;
62 }
63
65 bool operator!=(const GfInterval &rhs) const {
66 return !(*this == rhs);
67 }
68
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
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
92 double GetMin() const { return _min.value; }
93
95 double GetMax() const { return _max.value; }
96
98 void SetMin(double v) {
99 _min = _Bound(v, _min.closed);
100 }
101
103 void SetMin(double v, bool minClosed ) {
104 _min = _Bound(v, minClosed);
105 }
106
108 void SetMax(double v) {
109 _max = _Bound(v, _max.closed);
110 }
111
113 void SetMax(double v, bool maxClosed ) {
114 _max = _Bound(v, maxClosed);
115 }
116
118 bool IsMinClosed() const { return _min.closed; }
119
121 bool IsMaxClosed() const { return _max.closed; }
122
124 bool IsMinOpen() const { return ! _min.closed; }
125
127 bool IsMaxOpen() const { return ! _max.closed; }
128
130 bool IsMaxFinite() const {
131 return (_max.value != -std::numeric_limits<double>::infinity()
132 && _max.value != std::numeric_limits<double>::infinity());
133 }
134
136 bool IsMinFinite() const {
137 return (_min.value != -std::numeric_limits<double>::infinity()
138 && _min.value != std::numeric_limits<double>::infinity());
139 }
140
142 bool IsFinite() const {
143 return IsMaxFinite() && IsMinFinite();
144 }
145
147 bool IsEmpty() const {
148 return (_min.value > _max.value) ||
149 ((_min.value == _max.value)
150 && (! _min.closed || !_max.closed));
151 }
152
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
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
175 bool Contains(const GfInterval &i) const {
176 return (*this & i) == i;
177 }
178
180 bool Intersects(const GfInterval &i) const {
181 return !(*this & i).IsEmpty();
182 }
183
186
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
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
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
245 return *this += -rhs;
246 }
247
250 return GfInterval(-_max.value, -_min.value, _max.closed, _min.closed);
251 }
252
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
265 bool operator>(const GfInterval& rhs) {
266 // Defined in terms of operator<()
267 return rhs < *this;
268 }
269
271 bool operator<=(const GfInterval& rhs) {
272 // Defined in terms of operator<()
273 return !(rhs < *this);
274 }
275
277 bool operator>=(const GfInterval& rhs) {
278 // Defined in terms of operator<()
279 return !(*this < rhs);
280 }
281
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
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
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
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
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
323
326 return GfInterval( -std::numeric_limits<double>::infinity(),
327 std::numeric_limits<double>::infinity(),
328 false, false );
329 }
330
331private:
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
394 _Bound _min, _max;
395};
396
399GF_API std::ostream &operator<<(std::ostream&, const GfInterval&);
400
401PXR_NAMESPACE_CLOSE_SCOPE
402
403#endif // PXR_BASE_GF_INTERVAL_H
A basic mathematical interval class.
Definition: interval.h:33
GfInterval()
Construct an empty open interval, (0,0).
Definition: interval.h:39
bool operator>=(const GfInterval &rhs)
Greater than or equal operator.
Definition: interval.h:277
GfInterval(double val)
Construct a closed interval representing the single point, as [val,val].
Definition: interval.h:45
bool operator<=(const GfInterval &rhs)
Less than or equal operator.
Definition: interval.h:271
double GetMax() const
Maximum value.
Definition: interval.h:95
GfInterval & operator+=(const GfInterval &rhs)
Interval addition.
Definition: interval.h:233
static GfInterval GetFullInterval()
Returns the full interval (-inf, inf).
Definition: interval.h:325
GfInterval operator|(const GfInterval &rhs) const
Union operator.
Definition: interval.h:283
bool operator>(const GfInterval &rhs)
Greater than operator.
Definition: interval.h:265
bool IsFinite() const
Returns true if both the maximum and minimum value are finite.
Definition: interval.h:142
GfInterval operator-(const GfInterval &rhs) const
Subtraction operator.
Definition: interval.h:307
bool operator<(const GfInterval &rhs) const
Less-than operator.
Definition: interval.h:70
GfInterval & operator*=(const GfInterval &rhs)
Interval multiplication.
Definition: interval.h:254
double GetMin() const
Minimum value.
Definition: interval.h:92
GfInterval & operator-=(const GfInterval &rhs)
Interval subtraction.
Definition: interval.h:244
bool IsMaxFinite() const
Returns true if the maximum value is finite.
Definition: interval.h:130
double GetSize() const
Width of the interval.
Definition: interval.h:155
void SetMin(double v, bool minClosed)
Set minimum value and boundary condition.
Definition: interval.h:103
GfInterval operator-() const
Interval unary minus.
Definition: interval.h:249
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
bool IsMinClosed() const
Minimum boundary condition.
Definition: interval.h:118
bool IsMaxOpen() const
Maximum boundary condition.
Definition: interval.h:127
bool operator!=(const GfInterval &rhs) const
Inequality operator.
Definition: interval.h:65
bool operator==(const GfInterval &rhs) const
Equality operator.
Definition: interval.h:60
bool IsMinFinite() const
Returns true if the minimum value is finite.
Definition: interval.h:136
void SetMin(double v)
Set minimum value.
Definition: interval.h:98
GfInterval operator&(const GfInterval &rhs) const
Intersection operator.
Definition: interval.h:291
GfInterval(double min, double max, bool minClosed=true, bool maxClosed=true)
Construct an interval with the given arguments.
Definition: interval.h:51
size_t Hash() const
Hash value.
Definition: interval.h:85
GfInterval operator*(const GfInterval &rhs) const
Multiplication operator.
Definition: interval.h:315
GfInterval & operator|=(const GfInterval &rhs)
Returns the interval that bounds the union of this interval and rhs.
Definition: interval.h:211
GfInterval operator+(const GfInterval &rhs) const
Addition operator.
Definition: interval.h:299
bool Contains(const GfInterval &i) const
Return true iff the interval i is entirely contained in the interval.
Definition: interval.h:175
void SetMax(double v)
Set maximum value.
Definition: interval.h:108
bool Intersects(const GfInterval &i) const
Return true iff the given interval i intersects this interval.
Definition: interval.h:180
bool Contains(double d) const
Return true iff the value d is contained in the interval.
Definition: interval.h:164
bool IsMinOpen() const
Minimum boundary condition.
Definition: interval.h:124
bool IsMaxClosed() const
Maximum boundary condition.
Definition: interval.h:121
GfInterval & operator&=(const GfInterval &rhs)
Boolean intersection.
Definition: interval.h:188
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:475
Assorted mathematical utility functions.
T GfMax(T a1, T a2)
Returns the largest of the given values.
Definition: math.h:326
GF_API std::ostream & operator<<(std::ostream &, const GfBBox3d &)
Output a GfBBox3d using the format [(range) matrix zeroArea].
size_t hash_value(const half h)
Overload hash_value for half.
Definition: half.h:28