rect.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2016 The ClanLib 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 ClanLib 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 clan
41 {
44 
49  template<typename Type>
50  class Rectx
51  {
52  public:
56  Rectx() : left(0), top(0), right(0), bottom(0) {}
57 
61  Rectx(const Sizex<Type> &s) : left(0), top(0), right(s.width), bottom(s.height) {}
62 
69  Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
70  : left(new_left), top(new_top), right(new_right), bottom(new_bottom) {}
71 
76  Rectx(const Pointx<Type> &p, const Sizex<Type> &size)
77  : left(p.x), top(p.y), right(p.x + size.width), bottom(p.y + size.height) {}
78 
84  Rectx(Type new_left, Type new_top, const Sizex<Type> &size)
85  : left(new_left), top(new_top), right(new_left + size.width), bottom(new_top + size.height) {}
86 
90  Rectx(const Rectx<int> &rect);
91 
95  Rectx(const Rectx<float> &rect);
96 
100  Rectx(const Rectx<double> &rect);
101 
103  bool operator==(const Rectx<Type> &r) const
104  {
105  return (left == r.left && top == r.top && right == r.right && bottom == r.bottom);
106  }
107 
109  bool operator!=(const Rectx<Type> &r) const
110  {
111  return (left != r.left || top != r.top || right != r.right || bottom != r.bottom);
112  }
113 
115  Rectx<Type> &operator*=(const Type &s)
116  {
117  left *= s; top *= s; right *= s; bottom *= s; return *this;
118  }
119 
121  Rectx<Type> operator*(const Type &s) const
122  {
123  return Rectx<Type>(left*s, top*s, right*s, bottom *s);
124  }
125 
126  static Rectx<Type> xywh(Type x, Type y, Type width, Type height) { return Rectx<Type>(x, y, x + width, y + 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 get_width() const { return right - left; }
143 
145  Type get_height() const { return bottom - top; }
146 
148  Sizex<Type> get_size() const { return Sizex<Type>(right - left, bottom - top); }
149 
151  bool contains(const Vec2<Type> &p) const
152  {
153  return (p.x >= left && p.x < right)
154  && (p.y >= top && p.y < bottom);
155  }
156 
159  {
160  return Pointx<Type>(left, top);
161  }
162 
165  {
166  return Pointx<Type>(right, top);
167  }
168 
171  {
172  return Pointx<Type>(right, bottom);
173  }
174 
177  {
178  return Pointx<Type>(left, bottom);
179  }
180 
182  bool is_overlapped(const Rectx<Type> &r) const
183  {
184  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
185  }
186 
188  bool is_inside(const Rectx<Type> &r) const
189  {
190  return ((left <= r.left)
191  && (top <= r.top)
192  && (right >= r.right)
193  && (bottom >= r.bottom));
194  }
195 
200  Rectx<Type> get_rot_bounds(const Vec2<Type> &hotspot, const Angle &angle) const;
201 
208  Rectx<Type> get_rot_bounds(Origin origin, Type x, Type y, const Angle &angle) const;
209 
212  {
213  return Pointx<Type>((left + right) / 2, (top + bottom) / 2);
214  }
215 
220  {
221  left = p.x;
222  top = p.y;
223  return *this;
224  }
225 
230  {
231  right = p.x;
232  bottom = p.y;
233  return *this;
234  }
235 
239  Rectx<Type> &set_width(Type width)
240  {
241  right = left + width;
242  return *this;
243  }
244 
248  Rectx<Type> &set_height(Type height)
249  {
250  bottom = top + height;
251  return *this;
252  }
253 
257  Rectx<Type> &shrink(const Type &new_left, const Type &new_top, const Type &new_right, const Type &new_bottom)
258  {
259  left += new_left; top += new_top; right -= new_right; bottom -= new_bottom;
260  return *this;
261  };
262 
266  Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
267  {
268  left += left_right; top += top_bottom; right -= left_right; bottom -= top_bottom;
269  return *this;
270  };
271 
275  Rectx<Type> &shrink(const Type &shrink)
276  {
277  left += shrink; top += shrink; right -= shrink; bottom -= shrink;
278  return *this;
279  };
280 
284  Rectx<Type> &expand(const Type &expand_left, const Type &expand_top, const Type &expand_right, const Type &expand_bottom)
285  {
286  left -= expand_left; top -= expand_top; right += expand_right; bottom += expand_bottom;
287  return *this;
288  };
289 
293  Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
294  {
295  left -= left_and_right;
296  right += left_and_right;
297  top -= top_and_bottom;
298  bottom += top_and_bottom;
299  return *this;
300  };
301 
305  Rectx<Type> &expand(const Type &expand)
306  {
307  left -= expand;
308  right += expand;
309  top -= expand;
310  bottom += expand;
311  return *this;
312  };
313 
318  {
319  left += p.x; top += p.y; right += p.x; bottom += p.y;
320  return *this;
321  };
322 
327  {
328  left += p.width; top += p.height; right += p.width; bottom += p.height;
329  return *this;
330  };
331 
336  {
337  left += p.left; top += p.top; right += p.left; bottom += p.top;
338  return *this;
339  };
340 
344  Rectx<Type> &translate(Type x, Type y)
345  {
346  left += x; top += y; right += x; bottom += y;
347  return *this;
348  };
349 
354  {
355  right = left + size.width;
356  bottom = top + size.height;
357  return *this;
358  }
359 
366  {
367  Rectx<Type> result;
368  result.left = max(left, rect.left);
369  result.right = min(right, rect.right);
370  result.top = max(top, rect.top);
371  result.bottom = min(bottom, rect.bottom);
372  if (result.right < result.left)
373  result.left = result.right;
374  if (result.bottom < result.top)
375  result.top = result.bottom;
376 
377  *this = result;
378  return *this;
379  }
380 
387  {
388  Rectx<Type> result;
389  result.left = min(left, rect.left);
390  result.right = max(right, rect.right);
391  result.top = min(top, rect.top);
392  result.bottom = max(bottom, rect.bottom);
393  *this = result;
394  return *this;
395  }
396 
404  {
405  if (left > right)
406  right = left;
407 
408  if (top > bottom)
409  bottom = top;
410 
411  return *this;
412  }
413 
420  Rectx<Type> &apply_alignment(Origin origin, Type x, Type y)
421  {
422  Vec2<Type> offset = Vec2<Type>::calc_origin(origin, get_size());
423  offset.x -= x;
424  offset.y -= y;
425 
426  left += offset.x;
427  top += offset.y;
428  right += offset.x;
429  bottom += offset.y;
430  return *this;
431  }
432 
437  {
438  top = max(top, cr.top);
439  left = max(left, cr.left);
440  right = min(right, cr.right);
441  bottom = min(bottom, cr.bottom);
442  top = min(top, bottom);
443  left = min(left, right);
444  return *this;
445  }
446  };
447 
448  template<>
449  inline Rectx<int>::Rectx(const Rectx<float> &rect)
450  : left(static_cast<int> (floor(rect.left + 0.5f))),
451  top(static_cast<int> (floor(rect.top + 0.5f))),
452  right(static_cast<int> (floor(rect.right + 0.5f))),
453  bottom(static_cast<int> (floor(rect.bottom + 0.5f)))
454  {
455  }
456 
457  template<>
458  inline Rectx<int>::Rectx(const Rectx<double> &rect)
459  : left(static_cast<int> (floor(rect.left + 0.5))),
460  top(static_cast<int> (floor(rect.top + 0.5))),
461  right(static_cast<int> (floor(rect.right + 0.5))),
462  bottom(static_cast<int> (floor(rect.bottom + 0.5)))
463  {
464  }
465 
466  template<typename Type>
467  inline Rectx<Type>::Rectx(const Rectx<int> &rect)
468  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
469  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
470  {
471  }
472 
473  template<typename Type>
474  inline Rectx<Type>::Rectx(const Rectx<float> &rect)
475  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
476  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
477  {
478  }
479 
480  template<typename Type>
481  inline Rectx<Type>::Rectx(const Rectx<double> &rect)
482  : left(static_cast<Type> (rect.left)), top(static_cast<Type> (rect.top)),
483  right(static_cast<Type> (rect.right)), bottom(static_cast<Type> (rect.bottom))
484  {
485  }
486 
488  class Rect : public Rectx<int>
489  {
490  public:
491  Rect() : Rectx<int>() {}
492  Rect(const Sizex<int> &s) : Rectx<int>(s) {}
493  Rect(int new_left, int new_top, int new_right, int new_bottom) : Rectx<int>(new_left, new_top, new_right, new_bottom) {}
494  Rect(const Pointx<int> &p, const Sizex<int> &size) : Rectx<int>(p, size) {}
495  Rect(const Rectx<int> &rect) : Rectx<int>(rect) {}
496  Rect(const Rectx<float> &rect) : Rectx<int>(rect) {}
497  Rect(const Rectx<double> &rect) : Rectx<int>(rect) {}
498  Rect(int new_left, int new_top, const Sizex<int> &size) : Rectx<int>(new_left, new_top, size) {}
499  };
500 
502  class Rectf : public Rectx<float>
503  {
504  public:
505  Rectf() : Rectx<float>() {}
506  Rectf(const Sizex<int> &s) : Rectx<float>(s) {}
507  Rectf(const Sizex<float> &s) : Rectx<float>(s) {}
508  Rectf(float new_left, float new_top, float new_right, float new_bottom) : Rectx<float>(new_left, new_top, new_right, new_bottom) {}
509  Rectf(const Pointx<float> &p, const Sizex<float> &size) : Rectx<float>(p, size) {}
510  Rectf(const Rectx<int> &rect) : Rectx<float>(rect) {}
511  Rectf(const Rectx<float> &rect) : Rectx<float>(rect) {}
512  Rectf(const Rectx<double> &rect) : Rectx<float>(rect) {}
513  Rectf(float new_left, float new_top, const Sizex<float> &size) : Rectx<float>(new_left, new_top, size) {}
514  };
515 
517  class Rectd : public Rectx<double>
518  {
519  public:
520  Rectd() : Rectx<double>() {}
521  Rectd(const Sizex<int> &s) : Rectx<double>(s) {}
522  Rectd(const Sizex<float> &s) : Rectx<double>(s) {}
523  Rectd(const Sizex<double> &s) : Rectx<double>(s) {}
524  Rectd(double new_left, double new_top, double new_right, double new_bottom) : Rectx<double>(new_left, new_top, new_right, new_bottom) {}
525  Rectd(const Pointx<double> &p, const Sizex<double> &size) : Rectx<double>(p, size) {}
526  Rectd(const Rectx<int> &rect) : Rectx<double>(rect) {}
527  Rectd(const Rectx<float> &rect) : Rectx<double>(rect) {}
528  Rectd(const Rectx<double> &rect) : Rectx<double>(rect) {}
529  Rectd(double new_left, double new_top, const Sizex<double> &size) : Rectx<double>(new_left, new_top, size) {}
530  };
531 
532  inline Rect RectPS(int x, int y, int width, int height)
533  {
534  return Rect(x, y, x + width, y + height);
535  }
536 
537  inline Rectf RectfPS(float x, float y, float width, float height)
538  {
539  return Rectf(x, y, x + width, y + height);
540  }
541 
542  inline Rectd RectdPS(double x, double y, double width, double height)
543  {
544  return Rectd(x, y, x + width, y + height);
545  }
546 
548 }
Type get_height() const
Returns the height of the rectangle.
Definition: rect.h:145
Rect RectPS(int x, int y, int width, int height)
Definition: rect.h:532
Rectx(const Sizex< Type > &s)
Constructs an rectangle.
Definition: rect.h:61
Definition: clanapp.h:35
Rectf(const Rectx< int > &rect)
Definition: rect.h:510
2D (left,top,right,bottom) rectangle structure - Double
Definition: rect.h:517
Type bottom
Y2-coordinate (point outside the rectange)
Definition: rect.h:139
Rectd(const Rectx< float > &rect)
Definition: rect.h:527
Angle class.
Definition: angle.h:59
Rectx< Type > & apply_alignment(Origin origin, Type x, Type y)
Applies an origin and offset pair to this rectangle.
Definition: rect.h:420
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.
Rect(int new_left, int new_top, int new_right, int new_bottom)
Definition: rect.h:493
2D vector
Definition: line.h:46
Rectd(double new_left, double new_top, const Sizex< double > &size)
Definition: rect.h:529
Rect(const Rectx< double > &rect)
Definition: rect.h:497
Rectd(const Sizex< float > &s)
Definition: rect.h:522
Rectx< Type > & set_bottom_right(const Vec2< Type > &p)
Sets the bottom-right point of the rectangle.
Definition: rect.h:229
Pointx< Type > get_bottom_left() const
Returns the bottom-left point outside the rectangle.
Definition: rect.h:176
Rectx< Type > & translate(const Sizex< Type > &p)
Translate the rect.
Definition: rect.h:326
Pointx< Type > get_top_right() const
Returns the top-right point outside the rectangle.
Definition: rect.h:164
Rectx()
Constructs an rectangle.
Definition: rect.h:56
Origin
Alignment origins.
Definition: origin.h:38
Rectx< Type > operator*(const Type &s) const
Rect * operator.
Definition: rect.h:121
Rectf(const Rectx< double > &rect)
Definition: rect.h:512
Rectf(const Sizex< float > &s)
Definition: rect.h:507
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:284
Type get_width() const
Returns the width of the rectangle.
Definition: rect.h:142
Rect(const Sizex< int > &s)
Definition: rect.h:492
Rectf()
Definition: rect.h:505
Rectx< Type > get_rot_bounds(const Vec2< Type > &hotspot, const Angle &angle) const
Returns another Rectx containing a rotated version of this one.
A min(A a, B b)
Definition: cl_math.h:57
Rectx< Type > & set_size(const Sizex< Type > &size)
Sets the size of the rectangle, maintaining top/left position.
Definition: rect.h:353
bool operator!=(const Rectx< Type > &r) const
Rect != Rect operator.
Definition: rect.h:109
Rectx< Type > & shrink(const Type &shrink)
Shrink the rectangle.
Definition: rect.h:275
Rectx< Type > & operator*=(const Type &s)
Rect *= operator.
Definition: rect.h:115
Pointx< Type > get_bottom_right() const
Returns the bottom-right point outside the rectangle.
Definition: rect.h:170
Rectx< Type > & clip(const Rectx< Type > &cr)
Clip according to the specified clip rectangle.
Definition: rect.h:436
Rectx< Type > & expand(const Type &expand)
Expand the rectangle.
Definition: rect.h:305
Rectf(float new_left, float new_top, float new_right, float new_bottom)
Definition: rect.h:508
Rect(const Pointx< int > &p, const Sizex< int > &size)
Definition: rect.h:494
2D (left,top,right,bottom) rectangle structure - Integer
Definition: rect.h:488
Rectd(const Sizex< int > &s)
Definition: rect.h:521
bool contains(const Vec2< Type > &p) const
Returns true if the rectangle contains the point.
Definition: rect.h:151
Rect(const Rectx< int > &rect)
Definition: rect.h:495
Rectf RectfPS(float x, float y, float width, float height)
Definition: rect.h:537
2D (left,top,right,bottom) rectangle structure - Float
Definition: rect.h:502
Type y
Definition: vec2.h:81
Rectd(const Sizex< double > &s)
Definition: rect.h:523
Rect(const Rectx< float > &rect)
Definition: rect.h:496
Rectd(const Pointx< double > &p, const Sizex< double > &size)
Definition: rect.h:525
A max(A a, B b)
Definition: cl_math.h:58
Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
Constructs an rectangle.
Definition: rect.h:69
Rectf(float new_left, float new_top, const Sizex< float > &size)
Definition: rect.h:513
Rectf(const Sizex< int > &s)
Definition: rect.h:506
Rectf(const Pointx< float > &p, const Sizex< float > &size)
Definition: rect.h:509
bool operator==(const Rectx< Type > &r) const
Rect == Rect operator.
Definition: rect.h:103
Pointx< Type > get_center() const
Returns the center point of the rectangle.
Definition: rect.h:211
Rectx< Type > & normalize()
Normalize rectangle.
Definition: rect.h:403
Type top
Y1-coordinate (top point inside the rectangle)
Definition: rect.h:133
Rectx< Type > & set_height(Type height)
Sets the height of the rectangle.
Definition: rect.h:248
Rectx< Type > & set_width(Type width)
Sets the width of the rectangle.
Definition: rect.h:239
Rectx(const Pointx< Type > &p, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:76
Rectx< Type > & translate(const Vec2< Type > &p)
Translate the rect.
Definition: rect.h:317
Rectx< Type > & translate(const Rectx< Type > &p)
Translate the rect by another rect (only uses the left and top coords).
Definition: rect.h:335
Rectd RectdPS(double x, double y, double width, double height)
Definition: rect.h:542
Type right
X2-coordinate (point outside the rectangle)
Definition: rect.h:136
static Rectx< Type > ltrb(Type left, Type top, Type right, Type bottom)
Definition: rect.h:127
Sizex< Type > get_size() const
Returns the size of the rectangle.
Definition: rect.h:148
Type height
Size height.
Definition: size.h:77
bool is_overlapped(const Rectx< Type > &r) const
Returns true if rectangle passed is overlapping or inside this rectangle.
Definition: rect.h:182
Rectx< Type > & shrink(const Type &left_right, const Type &top_bottom)
Shrink the rectangle.
Definition: rect.h:266
Rectx< Type > & expand(const Type &left_and_right, const Type &top_and_bottom)
Expand the rectangle.
Definition: rect.h:293
Rectx< Type > & bounding_rect(const Rectx< Type > &rect)
Calculates the bounding rectangle of the rectangles.
Definition: rect.h:386
Rectx(Type new_left, Type new_top, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:84
static Rectx< Type > xywh(Type x, Type y, Type width, Type height)
Definition: rect.h:126
2D (x,y) point structure.
Definition: point.h:51
Rectd()
Definition: rect.h:520
Rect(int new_left, int new_top, const Sizex< int > &size)
Definition: rect.h:498
Rectx< Type > & overlap(const Rectx< Type > &rect)
Calculates the intersection of two rectangles.
Definition: rect.h:365
Rectd(const Rectx< double > &rect)
Definition: rect.h:528
Type x
Definition: vec2.h:80
Rectd(const Rectx< int > &rect)
Definition: rect.h:526
Rectf(const Rectx< float > &rect)
Definition: rect.h:511
Type left
X1-coordinate (left point inside the rectangle)
Definition: rect.h:130
Rect()
Definition: rect.h:491
Rectx< Type > & translate(Type x, Type y)
Translate the rect.
Definition: rect.h:344
Pointx< Type > get_top_left() const
Returns the top-left point inside the rectangle.
Definition: rect.h:158
Rectx< Type > & set_top_left(const Vec2< Type > &p)
Sets the top-left point of the rectangle.
Definition: rect.h:219
bool is_inside(const Rectx< Type > &r) const
Returns true if rectangle passed is inside this rectangle.
Definition: rect.h:188
2D (width,height) size structure.
Definition: size.h:54
Type width
Size width.
Definition: size.h:74
Rectd(double new_left, double new_top, double new_right, double new_bottom)
Definition: rect.h:524
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:257