Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
range.h
Go to the documentation of this file.
1 
18 #ifndef ION_MATH_RANGE_H_
19 #define ION_MATH_RANGE_H_
20 
21 #include <algorithm>
22 #include <istream> // NOLINT
23 #include <ostream> // NOLINT
24 
25 #include "ion/base/logging.h"
26 #include "ion/base/static_assert.h"
27 #include "ion/base/stringutils.h"
28 #include "ion/math/vector.h"
29 #include "ion/math/vectorutils.h"
30 
31 namespace ion {
32 namespace math {
33 
38 template <typename T, int N> struct Range1TWrapper {
40  Range1TWrapper(const T& t_in) : t(t_in) {} // NOLINT - needs to be implicit.
41  operator T() const { return t; }
42  T& operator[](int index) {
43  DCHECK_EQ(index, 0);
44  return t;
45  }
46  const T& operator[](int index) const {
47  DCHECK_EQ(index, 0);
48  return t;
49  }
50 
51  static const T Zero() { return T(0); }
52 
54  template <typename U> friend std::istream& operator>>(
55  std::istream& in, Range1TWrapper<U, 0>& w);
56 
57  T t;
58 };
59 
60 template <typename T>
61 std::istream& operator>>(std::istream& in, Range1TWrapper<T, 0>& w) {
62  return in >> w.t;
63 }
64 
69 template <int Dimension, typename T>
70 class RangeBase {
71  public:
73  enum { kDimension = Dimension };
74 
77 
80 };
81 
83 template <typename T>
84 class RangeBase<1, T> {
85  public:
86  enum { kDimension = 1 };
89 };
90 
99 template <int Dimension, typename T>
100 class Range : public RangeBase<Dimension, T> {
101  public:
103  typedef typename BaseType::Endpoint Endpoint;
104  typedef typename BaseType::Size Size;
105 
107  Range() { MakeEmpty(); }
108 
112  Range(const Endpoint& min_point, const Endpoint& max_point) {
113  Set(min_point, max_point);
114  }
115 
119  static const Range BuildWithSize(const Endpoint& min_point,
120  const Size& size) {
121  Range r;
122  r.SetWithSize(min_point, size);
123  return r;
124  }
125 
127  void MakeEmpty();
128 
131  bool IsEmpty() const;
132 
135  const Endpoint& GetMinPoint() const { return min_point_; }
136  const Endpoint& GetMaxPoint() const { return max_point_; }
137 
141  void SetMinPoint(const Endpoint& p) { min_point_ = p; }
142  void SetMaxPoint(const Endpoint& p) { max_point_ = p; }
143  void Set(const Endpoint& min_point, const Endpoint& max_point) {
144  min_point_ = min_point;
145  max_point_ = max_point;
146  }
147 
149  void SetMinComponent(int i, T value);
150  void SetMaxComponent(int i, T value);
151 
155  void SetWithSize(const Endpoint& min_point, const Size& size) {
156  min_point_ = min_point;
157  max_point_ = min_point + size;
158  }
159 
161  const Size GetSize() const {
162  return IsEmpty() ? Size::Zero() : max_point_ - min_point_;
163  }
164 
167  const Endpoint GetCenter() const {
168  return IsEmpty() ? Endpoint::Zero() :
169  min_point_ + ((max_point_ - min_point_) / static_cast<T>(2));
170  }
171 
174  void ExtendByPoint(const Endpoint& p);
175 
178  void ExtendByRange(const Range& r);
179 
182  bool ContainsPoint(const Endpoint& p) const;
183 
186  bool ContainsRange(const Range& r) const;
187 
190  bool IntersectsRange(const Range& r) const;
191 
193  friend bool operator==(const Range& m0, const Range& m1) {
195  const bool m0_empty = m0.IsEmpty();
196  const bool m1_empty = m1.IsEmpty();
197  if (m0_empty || m1_empty)
198  return m0_empty == m1_empty;
199  else
200  return m0.min_point_ == m1.min_point_ && m0.max_point_ == m1.max_point_;
201  }
202  friend bool operator!=(const Range& m0, const Range& m1) {
203  return !(m0 == m1);
204  }
205 
206  private:
209  void ExtendMinByPoint(const Endpoint& p);
212  void ExtendMaxByPoint(const Endpoint& p);
213 
214  Endpoint min_point_;
215  Endpoint max_point_;
216 };
217 
219 template <int Dimension, typename T>
220 std::ostream& operator<<(std::ostream& out, const Range<Dimension, T>& r) {
221  if (r.IsEmpty())
222  return out << "R[EMPTY]";
223  else
224  return out << "R[" << r.GetMinPoint() << ", " << r.GetMaxPoint() << "]";
225 }
226 
228 template <int Dimension, typename T>
229 std::istream& operator>>(std::istream& in, Range<Dimension, T>& r) {
230  if (base::GetExpectedString(in, "R[")) {
231  if (base::GetExpectedString(in, "EMPTY]")) {
232  r = Range<Dimension, T>();
233  } else {
235  in.clear();
236  typename Range<Dimension, T>::Endpoint min_point, max_point;
237  if (in >> min_point >> base::GetExpectedChar<','> >> max_point
238  >> base::GetExpectedChar<']'>)
239  r.Set(min_point, max_point);
240  }
241  }
242 
243  return in;
244 }
245 
247 
250 
251 
253 template <int Dimension, typename T>
255  for (int i = 0; i < Dimension; ++i) {
257  min_point_[i] = static_cast<T>(1);
258  max_point_[i] = static_cast<T>(0);
259  }
260 }
261 
263 template <int Dimension, typename T>
265  for (int i = 0; i < Dimension; ++i) {
266  if (min_point_[i] > max_point_[i])
267  return true;
268  }
269  return false;
270 }
271 
272 template <int Dimension, typename T>
274  DCHECK_LE(0, i);
275  DCHECK_GT(Dimension, i);
276  if (0 <= i && i < Dimension)
277  min_point_[i] = value;
278 }
279 
280 template <int Dimension, typename T>
282  DCHECK_LE(0, i);
283  DCHECK_GT(Dimension, i);
284  if (0 <= i && i < Dimension)
285  max_point_[i] = value;
286 }
287 
288 template <int Dimension, typename T>
290  if (IsEmpty()) {
291  min_point_ = max_point_ = p;
292  } else {
293  ExtendMinByPoint(p);
294  ExtendMaxByPoint(p);
295  }
296 }
297 
298 template <int Dimension, typename T>
301  if (!r.IsEmpty()) {
302  if (IsEmpty()) {
303  *this = r;
304  } else {
305  ExtendMinByPoint(r.GetMinPoint());
306  ExtendMaxByPoint(r.GetMaxPoint());
307  }
308  }
309 }
310 
312 template <int Dimension, typename T>
314  for (int i = 0; i < Dimension; ++i) {
315  if (p[i] < min_point_[i] || p[i] > max_point_[i])
316  return false;
317  }
318  return true;
319 }
320 
321 template <int Dimension, typename T>
323  return ContainsPoint(r.GetMinPoint()) && ContainsPoint(r.GetMaxPoint());
324 }
325 
326 template <int Dimension, typename T>
328  const Endpoint& r_min_point = r.GetMinPoint();
329  const Endpoint& r_max_point = r.GetMaxPoint();
330  for (int i = 0; i < Dimension; ++i) {
331  if (min_point_[i] > r_max_point[i]) return false;
332  if (max_point_[i] < r_min_point[i]) return false;
333  }
334  return true;
335 }
336 
338 template <int Dimension, typename T>
339 void Range<Dimension, T>::ExtendMinByPoint(const Endpoint& p) {
340  for (int i = 0; i < Dimension; ++i) {
341  min_point_[i] = std::min(p[i], min_point_[i]);
342  }
343 }
344 
346 template <int Dimension, typename T>
347 void Range<Dimension, T>::ExtendMaxByPoint(const Endpoint& p) {
348  for (int i = 0; i < Dimension; ++i) {
349  max_point_[i] = std::max(p[i], max_point_[i]);
350  }
351 }
352 
354 
357 
358 
391 
393 
396 
397 
398 template<>
399 inline void Range3d::MakeEmpty() {
400  min_point_[0] = 1.0;
401  min_point_[1] = 1.0;
402  min_point_[2] = 1.0;
403  max_point_[0] = -1.0;
404  max_point_[1] = -1.0;
405  max_point_[2] = -1.0;
406 }
407 
408 template<>
409 inline bool Range3d::IsEmpty() const {
410  return
411  min_point_[0] > max_point_[0] ||
412  min_point_[1] > max_point_[1] ||
413  min_point_[2] > max_point_[2];
414 }
415 
416 template<>
417 inline bool Range3d::ContainsPoint(const Point3d& p) const {
418  return
419  p[0] >= min_point_[0] && p[0] <= max_point_[0] &&
420  p[1] >= min_point_[1] && p[1] <= max_point_[1] &&
421  p[2] >= min_point_[2] && p[2] <= max_point_[2];
422 }
423 
424 template<>
425 inline void Range3d::ExtendMinByPoint(const Point3d& p) {
426  min_point_[0] = std::min(p[0], min_point_[0]);
427  min_point_[1] = std::min(p[1], min_point_[1]);
428  min_point_[2] = std::min(p[2], min_point_[2]);
429 }
430 
431 template<>
432 inline void Range3d::ExtendMaxByPoint(const Point3d& p) {
433  max_point_[0] = std::max(p[0], max_point_[0]);
434  max_point_[1] = std::max(p[1], max_point_[1]);
435  max_point_[2] = std::max(p[2], max_point_[2]);
436 }
437 
438 template<>
439 inline void Range3f::MakeEmpty() {
440  min_point_[0] = 1.0f;
441  min_point_[1] = 1.0f;
442  min_point_[2] = 1.0f;
443  max_point_[0] = -1.0f;
444  max_point_[1] = -1.0f;
445  max_point_[2] = -1.0f;
446 }
447 
448 template<>
449 inline bool Range3f::IsEmpty() const {
450  return
451  min_point_[0] > max_point_[0] ||
452  min_point_[1] > max_point_[1] ||
453  min_point_[2] > max_point_[2];
454 }
455 
456 template<>
457 inline bool Range3f::ContainsPoint(const Point3f& p) const {
458  return
459  p[0] >= min_point_[0] && p[0] <= max_point_[0] &&
460  p[1] >= min_point_[1] && p[1] <= max_point_[1] &&
461  p[2] >= min_point_[2] && p[2] <= max_point_[2];
462 }
463 
464 template<>
465 inline void Range3f::ExtendMinByPoint(const Point3f& p) {
466  min_point_[0] = std::min(p[0], min_point_[0]);
467  min_point_[1] = std::min(p[1], min_point_[1]);
468  min_point_[2] = std::min(p[2], min_point_[2]);
469 }
470 
471 template<>
472 inline void Range3f::ExtendMaxByPoint(const Point3f& p) {
473  max_point_[0] = std::max(p[0], max_point_[0]);
474  max_point_[1] = std::max(p[1], max_point_[1]);
475  max_point_[2] = std::max(p[2], max_point_[2]);
476 }
477 
478 } // namespace math
479 } // namespace ion
480 
481 #endif // ION_MATH_RANGE_H_
Range< 4, double > Range4d
Definition: range.h:390
Range()
The default constructor defines an empty Range.
Definition: range.h:107
static const Range BuildWithSize(const Endpoint &min_point, const Size &size)
Convenience function that returns a Range from a minimum point and the Range size.
Definition: range.h:119
const Endpoint & GetMinPoint() const
Returns the minimum or maximum endpoint.
Definition: range.h:135
void SetMaxComponent(int i, T value)
Definition: range.h:281
Range1TWrapper< T, 1 > Size
Definition: range.h:88
Range< 3, int32 > Range3i
Definition: range.h:379
Range< 4, uint32 > Range4ui
Definition: range.h:388
Range(const Endpoint &min_point, const Endpoint &max_point)
Constructor that takes the minimum and maximum points.
Definition: range.h:112
const Size GetSize() const
Returns the size of the range, or the zero vector if the Range is empty.
Definition: range.h:161
The Range class defines an N-dimensional interval defined by minimum and maximum N-dimensional endpoi...
Definition: range.h:100
void MakeEmpty()
Sets the Range to be empty.
Definition: range.h:254
void ExtendByPoint(const Endpoint &p)
Extends the Range if necessary to contain the given point.
Definition: range.h:289
static const Vector Zero()
Returns a Vector containing all zeroes.
Definition: vector.h:201
Range< 1, int32 > Range1i
Definition: range.h:363
double value
Range< 2, double > Range2d
Definition: range.h:374
bool IntersectsRange(const Range &r) const
Returns true if this Range overlaps the given Range, i.e., there exists at least one point contained ...
Definition: range.h:327
Range< 4, float > Range4f
Definition: range.h:389
void SetWithSize(const Endpoint &min_point, const Size &size)
Sets the Range from the minimum point and Range size.
Definition: range.h:155
#define DCHECK_GT(val1, val2)
Definition: logging.h:337
bool ContainsRange(const Range &r) const
Returns true if this Range fully contains the given Range by testing both min/max points of input Ran...
Definition: range.h:322
Range1TWrapper< T, 0 > Endpoint
Definition: range.h:87
friend std::istream & operator>>(std::istream &in, Range1TWrapper< U, 0 > &w)
Allows reading wrapped value from a stream.
Range< 2, float > Range2f
Definition: range.h:373
Range< 2, uint16 > Range2ui16
Definition: range.h:370
Range< 2, int32 > Range2i
Definition: range.h:371
Range< 1, uint32 > Range1ui
Definition: range.h:364
const Endpoint GetCenter() const
Returns the point at the center of the range, or the origin if the range is empty.
Definition: range.h:167
Range< 3, uint16 > Range3ui16
Definition: range.h:378
Range< 3, uint32 > Range3ui
Definition: range.h:380
Range< 1, uint16 > Range1ui16
Definition: range.h:362
The RangeBase class makes it possible to treat Ranges with Dimension=1 specially. ...
Definition: range.h:70
Range< 3, uint8 > Range3ui8
Definition: range.h:376
T & operator[](int index)
Definition: range.h:42
BaseType::Size Size
Definition: range.h:104
Range< 3, float > Range3f
Definition: range.h:381
const T & operator[](int index) const
Definition: range.h:46
Range< 1, int16 > Range1i16
Definition: range.h:361
Range< 4, int8 > Range4i8
Definition: range.h:383
Range< 3, double > Range3d
Definition: range.h:382
This struct allows the Endpoint and Size types in a Range<1, T> to be treated like those of higher-di...
Definition: range.h:38
Range< 4, uint8 > Range4ui8
Definition: range.h:384
std::istream & GetExpectedChar(std::istream &in)
Reads a single character from the stream and returns the stream.
Definition: stringutils.h:215
bool IsEmpty() const
Returns true if the Range is empty, meaning that the minimum value is strictly greater than the maxim...
Definition: range.h:264
void SetMaxPoint(const Endpoint &p)
Definition: range.h:142
Copyright 2016 Google Inc.
Range< 3, int8 > Range3i8
Definition: range.h:375
Vector.
Definition: vector.h:180
void SetMinPoint(const Endpoint &p)
Modifies the minimum or maximum endpoint, or both.
Definition: range.h:141
Range< 2, uint8 > Range2ui8
Definition: range.h:368
RangeBase< Dimension, T > BaseType
Definition: range.h:102
std::istream & GetExpectedString(std::istream &in, const std::string &expected)
Attempts to read a string from the stream and returns the stream.
Definition: stringutils.h:228
Range< 2, int8 > Range2i8
Definition: range.h:367
#define DCHECK_EQ(val1, val2)
Definition: logging.h:332
Range< 3, int16 > Range3i16
Definition: range.h:377
Range< 4, uint16 > Range4ui16
Definition: range.h:386
static const T Zero()
Definition: range.h:51
bool ContainsPoint(const Endpoint &p) const
Returns true if the Range contains the given point.
Definition: range.h:313
#define DCHECK_LE(val1, val2)
Definition: logging.h:334
Range1TWrapper(const T &t_in)
Definition: range.h:40
friend bool operator!=(const Range &m0, const Range &m1)
Definition: range.h:202
void Set(const Endpoint &min_point, const Endpoint &max_point)
Definition: range.h:143
static const Point Zero()
Returns a Point containing all zeroes.
Definition: vector.h:320
Range< 1, int8 > Range1i8
Dimension- and type-specific typedefs.
Definition: range.h:359
Range< 4, int16 > Range4i16
Definition: range.h:385
Point.
Definition: vector.h:296
Range< 4, int32 > Range4i
Definition: range.h:387
Range< 2, uint32 > Range2ui
Definition: range.h:372
Range< 1, double > Range1d
Definition: range.h:366
std::istream & operator>>(std::istream &in, Angle< T > &a)
Definition: angle.h:135
const Endpoint & GetMaxPoint() const
Definition: range.h:136
void SetMinComponent(int i, T value)
Modifies a single element for the minimum or maximum endpoint.
Definition: range.h:273
Vector< Dimension, T > Size
Convenience typedef for the size of a Range.
Definition: range.h:79
BaseType::Endpoint Endpoint
Definition: range.h:103
void ExtendByRange(const Range &r)
Extends the Range if necessary to contain the given Range.
Definition: range.h:299
Range< 2, int16 > Range2i16
Definition: range.h:369
Range< 1, uint8 > Range1ui8
Definition: range.h:360
friend bool operator==(const Range &m0, const Range &m1)
Exact equality and inequality comparisons.
Definition: range.h:193
Point< Dimension, T > Endpoint
Convenience typedef for a Range endpoint type.
Definition: range.h:76
Range< 1, float > Range1f
Definition: range.h:365