rect.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2015 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 
33 #pragma once
34 
35 #include "vec2.h"
36 #include "size.h"
37 #include "point.h"
38 #include "origin.h"
39 #include "cl_math.h"
40 
41 namespace clan
42 {
45 
50 template<typename Type>
51 class Rectx
52 {
55 public:
59  Rectx() : left(0), top(0), right(0), bottom(0) {}
60 
64  Rectx(const Sizex<Type> &s) : left(0), top(0), right(s.width), bottom(s.height) {}
65 
72  Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
73  : left(new_left), top(new_top), right(new_right), bottom(new_bottom) {}
74 
79  Rectx(const Pointx<Type> &p, const Sizex<Type> &size)
80  : left(p.x), top(p.y), right(p.x + size.width), bottom(p.y + size.height) {}
81 
87  Rectx(Type new_left, Type new_top, const Sizex<Type> &size)
88  : left(new_left), top(new_top), right(new_left + size.width), bottom(new_top + size.height) {}
89 
93  Rectx(const Rectx<int> &rect);
94 
98  Rectx(const Rectx<float> &rect);
99 
103  Rectx(const Rectx<double> &rect);
104 
106  bool operator==(const Rectx<Type> &r) const
107  { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
108 
110  bool operator!=(const Rectx<Type> &r) const
111  { return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); }
112 
113  static Rectx<Type> xywh(Type x, Type y, Type width, Type height) { return Rectx<Type>(x,y,x+width, y+height); }
114  static Rectx<Type> ltrb(Type left, Type top, Type right, Type bottom) { return Rectx<Type>(left, top, right, bottom); }
115 
116 
120 public:
122  Type left;
123 
125  Type top;
126 
128  Type right;
129 
131  Type bottom;
132 
134  Type get_width() const { return right - left; }
135 
137  Type get_height() const { return bottom - top; }
138 
140  Sizex<Type> get_size() const { return Sizex<Type>(right - left, bottom - top); }
141 
143  bool contains(const Vec2<Type> &p) const
144  {
145  return (p.x >= left && p.x < right)
146  && (p.y >= top && p.y < bottom);
147  }
148 
151  {
152  return Pointx<Type>(left, top);
153  }
154 
157  {
158  return Pointx<Type>(right, top);
159  }
160 
163  {
164  return Pointx<Type>(right, bottom);
165  }
166 
169  {
170  return Pointx<Type>(left, bottom);
171  }
172 
174  bool is_overlapped(const Rectx<Type> &r) const
175  {
176  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
177  }
178 
180  bool is_inside(const Rectx<Type> &r) const
181  {
182  return ((left <= r.left)
183  && (top <= r.top)
184  && (right >= r.right)
185  && (bottom >= r.bottom));
186  }
187 
192  Rectx<Type> get_rot_bounds(const Vec2<Type> &hotspot, const Angle &angle) const;
193 
200  Rectx<Type> get_rot_bounds(Origin origin, Type x, Type y, const Angle &angle) const;
201 
204  {
205  return Pointx<Type>( (left + right)/2, ( top + bottom)/2 );
206  }
207 
211 public:
216  {
217  left = p.x;
218  top = p.y;
219  return *this;
220  }
221 
225  Rectx<Type> &set_width(Type width)
226  {
227  right = left + width;
228  return *this;
229  }
230 
234  Rectx<Type> &set_height(Type height)
235  {
236  bottom = top + height;
237  return *this;
238  }
239 
243  Rectx<Type> &shrink(const Type &new_left, const Type &new_top, const Type &new_right, const Type &new_bottom)
244  {
245  left += new_left; top += new_top; right -= new_right; bottom -= new_bottom;
246  return *this;
247  };
248 
252  Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
253  {
254  left += left_right; top += top_bottom; right -= left_right; bottom -= top_bottom;
255  return *this;
256  };
257 
261  Rectx<Type> &shrink(const Type &shrink)
262  {
263  left += shrink; top += shrink; right -= shrink; bottom -= shrink;
264  return *this;
265  };
266 
270  Rectx<Type> &expand(const Type &expand_left, const Type &expand_top, const Type &expand_right, const Type &expand_bottom)
271  {
272  left -= expand_left; top -= expand_top; right += expand_right; bottom += expand_bottom;
273  return *this;
274  };
275 
279  Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
280  {
281  left -= left_and_right;
282  right += left_and_right;
283  top -= top_and_bottom;
284  bottom += top_and_bottom;
285  return *this;
286  };
287 
291  Rectx<Type> &expand(const Type &expand)
292  {
293  left -= expand;
294  right += expand;
295  top -= expand;
296  bottom += expand;
297  return *this;
298  };
299 
304  {
305  left += p.x; top += p.y; right += p.x; bottom += p.y;
306  return *this;
307  };
308 
313  {
314  left += p.width; top += p.height; right += p.width; bottom += p.height;
315  return *this;
316  };
317 
322  {
323  left += p.left; top += p.top; right += p.left; bottom += p.top;
324  return *this;
325  };
326 
330  Rectx<Type> &translate(Type x, Type y)
331  {
332  left += x; top += y; right += x; bottom += y;
333  return *this;
334  };
335 
340  {
341  right = left + size.width;
342  bottom = top + size.height;
343  return *this;
344  }
345 
352  {
353  Rectx<Type> result;
354  result.left = max(left, rect.left);
355  result.right = min(right, rect.right);
356  result.top = max(top, rect.top);
357  result.bottom = min(bottom, rect.bottom);
358  if (result.right < result.left)
359  result.left = result.right;
360  if (result.bottom < result.top)
361  result.top = result.bottom;
362 
363  *this = result;
364  return *this;
365  }
366 
373  {
374  Rectx<Type> result;
375  result.left = min(left, rect.left);
376  result.right = max(right, rect.right);
377  result.top = min(top, rect.top);
378  result.bottom = max(bottom, rect.bottom);
379  *this = result;
380  return *this;
381  }
382 
390  {
391  if (left > right)
392  right = left;
393 
394  if (top > bottom)
395  bottom = top;
396 
397  return *this;
398  }
399 
406  Rectx<Type> &apply_alignment(Origin origin, Type x, Type y)
407  {
408  Vec2<Type> offset = Vec2<Type>::calc_origin(origin, get_size());
409  offset.x -= x;
410  offset.y -= y;
411 
412  left += offset.x;
413  top += offset.y;
414  right += offset.x;
415  bottom += offset.y;
416  return *this;
417  }
418 
423  {
424  top = max(top, cr.top);
425  left = max(left, cr.left);
426  right = min(right, cr.right);
427  bottom = min(bottom, cr.bottom);
428  top = min(top, bottom);
429  left = min(left, right);
430  return *this;
431  }
433 };
434 
435 template<>
436 inline Rectx<int>::Rectx(const Rectx<float> &rect)
437  : left( static_cast<int> (floor(rect.left + 0.5f)) ),
438  top( static_cast<int> (floor(rect.top + 0.5f)) ),
439  right( static_cast<int> (floor(rect.right + 0.5f)) ),
440  bottom( static_cast<int> (floor(rect.bottom+ 0.5f)) )
441  {}
442 
443 template<>
444 inline Rectx<int>::Rectx(const Rectx<double> &rect)
445  : left( static_cast<int> (floor(rect.left + 0.5)) ),
446  top( static_cast<int> (floor(rect.top + 0.5)) ),
447  right( static_cast<int> (floor(rect.right + 0.5)) ),
448  bottom( static_cast<int> (floor(rect.bottom+ 0.5)) )
449  {}
450 
451 template<typename Type>
452 inline Rectx<Type>::Rectx(const Rectx<int> &rect)
453  : left( static_cast<Type> (rect.left) ), top( static_cast<Type> (rect.top) ),
454  right( static_cast<Type> (rect.right) ), bottom( static_cast<Type> (rect.bottom) )
455  {}
456 
457 template<typename Type>
458 inline Rectx<Type>::Rectx(const Rectx<float> &rect)
459  : left( static_cast<Type> (rect.left) ), top( static_cast<Type> (rect.top) ),
460  right( static_cast<Type> (rect.right) ), bottom( static_cast<Type> (rect.bottom) )
461  {}
462 
463 template<typename Type>
465  : left( static_cast<Type> (rect.left) ), top( static_cast<Type> (rect.top) ),
466  right( static_cast<Type> (rect.right) ), bottom( static_cast<Type> (rect.bottom) )
467  {}
468 
470 class Rect : public Rectx<int>
471 {
472 public:
473  Rect() : Rectx<int>() {}
474  Rect(const Sizex<int> &s) : Rectx<int>(s) {}
475  Rect(int new_left, int new_top, int new_right, int new_bottom) : Rectx<int>(new_left, new_top, new_right, new_bottom) {}
476  Rect(const Pointx<int> &p, const Sizex<int> &size) : Rectx<int>(p, size) {}
477  Rect(const Rectx<int> &rect) : Rectx<int>(rect) {}
478  Rect(const Rectx<float> &rect) : Rectx<int>(rect) {}
479  Rect(const Rectx<double> &rect) : Rectx<int>(rect) {}
480  Rect(int new_left, int new_top, const Sizex<int> &size) : Rectx<int>(new_left, new_top, size) {}
481 };
482 
484 class Rectf : public Rectx<float>
485 {
486 public:
487  Rectf() : Rectx<float>() {}
488  Rectf(const Sizex<int> &s) : Rectx<float>(s) {}
489  Rectf(const Sizex<float> &s) : Rectx<float>(s) {}
490  Rectf(float new_left, float new_top, float new_right, float new_bottom) : Rectx<float>(new_left, new_top, new_right, new_bottom) {}
491  Rectf(const Pointx<float> &p, const Sizex<float> &size) : Rectx<float>(p, size) {}
492  Rectf(const Rectx<int> &rect) : Rectx<float>(rect) {}
493  Rectf(const Rectx<float> &rect) : Rectx<float>(rect) {}
494  Rectf(const Rectx<double> &rect) : Rectx<float>(rect) {}
495  Rectf(float new_left, float new_top, const Sizex<float> &size) : Rectx<float>(new_left, new_top, size) {}
496 };
497 
499 class Rectd : public Rectx<double>
500 {
501 public:
502  Rectd() : Rectx<double>() {}
503  Rectd(const Sizex<int> &s) : Rectx<double>(s) {}
504  Rectd(const Sizex<float> &s) : Rectx<double>(s) {}
505  Rectd(const Sizex<double> &s) : Rectx<double>(s) {}
506  Rectd(double new_left, double new_top, double new_right, double new_bottom) : Rectx<double>(new_left, new_top, new_right, new_bottom) {}
507  Rectd(const Pointx<double> &p, const Sizex<double> &size) : Rectx<double>(p, size) {}
508  Rectd(const Rectx<int> &rect) : Rectx<double>(rect) {}
509  Rectd(const Rectx<float> &rect) : Rectx<double>(rect) {}
510  Rectd(const Rectx<double> &rect) : Rectx<double>(rect) {}
511  Rectd(double new_left, double new_top, const Sizex<double> &size) : Rectx<double>(new_left, new_top, size) {}
512 };
513 
514 inline Rect RectPS(int x, int y, int width, int height)
515 {
516  return Rect(x, y, x+width, y+height);
517 }
518 
519 inline Rectf RectfPS(float x, float y, float width, float height)
520 {
521  return Rectf(x, y, x+width, y+height);
522 }
523 
524 inline Rectd RectdPS(double x, double y, double width, double height)
525 {
526  return Rectd(x, y, x+width, y+height);
527 }
528 
529 }
530 
bool contains(const Vec2< Type > &p) const
Returns true if the rectangle contains the point.
Definition: rect.h:143
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(const Pointx< Type > &p, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:79
Rectd(const Rectx< double > &rect)
Definition: rect.h:510
Rectd(const Sizex< int > &s)
Definition: rect.h:503
Rectx< Type > & shrink(const Type &left_right, const Type &top_bottom)
Shrink the rectangle.
Definition: rect.h:252
Rectx< Type > & expand(const Type &expand)
Expand the rectangle.
Definition: rect.h:291
Rectx< Type > & clip(const Rectx< Type > &cr)
Clip according to the specified clip rectangle.
Definition: rect.h:422
Type get_width() const
Returns the width of the rectangle.
Definition: rect.h:134
Sizex< Type > get_size() const
Returns the size of the rectangle.
Definition: rect.h:140
Type y
Definition: vec2.h:81
Rectd()
Definition: rect.h:502
Rectx(const Rectx< double > &rect)
Constructs an rectangle.
Definition: rect.h:464
Rectx< Type > & translate(const Rectx< Type > &p)
Translate the rect by another rect (only uses the left and top coords).
Definition: rect.h:321
Rectx< Type > & translate(Type x, Type y)
Translate the rect.
Definition: rect.h:330
Rectx< Type > & apply_alignment(Origin origin, Type x, Type y)
Applies an origin and offset pair to this rectangle.
Definition: rect.h:406
Rectf(const Sizex< int > &s)
Definition: rect.h:488
Rectd(const Rectx< int > &rect)
Definition: rect.h:508
Rectf(float new_left, float new_top, const Sizex< float > &size)
Definition: rect.h:495
bool is_inside(const Rectx< Type > &r) const
Returns true if rectangle passed is inside this rectangle.
Definition: rect.h:180
Rectx()
Constructs an rectangle.
Definition: rect.h:59
2D (left,top,right,bottom) rectangle structure - Integer
Definition: rect.h:471
2D (x,y) point structure.
Definition: point.h:53
Pointx< Type > get_bottom_left() const
Returns the bottom-left point outside the rectangle.
Definition: rect.h:168
Rectx(const Rectx< float > &rect)
Constructs an rectangle.
Definition: rect.h:458
Rect(const Rectx< float > &rect)
Definition: rect.h:478
Rectx(Type new_left, Type new_top, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:87
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:243
Rectx< Type > & set_width(Type width)
Sets the width of the rectangle.
Definition: rect.h:225
Rectx< Type > & translate(const Sizex< Type > &p)
Translate the rect.
Definition: rect.h:312
bool is_overlapped(const Rectx< Type > &r) const
Returns true if rectangle passed is overlapping or inside this rectangle.
Definition: rect.h:174
Rect(int new_left, int new_top, const Sizex< int > &size)
Definition: rect.h:480
Rectd(double new_left, double new_top, const Sizex< double > &size)
Definition: rect.h:511
2D (left,top,right,bottom) rectangle structure - Float
Definition: rect.h:485
Origin
Alignment origins.
Definition: origin.h:41
Rectx< Type > & set_size(const Sizex< Type > &size)
Sets the size of the rectangle, maintaining top/left position.
Definition: rect.h:339
Type x
Definition: vec2.h:80
Rectx(const Sizex< Type > &s)
Constructs an rectangle.
Definition: rect.h:64
Rect()
Definition: rect.h:473
Rectd(const Pointx< double > &p, const Sizex< double > &size)
Definition: rect.h:507
Rectf(const Rectx< int > &rect)
Definition: rect.h:492
Rect(const Rectx< double > &rect)
Definition: rect.h:479
Type top
Y1-coordinate (top point inside the rectangle)
Definition: rect.h:125
bool operator!=(const Rectx< Type > &r) const
Rect != Rect operator.
Definition: rect.h:110
Angle class.
Definition: angle.h:63
Rectd RectdPS(double x, double y, double width, double height)
Definition: rect.h:524
Rectx< Type > & overlap(const Rectx< Type > &rect)
Calculates the intersection of two rectangles.
Definition: rect.h:351
2D vector
Definition: line.h:48
Rectx< Type > & bounding_rect(const Rectx< Type > &rect)
Calculates the bounding rectangle of the rectangles.
Definition: rect.h:372
Rect(const Sizex< int > &s)
Definition: rect.h:474
Pointx< Type > get_center() const
Returns the center point of the rectangle.
Definition: rect.h:203
Rectf(const Pointx< float > &p, const Sizex< float > &size)
Definition: rect.h:491
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:270
Type right
X2-coordinate (point outside the rectangle)
Definition: rect.h:128
Pointx< Type > get_bottom_right() const
Returns the bottom-right point outside the rectangle.
Definition: rect.h:162
Rectx< Type > & expand(const Type &left_and_right, const Type &top_and_bottom)
Expand the rectangle.
Definition: rect.h:279
Pointx< Type > get_top_left() const
Returns the top-left point inside the rectangle.
Definition: rect.h:150
Rectd(const Rectx< float > &rect)
Definition: rect.h:509
Type bottom
Y2-coordinate (point outside the rectange)
Definition: rect.h:131
Rectf(const Rectx< double > &rect)
Definition: rect.h:494
Definition: clanapp.h:36
Type get_height() const
Returns the height of the rectangle.
Definition: rect.h:137
static Rectx< Type > xywh(Type x, Type y, Type width, Type height)
Definition: rect.h:113
Rectx< Type > & set_height(Type height)
Sets the height of the rectangle.
Definition: rect.h:234
static Rectx< Type > ltrb(Type left, Type top, Type right, Type bottom)
Definition: rect.h:114
Rectx< Type > & normalize()
Normalize rectangle.
Definition: rect.h:389
Rectf(float new_left, float new_top, float new_right, float new_bottom)
Definition: rect.h:490
2D (left,top,right,bottom) rectangle structure - Double
Definition: rect.h:500
Rect(const Rectx< int > &rect)
Definition: rect.h:477
Rectx< Type > get_rot_bounds(const Vec2< Type > &hotspot, const Angle &angle) const
Returns another Rectx<Type> containing a rotated version of this one.
Rect RectPS(int x, int y, int width, int height)
Definition: rect.h:514
Rectf()
Definition: rect.h:487
Type width
Size width.
Definition: size.h:82
A max(A a, B b)
Definition: cl_math.h:59
Rectx(const Rectx< int > &rect)
Constructs an rectangle.
Definition: rect.h:452
Rectf RectfPS(float x, float y, float width, float height)
Definition: rect.h:519
Rectf(const Sizex< float > &s)
Definition: rect.h:489
Type height
Size height.
Definition: size.h:85
bool operator==(const Rectx< Type > &r) const
Rect == Rect operator.
Definition: rect.h:106
Rectx< Type > & shrink(const Type &shrink)
Shrink the rectangle.
Definition: rect.h:261
Rectd(const Sizex< double > &s)
Definition: rect.h:505
Rectx< Type > get_rot_bounds(Origin origin, Type x, Type y, const Angle &angle) const
Returns another Rectx<Type> containing a rotated version of this one.
Rect(const Pointx< int > &p, const Sizex< int > &size)
Definition: rect.h:476
Type left
X1-coordinate (left point inside the rectangle)
Definition: rect.h:122
2D (width,height) size structure.
Definition: size.h:55
Rectx< Type > & translate(const Vec2< Type > &p)
Translate the rect.
Definition: rect.h:303
Rectd(double new_left, double new_top, double new_right, double new_bottom)
Definition: rect.h:506
Rectd(const Sizex< float > &s)
Definition: rect.h:504
A min(A a, B b)
Definition: cl_math.h:58
Rect(int new_left, int new_top, int new_right, int new_bottom)
Definition: rect.h:475
Rectf(const Rectx< float > &rect)
Definition: rect.h:493
Rectx< Type > & set_top_left(const Vec2< Type > &p)
Sets the top-left point of the rectangle.
Definition: rect.h:215
Pointx< Type > get_top_right() const
Returns the top-right point outside the rectangle.
Definition: rect.h:156
Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
Constructs an rectangle.
Definition: rect.h:72