Loading...
Searching...
No Matches
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#include "pxr/base/tf/hash.h"
34
35#include <float.h>
36#include <iosfwd>
37#include <limits>
38
39PXR_NAMESPACE_OPEN_SCOPE
40
50{
51public:
54
57 _min(0.0, false),
58 _max(0.0, false)
59 {}
60
62 GfInterval(double val) :
63 _min(val, true),
64 _max(val, true)
65 {}
66
68 GfInterval(double min, double max,
69 bool minClosed=true, bool maxClosed=true) :
70 _min(min, minClosed),
71 _max(max, maxClosed)
72 {}
73
75
77 bool operator==(const GfInterval &rhs) const {
78 return _min == rhs._min && _max == rhs._max;
79 }
80
82 bool operator!=(const GfInterval &rhs) const {
83 return !(*this == rhs);
84 }
85
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
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
109 double GetMin() const { return _min.value; }
110
112 double GetMax() const { return _max.value; }
113
115 void SetMin(double v) {
116 _min = _Bound(v, _min.closed);
117 }
118
120 void SetMin(double v, bool minClosed ) {
121 _min = _Bound(v, minClosed);
122 }
123
125 void SetMax(double v) {
126 _max = _Bound(v, _max.closed);
127 }
128
130 void SetMax(double v, bool maxClosed ) {
131 _max = _Bound(v, maxClosed);
132 }
133
135 bool IsMinClosed() const { return _min.closed; }
136
138 bool IsMaxClosed() const { return _max.closed; }
139
141 bool IsMinOpen() const { return ! _min.closed; }
142
144 bool IsMaxOpen() const { return ! _max.closed; }
145
147 bool IsMaxFinite() const {
148 return (_max.value != -std::numeric_limits<double>::infinity()
149 && _max.value != std::numeric_limits<double>::infinity());
150 }
151
153 bool IsMinFinite() const {
154 return (_min.value != -std::numeric_limits<double>::infinity()
155 && _min.value != std::numeric_limits<double>::infinity());
156 }
157
159 bool IsFinite() const {
160 return IsMaxFinite() && IsMinFinite();
161 }
162
164 bool IsEmpty() const {
165 return (_min.value > _max.value) ||
166 ((_min.value == _max.value)
167 && (! _min.closed || !_max.closed));
168 }
169
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
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
192 bool Contains(const GfInterval &i) const {
193 return (*this & i) == i;
194 }
195
197 bool Intersects(const GfInterval &i) const {
198 return !(*this & i).IsEmpty();
199 }
200
203
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
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
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
262 return *this += -rhs;
263 }
264
267 return GfInterval(-_max.value, -_min.value, _max.closed, _min.closed);
268 }
269
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
282 bool operator>(const GfInterval& rhs) {
283 // Defined in terms of operator<()
284 return rhs < *this;
285 }
286
288 bool operator<=(const GfInterval& rhs) {
289 // Defined in terms of operator<()
290 return !(rhs < *this);
291 }
292
294 bool operator>=(const GfInterval& rhs) {
295 // Defined in terms of operator<()
296 return !(*this < rhs);
297 }
298
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
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
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
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
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
340
343 return GfInterval( -std::numeric_limits<double>::infinity(),
344 std::numeric_limits<double>::infinity(),
345 false, false );
346 }
347
348private:
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
411 _Bound _min, _max;
412};
413
416GF_API std::ostream &operator<<(std::ostream&, const GfInterval&);
417
418PXR_NAMESPACE_CLOSE_SCOPE
419
420#endif // PXR_BASE_GF_INTERVAL_H
A basic mathematical interval class.
Definition: interval.h:50
GfInterval()
Construct an empty open interval, (0,0).
Definition: interval.h:56
bool operator>=(const GfInterval &rhs)
Greater than or equal operator.
Definition: interval.h:294
GfInterval(double val)
Construct a closed interval representing the single point, as [val,val].
Definition: interval.h:62
bool operator<=(const GfInterval &rhs)
Less than or equal operator.
Definition: interval.h:288
double GetMax() const
Maximum value.
Definition: interval.h:112
GfInterval & operator+=(const GfInterval &rhs)
Interval addition.
Definition: interval.h:250
static GfInterval GetFullInterval()
Returns the full interval (-inf, inf).
Definition: interval.h:342
GfInterval operator|(const GfInterval &rhs) const
Union operator.
Definition: interval.h:300
bool operator>(const GfInterval &rhs)
Greater than operator.
Definition: interval.h:282
bool IsFinite() const
Returns true if both the maximum and minimum value are finite.
Definition: interval.h:159
GfInterval operator-(const GfInterval &rhs) const
Subtraction operator.
Definition: interval.h:324
bool operator<(const GfInterval &rhs) const
Less-than operator.
Definition: interval.h:87
GfInterval & operator*=(const GfInterval &rhs)
Interval multiplication.
Definition: interval.h:271
double GetMin() const
Minimum value.
Definition: interval.h:109
GfInterval & operator-=(const GfInterval &rhs)
Interval subtraction.
Definition: interval.h:261
bool IsMaxFinite() const
Returns true if the maximum value is finite.
Definition: interval.h:147
double GetSize() const
Width of the interval.
Definition: interval.h:172
void SetMin(double v, bool minClosed)
Set minimum value and boundary condition.
Definition: interval.h:120
GfInterval operator-() const
Interval unary minus.
Definition: interval.h:266
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
bool IsMinClosed() const
Minimum boundary condition.
Definition: interval.h:135
bool IsMaxOpen() const
Maximum boundary condition.
Definition: interval.h:144
bool operator!=(const GfInterval &rhs) const
Inequality operator.
Definition: interval.h:82
bool operator==(const GfInterval &rhs) const
Equality operator.
Definition: interval.h:77
bool IsMinFinite() const
Returns true if the minimum value is finite.
Definition: interval.h:153
void SetMin(double v)
Set minimum value.
Definition: interval.h:115
GfInterval operator&(const GfInterval &rhs) const
Intersection operator.
Definition: interval.h:308
GfInterval(double min, double max, bool minClosed=true, bool maxClosed=true)
Construct an interval with the given arguments.
Definition: interval.h:68
size_t Hash() const
Hash value.
Definition: interval.h:102
GfInterval operator*(const GfInterval &rhs) const
Multiplication operator.
Definition: interval.h:332
GfInterval & operator|=(const GfInterval &rhs)
Returns the interval that bounds the union of this interval and rhs.
Definition: interval.h:228
GfInterval operator+(const GfInterval &rhs) const
Addition operator.
Definition: interval.h:316
bool Contains(const GfInterval &i) const
Return true iff the interval i is entirely contained in the interval.
Definition: interval.h:192
void SetMax(double v)
Set maximum value.
Definition: interval.h:125
bool Intersects(const GfInterval &i) const
Return true iff the given interval i intersects this interval.
Definition: interval.h:197
bool Contains(double d) const
Return true iff the value d is contained in the interval.
Definition: interval.h:181
bool IsMinOpen() const
Minimum boundary condition.
Definition: interval.h:141
bool IsMaxClosed() const
Maximum boundary condition.
Definition: interval.h:138
GfInterval & operator&=(const GfInterval &rhs)
Boolean intersection.
Definition: interval.h:205
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:492
Assorted mathematical utility functions.
T GfMax(T a1, T a2)
Returns the largest of the given values.
Definition: math.h:219
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:45