HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_BoundingRect.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_BoundingRect.h (UT Library, C++)
7  *
8  * COMMENTS: Bounding Rectangle (floating point)
9  */
10 
11 #ifndef __UT_BoundingRect_H__
12 #define __UT_BoundingRect_H__
13 
14 #include "UT_API.h"
15 #include "UT_Assert.h"
16 #include "UT_Vector2.h"
17 
18 #include <SYS/SYS_Math.h>
19 #include <SYS/SYS_Hash.h>
20 
21 #include <iosfwd>
22 
23 
24 class UT_JSONWriter;
25 class UT_JSONValue;
26 class UT_JSONParser;
27 
28 template <typename T>
30 {
31 public:
33 
35  UT_BoundingRectT(T xmin, T ymin, T xmax, T ymax)
36  {
37  vals[0][0] = xmin;
38  vals[1][0] = ymin;
39  vals[0][1] = xmax;
40  vals[1][1] = ymax;
41  }
42 
43  UT_BoundingRectT(const UT_Vector2T<T> &lowerbound,
44  const UT_Vector2T<T> &upperbound)
45  {
46  vals[0][0] = lowerbound.vec[0];
47  vals[0][1] = upperbound.vec[0];
48  vals[1][0] = lowerbound.vec[1];
49  vals[1][1] = upperbound.vec[1];
50  }
51 
52  template<typename U>
54  {
55  vals[0][0] = T(src.vals[0][0]);
56  vals[0][1] = T(src.vals[0][1]);
57  vals[1][0] = T(src.vals[1][0]);
58  vals[1][1] = T(src.vals[1][1]);
59  }
60 
61  T operator()(unsigned m, unsigned n) const
62  {
63  UT_ASSERT_P( m < 2 && n < 2 );
64  return vals[m][n];
65  }
66  T &operator()(unsigned m, unsigned n)
67  {
68  UT_ASSERT_P( m < 2 && n < 2 );
69  return vals[m][n];
70  }
71 
72  int operator==(const UT_BoundingRectT<T> &brect) const
73  {
74  return (vals[0][0] == brect.vals[0][0] &&
75  vals[0][1] == brect.vals[0][1] &&
76  vals[1][0] == brect.vals[1][0] &&
77  vals[1][1] == brect.vals[1][1] );
78  }
79  bool operator!=(const UT_BoundingRectT<T> &brect) const
80  {
81  return !(*this == brect);
82  }
83 
84  int contains(const UT_Vector2T<T> &pt) const
85  {
86  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
87  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
88  return 1;
89  }
90  int contains(const UT_Vector2T<T> &pt, T tol) const
91  {
92  if (vals[0][0] > pt.x() + tol ||
93  vals[0][1] < pt.x() - tol)
94  return 0;
95  if (vals[1][0] > pt.y() + tol ||
96  vals[1][1] < pt.y() - tol)
97  return 0;
98  return 1;
99  }
100  int contains(T x, T y) const
101  {
102  return (x >= vals[0][0] && x <= vals[0][1] &&
103  y >= vals[1][0] && y <= vals[1][1] );
104  }
106  {
107  UT_Vector2T<T> closest_pt(pt.x(), pt.y());
108 
109  if (closest_pt.x() < xmin())
110  closest_pt.x() = xmin();
111  else if (closest_pt.x() > xmax())
112  closest_pt.x() = xmax();
113 
114  if (closest_pt.y() < ymin())
115  closest_pt.y() = ymin();
116  else if (closest_pt.y() > ymax())
117  closest_pt.y() = ymax();
118 
119  return closest_pt;
120  }
121 
122  int isInside(const UT_BoundingRectT<T> &brect) const
123  {
124  // are we inside brect?
125  return (vals[0][0] >= brect.vals[0][0] &&
126  vals[0][1] <= brect.vals[0][1] &&
127  vals[1][0] >= brect.vals[1][0] &&
128  vals[1][1] <= brect.vals[1][1] );
129  }
130 
131  // Determine whether a triangle defined by (v0, v1, v2) intersects the rect
132  inline int intersects(const UT_Vector2T<T> &v0,
133  const UT_Vector2T<T> &v1,
134  const UT_Vector2T<T> &v2) const;
135  // Determine whether a line between v0 & v1 intersects the rect
136  inline int intersects(const UT_Vector2T<T> &v0,
137  const UT_Vector2T<T> &v1) const;
138  inline int intersects(const UT_BoundingRectT<T> &rect) const
139  {
140  if (vals[0][0] > rect.vals[0][1] ||
141  vals[0][1] < rect.vals[0][0])
142  return 0;
143  if (vals[1][0] > rect.vals[1][1] ||
144  vals[1][1] < rect.vals[1][0])
145  return 0;
146  return 1;
147  }
148  inline int intersects(const UT_BoundingRectT<T> &rect, T tol) const
149  {
150  if (vals[0][0] > rect.vals[0][1] + tol ||
151  vals[0][1] < rect.vals[0][0] - tol)
152  return 0;
153  if (vals[1][0] > rect.vals[1][1] + tol ||
154  vals[1][1] < rect.vals[1][0] - tol)
155  return 0;
156  return 1;
157  }
158 
160  {
161  if (!intersects(src))
162  return false;
163  intersectBounds(src);
164  return true;
165  }
167  {
168  vals[0][0] = SYSmax(vals[0][0], src.vals[0][0]);
169  vals[0][1] = SYSmin(vals[0][1], src.vals[0][1]);
170  vals[1][0] = SYSmax(vals[1][0], src.vals[1][0]);
171  vals[1][1] = SYSmin(vals[1][1], src.vals[1][1]);
172  }
173  void clampX(T min, T max)
174  {
175  vals[0][0] = SYSmax(vals[0][0], min);
176  vals[0][1] = SYSmin(vals[0][1], max);
177  }
178  void clampY(T min, T max)
179  {
180  vals[1][0] = SYSmax(vals[1][0], min);
181  vals[1][1] = SYSmin(vals[1][1], max);
182  }
183 
184  /// Check whether the bounding box contains at least one point.
185  bool isValid() const
186  {
187  return vals[0][0] <= vals[0][1] &&
188  vals[1][0] <= vals[1][1];
189  }
190  void makeInvalid() { initBounds(); }
191 
192  /// Initialize the box such that
193  /// - No points are contained in the box
194  /// - The box occupies no position in space
195  void initBounds()
196  {
197  vals[0][0] =
198  vals[1][0] =
200  vals[0][1] =
201  vals[1][1] =
203  }
204  void initBounds(const UT_Vector2T<T> &pt)
205  {
206  vals[0][0] = vals[0][1] = pt.x();
207  vals[1][0] = vals[1][1] = pt.y();
208  }
209  void initBounds(T x, T y)
210  {
211  vals[0][0] = vals[0][1] = x;
212  vals[1][0] = vals[1][1] = y;
213  }
214  void initBounds(T xmin, T xmax, T ymin, T ymax)
215  {
216  vals[0][0] = xmin; vals[0][1] = xmax;
217  vals[1][0] = ymin; vals[1][1] = ymax;
218  }
219  void initBounds(const fpreal32 *v) { initBounds(v[0], v[1]); }
220  void initBounds(const fpreal64 *v) { initBounds(v[0], v[1]); }
221  void initBounds(const UT_BoundingRectT<T> &rect)
222  {
223  vals[0][0] = rect.vals[0][0];
224  vals[0][1] = rect.vals[0][1];
225  vals[1][0] = rect.vals[1][0];
226  vals[1][1] = rect.vals[1][1];
227  }
228 
229  /// Initialize the box to the largest size
231  {
232  vals[0][0] = vals[1][0] =
234  vals[0][1] = vals[1][1] =
236  }
237 
239  {
240  enlargeBounds(pt.x(), pt.y());
241  }
242  void enlargeBounds(T x, T y)
243  {
244  vals[0][0] = SYSmin(vals[0][0], x);
245  vals[0][1] = SYSmax(vals[0][1], x);
246  vals[1][0] = SYSmin(vals[1][0], y);
247  vals[1][1] = SYSmax(vals[1][1], y);
248  }
249  void enlargeBounds(const fpreal32 *v) { enlargeBounds(v[0], v[1]); }
250  void enlargeBounds(const fpreal64 *v) { enlargeBounds(v[0], v[1]); }
251  void enlargeBounds(T xmin, T xmax, T ymin, T ymax)
252  {
253  vals[0][0] = SYSmin(vals[0][0], xmin);
254  vals[0][1] = SYSmax(vals[0][1], xmax);
255  vals[1][0] = SYSmin(vals[1][0], ymin);
256  vals[1][1] = SYSmax(vals[1][1], ymax);
257  }
259  {
260  vals[0][0] = SYSmin(vals[0][0], rect(0, 0));
261  vals[0][1] = SYSmax(vals[0][1], rect(0, 1));
262  vals[1][0] = SYSmin(vals[1][0], rect(1, 0));
263  vals[1][1] = SYSmax(vals[1][1], rect(1, 1));
264  }
265  void expandBounds(T dx, T dy)
266  {
267  vals[0][0] -= dx;
268  vals[0][1] += dx;
269  vals[1][0] -= dy;
270  vals[1][1] += dy;
271  }
272  void stretch(T percent = 0.001, T min = 0.001)
273  {
274  T d;
275  d = min + sizeX()*percent;
276  vals[0][0] -= d; vals[0][1] += d;
277  d = min + sizeY()*percent;
278  vals[1][0] -= d; vals[1][1] += d;
279  }
280  void translate(T x, T y)
281  {
282  vals[0][0] += x;
283  vals[0][1] += x;
284  vals[1][0] += y;
285  vals[1][1] += y;
286  }
287  void scale(T xscale, T yscale)
288  {
289  vals[0][0] *= xscale; vals[0][1] *= xscale;
290  vals[1][0] *= yscale; vals[1][1] *= yscale;
291  }
292 
294  {
295  int flag = 0;
296 
297  if (xmin() > box.xmax()) flag |= 0x01;
298  else if (xmax() < box.xmin()) flag |= 0x02;
299  if (ymin() > box.ymax()) flag |= 0x04;
300  else if (ymax() < box.ymin()) flag |= 0x08;
301 
302  return flag;
303  }
304 
305  T sizeX() const { return vals[0][1] - vals[0][0]; }
306  T sizeY() const { return vals[1][1] - vals[1][0]; }
307 
308  T centerX() const { return (vals[0][0] + vals[0][1]) * 0.5; }
309  T centerY() const { return (vals[1][0] + vals[1][1]) * 0.5; }
310 
311  // projects (x,y) orthogonally to the closest point on the rectangle.
312  // Result is stored back into x and y. If valid addresses are passed into
313  // touchx and touchy, then, the values in those addresses would indicate
314  // if the new (x,y) now touches the x edges or y edges of the rectangle.
315  inline void project(T &x, T &y, int *touchx=0, int *touchy=0) const;
316 
317  T LX() const { return vals[0][0]; }
318  T LY() const { return vals[1][0]; }
319  T UX() const { return vals[0][1]; }
320  T UY() const { return vals[1][1]; }
321 
322  T &LX() { return vals[0][0]; }
323  T &LY() { return vals[1][0]; }
324  T &UX() { return vals[0][1]; }
325  T &UY() { return vals[1][1]; }
326 
327  void setX0(T v) { vals[0][0] = v; }
328  void setX1(T v) { vals[0][1] = v; }
329  void setY0(T v) { vals[1][0] = v; }
330  void setY1(T v) { vals[1][1] = v; }
331 
332  T getX0() const { return vals[0][0]; }
333  T getX1() const { return vals[0][1]; }
334  T getY0() const { return vals[1][0]; }
335  T getY1() const { return vals[1][1]; }
336 
337  T &getX0() { return vals[0][0]; }
338  T &getX1() { return vals[0][1]; }
339  T &getY0() { return vals[1][0]; }
340  T &getY1() { return vals[1][1]; }
341 
342  T xmin() const { return vals[0][0]; }
343  T xmax() const { return vals[0][1]; }
344  T ymin() const { return vals[1][0]; }
345  T ymax() const { return vals[1][1]; }
346 
347  T xsize() const { return vals[0][1] - vals[0][0]; }
348  T ysize() const { return vals[1][1] - vals[1][0]; }
349 
350  // Intersect a ray with the rect. Returns 0 if no intersection found.
351  // distance will be set to the intersection distance (between 0 & tmax)
352  inline int intersectRay(const UT_Vector2T<T> &orig,
353  const UT_Vector2T<T> &dir,
354  T tmax = 1E17,
355  T *distance = 0,
356  UT_Vector2T<T> *xsect = 0) const;
357 
358  // I/O friends:
359  friend std::ostream &operator<<(std::ostream &os,
360  const UT_BoundingRectT<T> &brect)
361  {
362  brect.save(os);
363  return os;
364  }
365  /// @{
366  /// Methods to serialize to a JSON stream. The vector is stored as an
367  /// array of 4 reals (xmin, xmax, ymin, ymax)
368  bool save(UT_JSONWriter &w) const;
369  bool save(UT_JSONValue &v) const;
370  bool load(UT_JSONParser &p);
371  /// @}
372 
373  void dump(const char *msg="") const;
374  void dump(std::ostream &os) const;
375 
376  /// @{
377  /// Access to the serialized data
378  const T *getSerialized() const { return myFloats; }
379  const T *data() const { return myFloats; }
380  T *data() { return myFloats; }
381  /// @}
382 
383  /// @{
384  /// Iterate over the data serially
385  const T *begin() const { return &myFloats[0]; }
386  const T *end() const { return &myFloats[4]; }
387  T *begin() { return &myFloats[0]; }
388  T *end() { return &myFloats[4]; }
389  /// @}
390 
391  /// @{
392  /// Compute a hash
393  uint64 hash() const { return SYShashRange(begin(), end()); }
394  friend std::size_t hash_value(const this_type &t) { return t.hash(); }
395  /// @}
396 
397  union {
398  T vals[2][2];
399  T myFloats[4];
400  };
401 private:
402  void save(std::ostream &os) const;
403 };
404 
405 template <typename T>
406 UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingRectT<T> &v);
407 
414 
415 #include "UT_BoundingRectImpl.h"
416 
417 #endif
int intersects(const UT_BoundingRectT< T > &rect, T tol) const
#define SYSmax(a, b)
Definition: SYS_Math.h:1365
void stretch(T percent=0.001, T min=0.001)
UT_BoundingRectT(const UT_BoundingRectT< U > &src)
UT_BoundingRectT< fpreal > UT_BoundingRectR
UT_BoundingRectT< int64 > UT_BoundingRectI
GLenum GLuint GLsizei bufsize
Definition: glcorearb.h:1817
void initBounds(T xmin, T xmax, T ymin, T ymax)
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:128
const T * getSerialized() const
const GLdouble * v
Definition: glcorearb.h:836
bool intersectIfOverlapping(const UT_BoundingRectT< T > &src)
const T * data() const
T & x(void)
Definition: UT_Vector2.h:284
void scale(T xscale, T yscale)
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:72
uint8 cohenSutherland(const UT_BoundingRectT< T > &box) const
#define UT_API
Definition: UT_API.h:12
GLint y
Definition: glcorearb.h:102
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
void enlargeBounds(const UT_BoundingRectT< T > &rect)
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
2D Vector class.
Definition: UT_Vector2.h:137
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
void enlargeBounds(const UT_Vector2T< T > &pt)
const hboost::disable_if_c< VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:132
bool save(UT_JSONWriter &w) const
int contains(const UT_Vector2T< T > &pt, T tol) const
GLdouble n
Definition: glcorearb.h:2007
UT_BoundingRectT< float > UT_BoundingRect
unsigned long long uint64
Definition: SYS_Types.h:107
int contains(T x, T y) const
const T * begin() const
UT_BoundingRectT< fpreal32 > UT_BoundingRectF
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:634
void initMaxBounds()
Initialize the box to the largest size.
double fpreal64
Definition: SYS_Types.h:191
GLuint GLuint end
Definition: glcorearb.h:474
void enlargeBounds(const fpreal32 *v)
bool isValid() const
Check whether the bounding box contains at least one point.
void initBounds(const fpreal64 *v)
T & operator()(unsigned m, unsigned n)
int intersects(const UT_BoundingRectT< T > &rect) const
void enlargeBounds(const fpreal64 *v)
void enlargeBounds(T x, T y)
int operator==(const UT_BoundingRectT< T > &brect) const
friend std::ostream & operator<<(std::ostream &os, const UT_BoundingRectT< T > &brect)
void clampX(T min, T max)
GLfloat v0
Definition: glcorearb.h:815
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
void initBounds(const UT_Vector2T< T > &pt)
UT_BoundingRectT(T xmin, T ymin, T xmax, T ymax)
UT_BoundingRectT< int32 > UT_BoundingRecti
UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingRectT< T > &v)
unsigned char uint8
Definition: SYS_Types.h:31
bool intersects(const Box< Vec3< T > > &b, const Line3< T > &r, Vec3< T > &ip)
Definition: ImathBoxAlgo.h:728
void clampY(T min, T max)
bool operator!=(const UT_BoundingRectT< T > &brect) const
GLint GLenum GLint x
Definition: glcorearb.h:408
GLfloat GLfloat v1
Definition: glcorearb.h:816
void translate(T x, T y)
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:75
T operator()(unsigned m, unsigned n) const
T & y(void)
Definition: UT_Vector2.h:286
UT_Vector2T< T > closestPoint(const UT_Vector2T< T > &pt) const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
friend std::size_t hash_value(const this_type &t)
uint64 hash() const
void expandBounds(T dx, T dy)
const T * end() const
int isInside(const UT_BoundingRectT< T > &brect) const
void enlargeBounds(T xmin, T xmax, T ymin, T ymax)
void initBounds(T x, T y)
int contains(const UT_Vector2T< T > &pt) const
png_infop png_uint_32 flag
Definition: png.h:2242
#define SYSmin(a, b)
Definition: SYS_Math.h:1366
UT_BoundingRectT< T > this_type
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER Vec project(const Vec &s, const Vec &t)
Definition: ImathVecAlgo.h:96
void intersectBounds(const UT_BoundingRectT< T > &src)
float fpreal32
Definition: SYS_Types.h:190
UT_BoundingRectT< fpreal64 > UT_BoundingRectD
void initBounds(const fpreal32 *v)
void initBounds(const UT_BoundingRectT< T > &rect)
UT_BoundingRectT(const UT_Vector2T< T > &lowerbound, const UT_Vector2T< T > &upperbound)
GLenum src
Definition: glcorearb.h:1792