rect.h
1 /*
2 ** UICore
3 ** Copyright (c) 1997-2015 The UICore Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries UICore may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Magnus Norddahl
27 ** Kenneth Gangstoe
28 ** Harry Storbacka
29 ** Mark Page
30 */
31 
32 #pragma once
33 
34 #include "vec2.h"
35 #include "size.h"
36 #include "point.h"
37 #include "origin.h"
38 #include "cl_math.h"
39 
40 namespace uicore
41 {
46  template<typename Type>
47  class Rectx
48  {
49  public:
53  Rectx() : left(0), top(0), right(0), bottom(0) {}
54 
58  Rectx(const Sizex<Type> &s) : left(0), top(0), right(s.width), bottom(s.height) {}
59 
66  Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
67  : left(new_left), top(new_top), right(new_right), bottom(new_bottom) {}
68 
74  : left(p.x), top(p.y), right(p.x + size.width), bottom(p.y + size.height) {}
75 
81  Rectx(Type new_left, Type new_top, const Sizex<Type> &size)
82  : left(new_left), top(new_top), right(new_left + size.width), bottom(new_top + size.height) {}
83 
87  Rectx(const Rectx<int> &rect);
88 
92  Rectx(const Rectx<float> &rect);
93 
97  Rectx(const Rectx<double> &rect);
98 
100  bool operator==(const Rectx<Type> &r) const
101  {
102  return (left == r.left && top == r.top && right == r.right && bottom == r.bottom);
103  }
104 
106  bool operator!=(const Rectx<Type> &r) const
107  {
108  return (left != r.left || top != r.top || right != r.right || bottom != r.bottom);
109  }
110 
112  Rectx<Type> &operator*=(const Type &s)
113  {
114  left *= s; top *= s; right *= s; bottom *= s; return *this;
115  }
116 
118  Rectx<Type> operator*(const Type &s) const
119  {
120  return Rectx<Type>(left*s, top*s, right*s, bottom *s);
121  }
122 
123  static Rectx<Type> wh(Type width, Type height) { return Rectx<Type>(0, 0, width, height); }
124  static Rectx<Type> wh(const Sizex<Type> &size) { return Rectx<Type>(0, 0, size.width, size.height); }
125  static Rectx<Type> xywh(Type x, Type y, Type width, Type height) { return Rectx<Type>(x, y, x + width, y + height); }
126  static Rectx<Type> xywh(const Pointx<Type> &pos, const Sizex<Type> &size) { return Rectx<Type>(pos.x, pos.y, pos.x + size.width, pos.y + size.height); }
127  static Rectx<Type> ltrb(Type left, Type top, Type right, Type bottom) { return Rectx<Type>(left, top, right, bottom); }
128 
130  Type left;
131 
133  Type top;
134 
136  Type right;
137 
139  Type bottom;
140 
142  Type width() const { return right - left; }
143 
145  Type height() const { return bottom - top; }
146 
148  Type x() const { return left; }
149 
151  Type y() const { return top; }
152 
154  Pointx<Type> position() const { return Pointx<Type>(left, top); }
155 
157  Sizex<Type> size() const { return Sizex<Type>(right - left, bottom - top); }
158 
160  bool contains(const Vec2<Type> &p) const
161  {
162  return (p.x >= left && p.x < right)
163  && (p.y >= top && p.y < bottom);
164  }
165 
168  {
169  return Pointx<Type>(left, top);
170  }
171 
174  {
175  return Pointx<Type>(right, top);
176  }
177 
180  {
181  return Pointx<Type>(right, bottom);
182  }
183 
186  {
187  return Pointx<Type>(left, bottom);
188  }
189 
191  bool is_overlapped(const Rectx<Type> &r) const
192  {
193  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
194  }
195 
197  bool is_inside(const Rectx<Type> &r) const
198  {
199  return ((left <= r.left)
200  && (top <= r.top)
201  && (right >= r.right)
202  && (bottom >= r.bottom));
203  }
204 
209  Rectx<Type> rot_bounds(const Vec2<Type> &hotspot, float angle) const;
210 
217  Rectx<Type> rot_bounds(Origin origin, Type x, Type y, float angle) const;
218 
221  {
222  return Pointx<Type>((left + right) / 2, (top + bottom) / 2);
223  }
224 
229  {
230  auto w = width();
231  auto h = height();
232  left = p.x;
233  top = p.y;
234  right = left + w;
235  bottom = top + h;
236  return *this;
237  }
238 
243  {
244  right = left + width;
245  return *this;
246  }
247 
252  {
253  bottom = top + height;
254  return *this;
255  }
256 
260  Rectx<Type> &shrink(const Type &new_left, const Type &new_top, const Type &new_right, const Type &new_bottom)
261  {
262  left += new_left; top += new_top; right -= new_right; bottom -= new_bottom;
263  return *this;
264  };
265 
269  Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
270  {
271  left += left_right; top += top_bottom; right -= left_right; bottom -= top_bottom;
272  return *this;
273  };
274 
278  Rectx<Type> &shrink(const Type &shrink)
279  {
280  left += shrink; top += shrink; right -= shrink; bottom -= shrink;
281  return *this;
282  };
283 
287  Rectx<Type> &expand(const Type &expand_left, const Type &expand_top, const Type &expand_right, const Type &expand_bottom)
288  {
289  left -= expand_left; top -= expand_top; right += expand_right; bottom += expand_bottom;
290  return *this;
291  };
292 
296  Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
297  {
298  left -= left_and_right;
299  right += left_and_right;
300  top -= top_and_bottom;
301  bottom += top_and_bottom;
302  return *this;
303  };
304 
308  Rectx<Type> &expand(const Type &expand)
309  {
310  left -= expand;
311  right += expand;
312  top -= expand;
313  bottom += expand;
314  return *this;
315  };
316 
321  {
322  left += p.x; top += p.y; right += p.x; bottom += p.y;
323  return *this;
324  };
325 
330  {
331  left += p.width; top += p.height; right += p.width; bottom += p.height;
332  return *this;
333  };
334 
339  {
340  left += p.left; top += p.top; right += p.left; bottom += p.top;
341  return *this;
342  };
343 
347  Rectx<Type> &translate(Type x, Type y)
348  {
349  left += x; top += y; right += x; bottom += y;
350  return *this;
351  };
352 
357  {
358  right = left + size.width;
359  bottom = top + size.height;
360  return *this;
361  }
362 
369  {
370  Rectx<Type> result;
371  result.left = max(left, rect.left);
372  result.right = min(right, rect.right);
373  result.top = max(top, rect.top);
374  result.bottom = min(bottom, rect.bottom);
375  if (result.right < result.left)
376  result.left = result.right;
377  if (result.bottom < result.top)
378  result.top = result.bottom;
379 
380  *this = result;
381  return *this;
382  }
383 
390  {
391  Rectx<Type> result;
392  result.left = min(left, rect.left);
393  result.right = max(right, rect.right);
394  result.top = min(top, rect.top);
395  result.bottom = max(bottom, rect.bottom);
396  *this = result;
397  return *this;
398  }
399 
407  {
408  if (left > right)
409  right = left;
410 
411  if (top > bottom)
412  bottom = top;
413 
414  return *this;
415  }
416 
423  Rectx<Type> &apply_alignment(Origin origin, Type x, Type y)
424  {
425  Vec2<Type> offset = Vec2<Type>::calc_origin(origin, size());
426  offset.x -= x;
427  offset.y -= y;
428 
429  left += offset.x;
430  top += offset.y;
431  right += offset.x;
432  bottom += offset.y;
433  return *this;
434  }
435 
440  {
441  top = max(top, cr.top);
442  left = max(left, cr.left);
443  right = min(right, cr.right);
444  bottom = min(bottom, cr.bottom);
445  top = min(top, bottom);
446  left = min(left, right);
447  return *this;
448  }
449  };
450 
451  template<>
452  inline Rectx<int>::Rectx(const Rectx<float> &rect)
453  : left(static_cast<int> (floor(rect.left + 0.5f))),
454  top(static_cast<int> (floor(rect.top + 0.5f))),
455  right(static_cast<int> (floor(rect.right + 0.5f))),
456  bottom(static_cast<int> (floor(rect.bottom + 0.5f)))
457  {
458  }
459 
460  template<>
461  inline Rectx<int>::Rectx(const Rectx<double> &rect)
462  : left(static_cast<int> (floor(rect.left + 0.5))),
463  top(static_cast<int> (floor(rect.top + 0.5))),
464  right(static_cast<int> (floor(rect.right + 0.5))),
465  bottom(static_cast<int> (floor(rect.bottom + 0.5)))
466  {
467  }
468 
469  template<typename Type>
470  inline Rectx<Type>::Rectx(const Rectx<int> &rect)
471  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
472  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
473  {
474  }
475 
476  template<typename Type>
477  inline Rectx<Type>::Rectx(const Rectx<float> &rect)
478  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
479  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
480  {
481  }
482 
483  template<typename Type>
484  inline Rectx<Type>::Rectx(const Rectx<double> &rect)
485  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
486  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
487  {
488  }
489 
491  class Rect : public Rectx<int>
492  {
493  public:
494  Rect() : Rectx<int>() {}
495  Rect(const Sizex<int> &s) : Rectx<int>(s) {}
496  Rect(int new_left, int new_top, int new_right, int new_bottom) : Rectx<int>(new_left, new_top, new_right, new_bottom) {}
497  Rect(const Pointx<int> &p, const Sizex<int> &size) : Rectx<int>(p, size) {}
498  Rect(const Rectx<int> &rect) : Rectx<int>(rect) {}
499  Rect(const Rectx<float> &rect) : Rectx<int>(rect) {}
500  Rect(const Rectx<double> &rect) : Rectx<int>(rect) {}
501  Rect(int new_left, int new_top, const Sizex<int> &size) : Rectx<int>(new_left, new_top, size) {}
502  };
503 
505  class Rectf : public Rectx<float>
506  {
507  public:
508  Rectf() : Rectx<float>() {}
509  Rectf(const Sizex<int> &s) : Rectx<float>(s) {}
510  Rectf(const Sizex<float> &s) : Rectx<float>(s) {}
511  Rectf(float new_left, float new_top, float new_right, float new_bottom) : Rectx<float>(new_left, new_top, new_right, new_bottom) {}
512  Rectf(const Pointx<float> &p, const Sizex<float> &size) : Rectx<float>(p, size) {}
513  Rectf(const Rectx<int> &rect) : Rectx<float>(rect) {}
514  Rectf(const Rectx<float> &rect) : Rectx<float>(rect) {}
515  Rectf(const Rectx<double> &rect) : Rectx<float>(rect) {}
516  Rectf(float new_left, float new_top, const Sizex<float> &size) : Rectx<float>(new_left, new_top, size) {}
517  };
518 
520  class Rectd : public Rectx<double>
521  {
522  public:
523  Rectd() : Rectx<double>() {}
524  Rectd(const Sizex<int> &s) : Rectx<double>(s) {}
525  Rectd(const Sizex<float> &s) : Rectx<double>(s) {}
526  Rectd(const Sizex<double> &s) : Rectx<double>(s) {}
527  Rectd(double new_left, double new_top, double new_right, double new_bottom) : Rectx<double>(new_left, new_top, new_right, new_bottom) {}
528  Rectd(const Pointx<double> &p, const Sizex<double> &size) : Rectx<double>(p, size) {}
529  Rectd(const Rectx<int> &rect) : Rectx<double>(rect) {}
530  Rectd(const Rectx<float> &rect) : Rectx<double>(rect) {}
531  Rectd(const Rectx<double> &rect) : Rectx<double>(rect) {}
532  Rectd(double new_left, double new_top, const Sizex<double> &size) : Rectx<double>(new_left, new_top, size) {}
533  };
534 
535  inline Rect RectPS(int x, int y, int width, int height)
536  {
537  return Rect(x, y, x + width, y + height);
538  }
539 
540  inline Rectf RectfPS(float x, float y, float width, float height)
541  {
542  return Rectf(x, y, x + width, y + height);
543  }
544 
545  inline Rectd RectdPS(double x, double y, double width, double height)
546  {
547  return Rectd(x, y, x + width, y + height);
548  }
549 }
Rectx()
Constructs an rectangle.
Definition: rect.h:53
Rect(const Sizex< int > &s)
Definition: rect.h:495
Rectx< Type > & normalize()
Normalize rectangle.
Definition: rect.h:406
bool operator!=(const Rectx< Type > &r) const
Rect != Rect operator.
Definition: rect.h:106
Rectx< Type > & shrink(const Type &left_right, const Type &top_bottom)
Shrink the rectangle.
Definition: rect.h:269
Rectf(const Sizex< float > &s)
Definition: rect.h:510
Rectd(const Pointx< double > &p, const Sizex< double > &size)
Definition: rect.h:528
Rectf(const Rectx< float > &rect)
Definition: rect.h:514
A min(A a, B b)
Definition: cl_math.h:55
Rectf(const Rectx< int > &rect)
Definition: rect.h:513
static Rectx< Type > xywh(Type x, Type y, Type width, Type height)
Definition: rect.h:125
Rectx< Type > & bounding_rect(const Rectx< Type > &rect)
Calculates the bounding rectangle of the rectangles.
Definition: rect.h:389
static Rectx< Type > xywh(const Pointx< Type > &pos, const Sizex< Type > &size)
Definition: rect.h:126
Sizex< Type > size() const
Returns the size of the rectangle.
Definition: rect.h:157
bool operator==(const Rectx< Type > &r) const
Rect == Rect operator.
Definition: rect.h:100
Rect(const Rectx< float > &rect)
Definition: rect.h:499
static Rectx< Type > ltrb(Type left, Type top, Type right, Type bottom)
Definition: rect.h:127
2D vector
Definition: line.h:43
Rect RectPS(int x, int y, int width, int height)
Definition: rect.h:535
2D (width,height) size structure.
Definition: size.h:51
Rectf(const Rectx< double > &rect)
Definition: rect.h:515
Type top
Y1-coordinate (top point inside the rectangle)
Definition: rect.h:133
static Rectx< Type > wh(Type width, Type height)
Definition: rect.h:123
2D (left,top,right,bottom) rectangle structure - Double
Definition: rect.h:520
Rectx< Type > & set_position(const Vec2< Type > &p)
Sets the position of the rectangle.
Definition: rect.h:228
Rectx(const Sizex< Type > &s)
Constructs an rectangle.
Definition: rect.h:58
Rectd(const Sizex< double > &s)
Definition: rect.h:526
bool is_inside(const Rectx< Type > &r) const
Returns true if rectangle passed is inside this rectangle.
Definition: rect.h:197
Rectd(const Rectx< int > &rect)
Definition: rect.h:529
Type x
Definition: vec2.h:75
Rectx(Type new_left, Type new_top, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:81
2D (x,y) point structure.
Definition: point.h:48
Rectx< Type > & set_size(const Sizex< Type > &size)
Sets the size of the rectangle, maintaining top/left position.
Definition: rect.h:356
static Pointx< Type > calc_origin(Origin origin, const Sizex< Type > &size)
Returns the anchor point for the origin within the dimensions of the size structure.
Rectx< Type > & shrink(const Type &new_left, const Type &new_top, const Type &new_right, const Type &new_bottom)
Shrink the rectangle.
Definition: rect.h:260
Rectx< Type > & expand(const Type &left_and_right, const Type &top_and_bottom)
Expand the rectangle.
Definition: rect.h:296
Rect(const Rectx< int > &rect)
Definition: rect.h:498
Rectx< Type > & shrink(const Type &shrink)
Shrink the rectangle.
Definition: rect.h:278
Rectd RectdPS(double x, double y, double width, double height)
Definition: rect.h:545
Type y() const
Y position of rectangle.
Definition: rect.h:151
Rectd()
Definition: rect.h:523
Rectf(float new_left, float new_top, float new_right, float new_bottom)
Definition: rect.h:511
Rectx< Type > & expand(const Type &expand)
Expand the rectangle.
Definition: rect.h:308
Rectx< Type > & translate(Type x, Type y)
Translate the rect.
Definition: rect.h:347
Rectx< Type > & translate(const Vec2< Type > &p)
Translate the rect.
Definition: rect.h:320
Type bottom
Y2-coordinate (point outside the rectange)
Definition: rect.h:139
Rectd(double new_left, double new_top, const Sizex< double > &size)
Definition: rect.h:532
Rectf(const Sizex< int > &s)
Definition: rect.h:509
Rect(const Rectx< double > &rect)
Definition: rect.h:500
Rectd(const Sizex< int > &s)
Definition: rect.h:524
Rectx< Type > & translate(const Sizex< Type > &p)
Translate the rect.
Definition: rect.h:329
Rectf()
Definition: rect.h:508
Pointx< Type > bottom_right() const
Returns the bottom-right point outside the rectangle.
Definition: rect.h:179
Pointx< Type > top_right() const
Returns the top-right point outside the rectangle.
Definition: rect.h:173
Type y
Definition: vec2.h:76
Type right
X2-coordinate (point outside the rectangle)
Definition: rect.h:136
Rectx< Type > & clip(const Rectx< Type > &cr)
Clip according to the specified clip rectangle.
Definition: rect.h:439
bool is_overlapped(const Rectx< Type > &r) const
Returns true if rectangle passed is overlapping or inside this rectangle.
Definition: rect.h:191
Type height
Size height.
Definition: size.h:74
Rectf(const Pointx< float > &p, const Sizex< float > &size)
Definition: rect.h:512
Rect(int new_left, int new_top, const Sizex< int > &size)
Definition: rect.h:501
Rectf RectfPS(float x, float y, float width, float height)
Definition: rect.h:540
Rect(const Pointx< int > &p, const Sizex< int > &size)
Definition: rect.h:497
Type height() const
Returns the height of the rectangle.
Definition: rect.h:145
Rectf(float new_left, float new_top, const Sizex< float > &size)
Definition: rect.h:516
2D (left,top,right,bottom) rectangle structure - Float
Definition: rect.h:505
Rectx< Type > & apply_alignment(Origin origin, Type x, Type y)
Applies an origin and offset pair to this rectangle.
Definition: rect.h:423
Rectx< Type > & expand(const Type &expand_left, const Type &expand_top, const Type &expand_right, const Type &expand_bottom)
Expand the rectangle.
Definition: rect.h:287
Rectd(double new_left, double new_top, double new_right, double new_bottom)
Definition: rect.h:527
Type left
X1-coordinate (left point inside the rectangle)
Definition: rect.h:130
2D (left,top,right,bottom) rectangle structure - Integer
Definition: rect.h:491
A max(A a, B b)
Definition: cl_math.h:56
Type width
Size width.
Definition: size.h:71
Rectd(const Rectx< double > &rect)
Definition: rect.h:531
Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
Constructs an rectangle.
Definition: rect.h:66
Rectx< Type > & operator*=(const Type &s)
Rect *= operator.
Definition: rect.h:112
Rectd(const Sizex< float > &s)
Definition: rect.h:525
Rectx< Type > & set_height(Type height)
Sets the height of the rectangle.
Definition: rect.h:251
Pointx< Type > bottom_left() const
Returns the bottom-left point outside the rectangle.
Definition: rect.h:185
Pointx< Type > center() const
Returns the center point of the rectangle.
Definition: rect.h:220
Pointx< Type > position() const
Returns the position of the rectangle.
Definition: rect.h:154
Rectx< Type > rot_bounds(const Vec2< Type > &hotspot, float angle) const
Returns another Rectx containing a rotated version of this one.
Rectx< Type > & overlap(const Rectx< Type > &rect)
Calculates the intersection of two rectangles.
Definition: rect.h:368
Pointx< Type > top_left() const
Returns the top-left point inside the rectangle.
Definition: rect.h:167
Rect(int new_left, int new_top, int new_right, int new_bottom)
Definition: rect.h:496
Origin
Alignment origins.
Definition: origin.h:35
Rectx< Type > & set_width(Type width)
Sets the width of the rectangle.
Definition: rect.h:242
Type width() const
Returns the width of the rectangle.
Definition: rect.h:142
Type x() const
X position of rectangle.
Definition: rect.h:148
Rect()
Definition: rect.h:494
static Rectx< Type > wh(const Sizex< Type > &size)
Definition: rect.h:124
Definition: Application/application.h:35
Rectx< Type > operator*(const Type &s) const
Rect * operator.
Definition: rect.h:118
Rectx(const Pointx< Type > &p, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:73
bool contains(const Vec2< Type > &p) const
Returns true if the rectangle contains the point.
Definition: rect.h:160
Rectx< Type > & translate(const Rectx< Type > &p)
Translate the rect by another rect (only uses the left and top coords).
Definition: rect.h:338
Rectd(const Rectx< float > &rect)
Definition: rect.h:530