rect.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2020 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<Type> &rect) = default;
91 
92  template<typename OtherType, typename std::enable_if_t<std::is_integral<Type>::value && !std::is_integral<OtherType>::value, int> = 0>
93  Rectx(const Rectx<OtherType>& copy) : left(static_cast<Type>(std::floor(copy.left + 0.5f))), top(static_cast<Type>(std::floor(copy.top + 0.5f))), right(static_cast<Type>(std::floor(copy.right + 0.5f))), bottom(static_cast<Type>(std::floor(copy.bottom + 0.5f))) {}
94 
95  template<typename OtherType, typename std::enable_if_t<!std::is_integral<Type>::value || std::is_integral<OtherType>::value, int> = 0>
96  Rectx(const Rectx<OtherType>& copy) : left(static_cast<Type>(copy.left)), top(static_cast<Type>(copy.top)), right(static_cast<Type>(copy.right)), bottom(static_cast<Type>(copy.bottom)) {}
97 
99  bool operator==(const Rectx<Type> &r) const
100  {
101  return (left == r.left && top == r.top && right == r.right && bottom == r.bottom);
102  }
103 
105  bool operator!=(const Rectx<Type> &r) const
106  {
107  return (left != r.left || top != r.top || right != r.right || bottom != r.bottom);
108  }
109 
111  Rectx<Type> &operator*=(const Type &s)
112  {
113  left *= s; top *= s; right *= s; bottom *= s; return *this;
114  }
115 
117  Rectx<Type> operator*(const Type &s) const
118  {
119  return Rectx<Type>(left*s, top*s, right*s, bottom *s);
120  }
121 
122  static Rectx<Type> xywh(Type x, Type y, Type width, Type height) { return Rectx<Type>(x, y, x + width, y + height); }
123  static Rectx<Type> ltrb(Type left, Type top, Type right, Type bottom) { return Rectx<Type>(left, top, right, bottom); }
124 
126  Type left;
127 
129  Type top;
130 
132  Type right;
133 
135  Type bottom;
136 
138  Type get_width() const { return right - left; }
139 
141  Type get_height() const { return bottom - top; }
142 
144  Sizex<Type> get_size() const { return Sizex<Type>(right - left, bottom - top); }
145 
147  bool contains(const Vec2<Type> &p) const
148  {
149  return (p.x >= left && p.x < right)
150  && (p.y >= top && p.y < bottom);
151  }
152 
155  {
156  return Pointx<Type>(left, top);
157  }
158 
161  {
162  return Pointx<Type>(right, top);
163  }
164 
167  {
168  return Pointx<Type>(right, bottom);
169  }
170 
173  {
174  return Pointx<Type>(left, bottom);
175  }
176 
178  bool is_overlapped(const Rectx<Type> &r) const
179  {
180  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
181  }
182 
184  bool is_inside(const Rectx<Type> &r) const
185  {
186  return ((left <= r.left)
187  && (top <= r.top)
188  && (right >= r.right)
189  && (bottom >= r.bottom));
190  }
191 
196  Rectx<Type> get_rot_bounds(const Vec2<Type> &hotspot, const Angle &angle) const;
197 
204  Rectx<Type> get_rot_bounds(Origin origin, Type x, Type y, const Angle &angle) const;
205 
208  {
209  return Pointx<Type>((left + right) / 2, (top + bottom) / 2);
210  }
211 
216  {
217  left = p.x;
218  top = p.y;
219  return *this;
220  }
221 
226  {
227  right = p.x;
228  bottom = p.y;
229  return *this;
230  }
231 
235  Rectx<Type> &set_width(Type width)
236  {
237  right = left + width;
238  return *this;
239  }
240 
244  Rectx<Type> &set_height(Type height)
245  {
246  bottom = top + height;
247  return *this;
248  }
249 
253  Rectx<Type> &shrink(const Type &new_left, const Type &new_top, const Type &new_right, const Type &new_bottom)
254  {
255  left += new_left; top += new_top; right -= new_right; bottom -= new_bottom;
256  return *this;
257  };
258 
262  Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
263  {
264  left += left_right; top += top_bottom; right -= left_right; bottom -= top_bottom;
265  return *this;
266  };
267 
271  Rectx<Type> &shrink(const Type &shrink)
272  {
273  left += shrink; top += shrink; right -= shrink; bottom -= shrink;
274  return *this;
275  };
276 
280  Rectx<Type> &expand(const Type &expand_left, const Type &expand_top, const Type &expand_right, const Type &expand_bottom)
281  {
282  left -= expand_left; top -= expand_top; right += expand_right; bottom += expand_bottom;
283  return *this;
284  };
285 
289  Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
290  {
291  left -= left_and_right;
292  right += left_and_right;
293  top -= top_and_bottom;
294  bottom += top_and_bottom;
295  return *this;
296  };
297 
301  Rectx<Type> &expand(const Type &expand)
302  {
303  left -= expand;
304  right += expand;
305  top -= expand;
306  bottom += expand;
307  return *this;
308  };
309 
314  {
315  left += p.x; top += p.y; right += p.x; bottom += p.y;
316  return *this;
317  };
318 
323  {
324  left += p.width; top += p.height; right += p.width; bottom += p.height;
325  return *this;
326  };
327 
332  {
333  left += p.left; top += p.top; right += p.left; bottom += p.top;
334  return *this;
335  };
336 
340  Rectx<Type> &translate(Type x, Type y)
341  {
342  left += x; top += y; right += x; bottom += y;
343  return *this;
344  };
345 
350  {
351  right = left + size.width;
352  bottom = top + size.height;
353  return *this;
354  }
355 
362  {
363  Rectx<Type> result;
364  result.left = max(left, rect.left);
365  result.right = min(right, rect.right);
366  result.top = max(top, rect.top);
367  result.bottom = min(bottom, rect.bottom);
368  if (result.right < result.left)
369  result.left = result.right;
370  if (result.bottom < result.top)
371  result.top = result.bottom;
372 
373  *this = result;
374  return *this;
375  }
376 
383  {
384  Rectx<Type> result;
385  result.left = min(left, rect.left);
386  result.right = max(right, rect.right);
387  result.top = min(top, rect.top);
388  result.bottom = max(bottom, rect.bottom);
389  *this = result;
390  return *this;
391  }
392 
400  {
401  if (left > right)
402  right = left;
403 
404  if (top > bottom)
405  bottom = top;
406 
407  return *this;
408  }
409 
416  Rectx<Type> &apply_alignment(Origin origin, Type x, Type y)
417  {
418  Vec2<Type> offset = Vec2<Type>::calc_origin(origin, get_size());
419  offset.x -= x;
420  offset.y -= y;
421 
422  left += offset.x;
423  top += offset.y;
424  right += offset.x;
425  bottom += offset.y;
426  return *this;
427  }
428 
433  {
434  top = max(top, cr.top);
435  left = max(left, cr.left);
436  right = min(right, cr.right);
437  bottom = min(bottom, cr.bottom);
438  top = min(top, bottom);
439  left = min(left, right);
440  return *this;
441  }
442  };
443 
445  class Rect : public Rectx<int>
446  {
447  public:
448  Rect() : Rectx<int>() {}
449  Rect(const Sizex<int>& s) : Rectx<int>(s) {}
450  Rect(int new_left, int new_top, int new_right, int new_bottom) : Rectx<int>(new_left, new_top, new_right, new_bottom) {}
451  Rect(const Pointx<int>& p, const Sizex<int>& size) : Rectx<int>(p, size) {}
452  Rect(const Rectx<int>& rect) : Rectx<int>(rect) {}
453  Rect(const Rectx<float>& rect) : Rectx<int>(rect) {}
454  Rect(const Rectx<double>& rect) : Rectx<int>(rect) {}
455  Rect(int new_left, int new_top, const Sizex<int>& size) : Rectx<int>(new_left, new_top, size) {}
456  };
457 
459  class Rectf : public Rectx<float>
460  {
461  public:
462  Rectf() : Rectx<float>() {}
463  Rectf(const Sizex<int>& s) : Rectx<float>(s) {}
464  Rectf(const Sizex<float>& s) : Rectx<float>(s) {}
465  Rectf(float new_left, float new_top, float new_right, float new_bottom) : Rectx<float>(new_left, new_top, new_right, new_bottom) {}
466  Rectf(const Pointx<float>& p, const Sizex<float>& size) : Rectx<float>(p, size) {}
467  Rectf(const Rectx<int>& rect) : Rectx<float>(rect) {}
468  Rectf(const Rectx<float>& rect) : Rectx<float>(rect) {}
469  Rectf(const Rectx<double>& rect) : Rectx<float>(rect) {}
470  Rectf(float new_left, float new_top, const Sizex<float>& size) : Rectx<float>(new_left, new_top, size) {}
471  };
472 
474  class Rectd : public Rectx<double>
475  {
476  public:
477  Rectd() : Rectx<double>() {}
478  Rectd(const Sizex<int>& s) : Rectx<double>(s) {}
479  Rectd(const Sizex<float>& s) : Rectx<double>(s) {}
480  Rectd(const Sizex<double>& s) : Rectx<double>(s) {}
481  Rectd(double new_left, double new_top, double new_right, double new_bottom) : Rectx<double>(new_left, new_top, new_right, new_bottom) {}
482  Rectd(const Pointx<double>& p, const Sizex<double>& size) : Rectx<double>(p, size) {}
483  Rectd(const Rectx<int>& rect) : Rectx<double>(rect) {}
484  Rectd(const Rectx<float>& rect) : Rectx<double>(rect) {}
485  Rectd(const Rectx<double>& rect) : Rectx<double>(rect) {}
486  Rectd(double new_left, double new_top, const Sizex<double>& size) : Rectx<double>(new_left, new_top, size) {}
487  };
488 
489  inline Rect RectPS(int x, int y, int width, int height)
490  {
491  return Rect(x, y, x + width, y + height);
492  }
493 
494  inline Rectf RectfPS(float x, float y, float width, float height)
495  {
496  return Rectf(x, y, x + width, y + height);
497  }
498 
499  inline Rectd RectdPS(double x, double y, double width, double height)
500  {
501  return Rectd(x, y, x + width, y + height);
502  }
503 
505 }
Rectx(const Pointx< Type > &p, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:76
bool is_overlapped(const Rectx< Type > &r) const
Returns true if rectangle passed is overlapping or inside this rectangle.
Definition: rect.h:178
Rect RectPS(int x, int y, int width, int height)
Definition: rect.h:489
Definition: clanapp.h:35
Rectf(const Rectx< int > &rect)
Definition: rect.h:467
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.
2D (left,top,right,bottom) rectangle structure - Double
Definition: rect.h:474
Pointx< Type > get_center() const
Returns the center point of the rectangle.
Definition: rect.h:207
Rectd(const Rectx< float > &rect)
Definition: rect.h:484
Angle class.
Definition: angle.h:59
Type top
Y1-coordinate (top point inside the rectangle)
Definition: rect.h:129
Sizex< Type > get_size() const
Returns the size of the rectangle.
Definition: rect.h:144
Rect(int new_left, int new_top, int new_right, int new_bottom)
Definition: rect.h:450
Type get_height() const
Returns the height of the rectangle.
Definition: rect.h:141
Rectd(double new_left, double new_top, const Sizex< double > &size)
Definition: rect.h:486
Rect(const Rectx< double > &rect)
Definition: rect.h:454
Rectd(const Sizex< float > &s)
Definition: rect.h:479
Rectx< Type > & expand(const Type &expand)
Expand the rectangle.
Definition: rect.h:301
Rectx< Type > & translate(const Sizex< Type > &p)
Translate the rect.
Definition: rect.h:322
Rectx< Type > & overlap(const Rectx< Type > &rect)
Calculates the intersection of two rectangles.
Definition: rect.h:361
Pointx< Type > get_top_right() const
Returns the top-right point outside the rectangle.
Definition: rect.h:160
Origin
Alignment origins.
Definition: origin.h:38
Rectf(const Rectx< double > &rect)
Definition: rect.h:469
Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
Constructs an rectangle.
Definition: rect.h:69
Rectf(const Sizex< float > &s)
Definition: rect.h:464
Rectx< Type > & set_bottom_right(const Vec2< Type > &p)
Sets the bottom-right point of the rectangle.
Definition: rect.h:225
Rectx< Type > operator*(const Type &s) const
Rect * operator.
Definition: rect.h:117
STL namespace.
Rect(const Sizex< int > &s)
Definition: rect.h:449
Rectf()
Definition: rect.h:462
Rectx< Type > & expand(const Type &left_and_right, const Type &top_and_bottom)
Expand the rectangle.
Definition: rect.h:289
Rectx< Type > & set_width(Type width)
Sets the width of the rectangle.
Definition: rect.h:235
Rectx(Type new_left, Type new_top, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:84
Pointx< Type > get_top_left() const
Returns the top-left point inside the rectangle.
Definition: rect.h:154
Type right
X2-coordinate (point outside the rectangle)
Definition: rect.h:132
Pointx< Type > get_bottom_right() const
Returns the bottom-right point outside the rectangle.
Definition: rect.h:166
bool operator!=(const Rectx< Type > &r) const
Rect != Rect operator.
Definition: rect.h:105
Rectf(float new_left, float new_top, float new_right, float new_bottom)
Definition: rect.h:465
Rectx< Type > & normalize()
Normalize rectangle.
Definition: rect.h:399
Type get_width() const
Returns the width of the rectangle.
Definition: rect.h:138
Rect(const Pointx< int > &p, const Sizex< int > &size)
Definition: rect.h:451
Rectx< Type > & shrink(const Type &shrink)
Shrink the rectangle.
Definition: rect.h:271
2D (left,top,right,bottom) rectangle structure - Integer
Definition: rect.h:445
static Rectx< Type > ltrb(Type left, Type top, Type right, Type bottom)
Definition: rect.h:123
Rectd(const Sizex< int > &s)
Definition: rect.h:478
Rect(const Rectx< int > &rect)
Definition: rect.h:452
Type bottom
Y2-coordinate (point outside the rectange)
Definition: rect.h:135
Rectx< Type > & set_size(const Sizex< Type > &size)
Sets the size of the rectangle, maintaining top/left position.
Definition: rect.h:349
Rectf RectfPS(float x, float y, float width, float height)
Definition: rect.h:494
2D (left,top,right,bottom) rectangle structure - Float
Definition: rect.h:459
Rectd(const Sizex< double > &s)
Definition: rect.h:480
Rectx< Type > & set_height(Type height)
Sets the height of the rectangle.
Definition: rect.h:244
Rect(const Rectx< float > &rect)
Definition: rect.h:453
Rectd(const Pointx< double > &p, const Sizex< double > &size)
Definition: rect.h:482
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:280
2D vector
Definition: line.h:46
static Rectx< Type > xywh(Type x, Type y, Type width, Type height)
Definition: rect.h:122
Rectf(float new_left, float new_top, const Sizex< float > &size)
Definition: rect.h:470
Type y
Definition: vec2.h:81
Rectf(const Sizex< int > &s)
Definition: rect.h:463
2D (left,top,right,bottom) rectangle structure.
Definition: line.h:43
Rectf(const Pointx< float > &p, const Sizex< float > &size)
Definition: rect.h:466
Rectx< Type > & shrink(const Type &left_right, const Type &top_bottom)
Shrink the rectangle.
Definition: rect.h:262
Rectx< Type > & apply_alignment(Origin origin, Type x, Type y)
Applies an origin and offset pair to this rectangle.
Definition: rect.h:416
Rectx< Type > & set_top_left(const Vec2< Type > &p)
Sets the top-left point of the rectangle.
Definition: rect.h:215
Rectx< Type > & translate(const Vec2< Type > &p)
Translate the rect.
Definition: rect.h:313
Rectd RectdPS(double x, double y, double width, double height)
Definition: rect.h:499
Rectx< Type > & operator*=(const Type &s)
Rect *= operator.
Definition: rect.h:111
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:253
Type x
Definition: vec2.h:80
Type height
Size height.
Definition: size.h:82
Type left
X1-coordinate (left point inside the rectangle)
Definition: rect.h:126
Rectx(const Sizex< Type > &s)
Constructs an rectangle.
Definition: rect.h:61
Rectx< Type > & clip(const Rectx< Type > &cr)
Clip according to the specified clip rectangle.
Definition: rect.h:432
Rectx< Type > & bounding_rect(const Rectx< Type > &rect)
Calculates the bounding rectangle of the rectangles.
Definition: rect.h:382
2D (x,y) point structure.
Definition: point.h:51
Rectd()
Definition: rect.h:477
Pointx< Type > get_bottom_left() const
Returns the bottom-left point outside the rectangle.
Definition: rect.h:172
Rect(int new_left, int new_top, const Sizex< int > &size)
Definition: rect.h:455
Rectx< Type > & translate(Type x, Type y)
Translate the rect.
Definition: rect.h:340
Rectd(const Rectx< double > &rect)
Definition: rect.h:485
Rectd(const Rectx< int > &rect)
Definition: rect.h:483
Rectf(const Rectx< float > &rect)
Definition: rect.h:468
bool is_inside(const Rectx< Type > &r) const
Returns true if rectangle passed is inside this rectangle.
Definition: rect.h:184
Rect()
Definition: rect.h:448
Rectx()
Constructs an rectangle.
Definition: rect.h:56
bool operator==(const Rectx< Type > &r) const
Rect == Rect operator.
Definition: rect.h:99
Rectx(const Rectx< OtherType > &copy)
Definition: rect.h:93
2D (width,height) size structure.
Definition: size.h:54
bool contains(const Vec2< Type > &p) const
Returns true if the rectangle contains the point.
Definition: rect.h:147
Rectx< Type > get_rot_bounds(const Vec2< Type > &hotspot, const Angle &angle) const
Returns another Rectx<Type> containing a rotated version of this one.
Rectx< Type > & translate(const Rectx< Type > &p)
Translate the rect by another rect (only uses the left and top coords).
Definition: rect.h:331
Type width
Size width.
Definition: size.h:79
Rectd(double new_left, double new_top, double new_right, double new_bottom)
Definition: rect.h:481