rect.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2013 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 "../api_core.h"
36 #include "vec2.h"
37 #include "size.h"
38 #include "point.h"
39 #include "origin.h"
40 #include "cl_math.h"
41 
42 namespace clan
43 {
46 
51 template<typename Type>
52 class CL_API_CORE Rectx
53 {
56 public:
60  Rectx() { left = right = top = bottom = 0; }
61 
65  Rectx(const Sizex<Type> &s) { left = 0; top = 0; right = s.width; bottom = s.height; }
66 
73  Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
74  { left = new_left; top = new_top; right = new_right; bottom = new_bottom; }
75 
80  Rectx(const Pointx<Type> &p, const Sizex<Type> &size)
81  { left = p.x; top = p.y; right = left + size.width; bottom = top + size.height; }
82 
88  Rectx(Type new_left, Type new_top, const Sizex<Type> &size)
89  { left = new_left; top = new_top; right = left + size.width; bottom = top + size.height; }
90 
94  Rectx(const Rectx<int> &rect);
95 
99  Rectx(const Rectx<float> &rect);
100 
104  Rectx(const Rectx<double> &rect);
105 
107  bool operator==(const Rectx<Type> &r) const
108  { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
109 
111  bool operator!=(const Rectx<Type> &r) const
112  { return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); }
113 
117 public:
119  Type left;
120 
122  Type top;
123 
125  Type right;
126 
128  Type bottom;
129 
131  Type get_width() const { return right - left; }
132 
134  Type get_height() const { return bottom - top; }
135 
137  Sizex<Type> get_size() const { return Sizex<Type>(right - left, bottom - top); }
138 
140  bool contains(const Vec2<Type> &p) const
141  {
142  return (p.x >= left && p.x < right)
143  && (p.y >= top && p.y < bottom);
144  }
145 
148  {
149  return Pointx<Type>(left, top);
150  }
151 
154  {
155  return Pointx<Type>(right, top);
156  }
157 
160  {
161  return Pointx<Type>(right, bottom);
162  }
163 
166  {
167  return Pointx<Type>(left, bottom);
168  }
169 
171  bool is_overlapped(const Rectx<Type> &r) const
172  {
173  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
174  }
175 
177  bool is_inside(const Rectx<Type> &r) const
178  {
179  return ((left <= r.left)
180  && (top <= r.top)
181  && (right >= r.right)
182  && (bottom >= r.bottom));
183  }
184 
189  Rectx<Type> get_rot_bounds(const Vec2<Type> &hotspot, const Angle &angle) const;
190 
197  Rectx<Type> get_rot_bounds(Origin origin, Type x, Type y, const Angle &angle) const;
198 
201  {
202  return Pointx<Type>( (left + right)/2, ( top + bottom)/2 );
203  }
204 
208 public:
213  {
214  left = p.x;
215  top = p.y;
216  return *this;
217  }
218 
222  Rectx<Type> &set_width(Type width)
223  {
224  right = left + width;
225  return *this;
226  }
227 
231  Rectx<Type> &set_height(Type height)
232  {
233  bottom = top + height;
234  return *this;
235  }
236 
240  Rectx<Type> &shrink(const Type &left, const Type &top, const Type &right, const Type &bottom)
241  {
242  this->left += left; this->top += top; this->right -= right; this->bottom -= bottom;
243  return *this;
244  };
245 
249  Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
250  {
251  this->left += left_right; this->top += top_bottom; this->right -= left_right; this->bottom -= top_bottom;
252  return *this;
253  };
254 
258  Rectx<Type> &shrink(const Type &shrink)
259  {
260  this->left += shrink; this->top += shrink; this->right -= shrink; this->bottom -= shrink;
261  return *this;
262  };
263 
267  Rectx<Type> &expand(const Type &left, const Type &top, const Type &right, const Type &bottom)
268  {
269  this->left -= left; this->top -= top; this->right += right; this->bottom += bottom;
270  return *this;
271  };
272 
276  Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
277  {
278  this->left -= left_and_right;
279  this->right += left_and_right;
280  this->top -= top_and_bottom;
281  this->bottom += top_and_bottom;
282  return *this;
283  };
284 
288  Rectx<Type> &expand(const Type &expand)
289  {
290  this->left -= expand;
291  this->right += expand;
292  this->top -= expand;
293  this->bottom += expand;
294  return *this;
295  };
296 
301  {
302  left += p.x; top += p.y; right += p.x; bottom += p.y;
303  return *this;
304  };
305 
310  {
311  left += p.width; top += p.height; right += p.width; bottom += p.height;
312  return *this;
313  };
314 
319  {
320  left += p.left; top += p.top; right += p.left; bottom += p.top;
321  return *this;
322  };
323 
327  Rectx<Type> &translate(Type x, Type y)
328  {
329  left += x; top += y; right += x; bottom += y;
330  return *this;
331  };
332 
337  {
338  right = left + size.width;
339  bottom = top + size.height;
340  return *this;
341  }
342 
349  {
350  Rectx<Type> result;
351  result.left = max(left, rect.left);
352  result.right = min(right, rect.right);
353  result.top = max(top, rect.top);
354  result.bottom = min(bottom, rect.bottom);
355  if (result.right < result.left)
356  result.left = result.right;
357  if (result.bottom < result.top)
358  result.top = result.bottom;
359 
360  *this = result;
361  return *this;
362  }
363 
370  {
371  Rectx<Type> result;
372  result.left = min(left, rect.left);
373  result.right = max(right, rect.right);
374  result.top = min(top, rect.top);
375  result.bottom = max(bottom, rect.bottom);
376  *this = result;
377  return *this;
378  }
379 
387  {
388  if (left > right)
389  right = left;
390 
391  if (top > bottom)
392  bottom = top;
393 
394  return *this;
395  }
396 
403  Rectx<Type> &apply_alignment(Origin origin, Type x, Type y)
404  {
405  Vec2<Type> offset = Vec2<Type>::calc_origin(origin, get_size());
406  offset.x -= x;
407  offset.y -= y;
408 
409  left += offset.x;
410  top += offset.y;
411  right += offset.x;
412  bottom += offset.y;
413  return *this;
414  }
415 
420  {
421  top = max(top, cr.top);
422  left = max(left, cr.left);
423  right = min(right, cr.right);
424  bottom = min(bottom, cr.bottom);
425  top = min(top, bottom);
426  left = min(left, right);
427  return *this;
428  }
430 };
431 
432 template<>
433 inline Rectx<int>::Rectx(const Rectx<float> &rect)
434 { left = (int) (floor(rect.left + 0.5f)); top = (int) (floor(rect.top + 0.5f)); right = (int) (floor(rect.right + 0.5f)); bottom = (int) (floor(rect.bottom+0.5f)); }
435 
436 template<>
437 inline Rectx<int>::Rectx(const Rectx<double> &rect)
438 { left = (int) (floor(rect.left + 0.5)); top = (int) (floor(rect.top + 0.5)); right = (int) (floor(rect.right + 0.5)); bottom = (int) (floor(rect.bottom + 0.5)); }
439 
440 template<typename Type>
441 inline Rectx<Type>::Rectx(const Rectx<int> &rect)
442 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
443 
444 template<typename Type>
445 inline Rectx<Type>::Rectx(const Rectx<float> &rect)
446 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
447 
448 template<typename Type>
450 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
451 
453 class Rect : public Rectx<int>
454 {
455 public:
456  Rect() : Rectx<int>() {}
457  Rect(const Sizex<int> &s) : Rectx<int>(s) {}
458  Rect(int new_left, int new_top, int new_right, int new_bottom) : Rectx<int>(new_left, new_top, new_right, new_bottom) {}
459  Rect(const Pointx<int> &p, const Sizex<int> &size) : Rectx<int>(p, size) {}
460  Rect(const Rectx<int> &rect) : Rectx<int>(rect) {}
461  Rect(const Rectx<float> &rect) : Rectx<int>(rect) {}
462  Rect(const Rectx<double> &rect) : Rectx<int>(rect) {}
463  Rect(int new_left, int new_top, const Sizex<int> &size) : Rectx<int>(new_left, new_top, size) {}
464 };
465 
467 class Rectf : public Rectx<float>
468 {
469 public:
470  Rectf() : Rectx<float>() {}
471  Rectf(const Sizex<int> &s) : Rectx<float>(s) {}
472  Rectf(const Sizex<float> &s) : Rectx<float>(s) {}
473  Rectf(float new_left, float new_top, float new_right, float new_bottom) : Rectx<float>(new_left, new_top, new_right, new_bottom) {}
474  Rectf(const Pointx<float> &p, const Sizex<float> &size) : Rectx<float>(p, size) {}
475  Rectf(const Rectx<int> &rect) : Rectx<float>(rect) {}
476  Rectf(const Rectx<float> &rect) : Rectx<float>(rect) {}
477  Rectf(const Rectx<double> &rect) : Rectx<float>(rect) {}
478  Rectf(float new_left, float new_top, const Sizex<float> &size) : Rectx<float>(new_left, new_top, size) {}
479 };
480 
482 class Rectd : public Rectx<double>
483 {
484 public:
485  Rectd() : Rectx<double>() {}
486  Rectd(const Sizex<int> &s) : Rectx<double>(s) {}
487  Rectd(const Sizex<float> &s) : Rectx<double>(s) {}
488  Rectd(const Sizex<double> &s) : Rectx<double>(s) {}
489  Rectd(double new_left, double new_top, double new_right, double new_bottom) : Rectx<double>(new_left, new_top, new_right, new_bottom) {}
490  Rectd(const Pointx<double> &p, const Sizex<double> &size) : Rectx<double>(p, size) {}
491  Rectd(const Rectx<int> &rect) : Rectx<double>(rect) {}
492  Rectd(const Rectx<float> &rect) : Rectx<double>(rect) {}
493  Rectd(const Rectx<double> &rect) : Rectx<double>(rect) {}
494  Rectd(double new_left, double new_top, const Sizex<double> &size) : Rectx<double>(new_left, new_top, size) {}
495 };
496 
497 inline Rect RectPS(int x, int y, int width, int height)
498 {
499  return Rect(x, y, x+width, y+height);
500 }
501 
502 inline Rectf RectfPS(float x, float y, float width, float height)
503 {
504  return Rectf(x, y, x+width, y+height);
505 }
506 
507 inline Rectd RectdPS(double x, double y, double width, double height)
508 {
509  return Rectd(x, y, x+width, y+height);
510 }
511 
512 }
513 
Rectf(const Sizex< int > &s)
Definition: rect.h:471
Rectx(const Sizex< Type > &s)
Constructs an rectangle.
Definition: rect.h:65
Rect RectPS(int x, int y, int width, int height)
Definition: rect.h:497
bool operator!=(const Rectx< Type > &r) const
Rect != Rect operator.
Definition: rect.h:111
Rectx< Type > & shrink(const Type &left_right, const Type &top_bottom)
Shrink the rectangle.
Definition: rect.h:249
Rectx< Type > & shrink(const Type &shrink)
Shrink the rectangle.
Definition: rect.h:258
2D (left,top,right,bottom) rectangle structure - Double
Definition: rect.h:482
Rectx< Type > & translate(const Rectx< Type > &p)
Translate the rect by another rect (only uses the left and top coords).
Definition: rect.h:318
Type width
Size width.
Definition: size.h:83
Angle class.
Definition: angle.h:63
bool is_overlapped(const Rectx< Type > &r) const
Returns true if rectangle passed is overlapping or inside this rectangle.
Definition: rect.h:171
Rectd(const Rectx< int > &rect)
Definition: rect.h:491
Rectx< Type > & translate(const Vec2< Type > &p)
Translate the rect.
Definition: rect.h:300
Rectx< Type > & overlap(const Rectx< Type > &rect)
Calculates the intersection of two rectangles.
Definition: rect.h:348
Rectx()
Constructs an rectangle.
Definition: rect.h:60
Rectd(const Sizex< float > &s)
Definition: rect.h:487
Rect(int new_left, int new_top, const Sizex< int > &size)
Definition: rect.h:463
bool contains(const Vec2< Type > &p) const
Returns true if the rectangle contains the point.
Definition: rect.h:140
Rect()
Definition: rect.h:456
Rectx< Type > & clip(const Rectx< Type > &cr)
Clip according to the specified clip rectangle.
Definition: rect.h:419
Pointx< Type > get_center() const
Returns the center point of the rectangle.
Definition: rect.h:200
Origin
Alignment origins.
Definition: origin.h:41
Pointx< Type > get_top_right() const
Returns the top-right point outside the rectangle.
Definition: rect.h:153
Rectx(Type new_left, Type new_top, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:88
Rectx< Type > & set_top_left(const Vec2< Type > &p)
Sets the top-left point of the rectangle.
Definition: rect.h:212
Type height
Size height.
Definition: size.h:86
Rectd(const Pointx< double > &p, const Sizex< double > &size)
Definition: rect.h:490
Rectf(const Rectx< int > &rect)
Definition: rect.h:475
Rect(const Sizex< int > &s)
Definition: rect.h:457
A min(A a, B b)
Definition: cl_math.h:51
Rect(const Rectx< double > &rect)
Definition: rect.h:462
Rectx< Type > & expand(const Type &expand)
Expand the rectangle.
Definition: rect.h:288
Type top
Y1-coordinate (top point inside the rectangle)
Definition: rect.h:122
Rect(int new_left, int new_top, int new_right, int new_bottom)
Definition: rect.h:458
Rectd(double new_left, double new_top, const Sizex< double > &size)
Definition: rect.h:494
Rectd()
Definition: rect.h:485
Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
Constructs an rectangle.
Definition: rect.h:73
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 &left, const Type &top, const Type &right, const Type &bottom)
Shrink the rectangle.
Definition: rect.h:240
2D (left,top,right,bottom) rectangle structure - Integer
Definition: rect.h:453
Type x
Definition: vec2.h:82
bool is_inside(const Rectx< Type > &r) const
Returns true if rectangle passed is inside this rectangle.
Definition: rect.h:177
Rectf()
Definition: rect.h:470
Rectx< Type > & translate(const Sizex< Type > &p)
Translate the rect.
Definition: rect.h:309
Rectx< Type > & set_height(Type height)
Sets the height of the rectangle.
Definition: rect.h:231
Type get_width() const
Returns the width of the rectangle.
Definition: rect.h:131
Rectf RectfPS(float x, float y, float width, float height)
Definition: rect.h:502
Sizex< Type > get_size() const
Returns the size of the rectangle.
Definition: rect.h:137
Rectx< Type > & expand(const Type &left_and_right, const Type &top_and_bottom)
Expand the rectangle.
Definition: rect.h:276
2D (left,top,right,bottom) rectangle structure - Float
Definition: rect.h:467
Rectf(const Sizex< float > &s)
Definition: rect.h:472
Rectx< Type > & expand(const Type &left, const Type &top, const Type &right, const Type &bottom)
Expand the rectangle.
Definition: rect.h:267
Rect(const Rectx< float > &rect)
Definition: rect.h:461
Rectx< Type > & apply_alignment(Origin origin, Type x, Type y)
Applies an origin and offset pair to this rectangle.
Definition: rect.h:403
Rectd(const Rectx< float > &rect)
Definition: rect.h:492
Rectx< Type > & set_size(const Sizex< Type > &size)
Sets the size of the rectangle, maintaining top/left position.
Definition: rect.h:336
Rect(const Pointx< int > &p, const Sizex< int > &size)
Definition: rect.h:459
A max(A a, B b)
Definition: cl_math.h:52
Rect(const Rectx< int > &rect)
Definition: rect.h:460
2D vector
Definition: line.h:49
Rectf(const Rectx< float > &rect)
Definition: rect.h:476
2D (left,top,right,bottom) rectangle structure.
Definition: line.h:46
Rectx< Type > & bounding_rect(const Rectx< Type > &rect)
Calculates the bounding rectangle of the rectangles.
Definition: rect.h:369
Type left
X1-coordinate (left point inside the rectangle)
Definition: rect.h:119
Type right
X2-coordinate (point outside the rectangle)
Definition: rect.h:125
bool operator==(const Rectx< Type > &r) const
Rect == Rect operator.
Definition: rect.h:107
Rectd RectdPS(double x, double y, double width, double height)
Definition: rect.h:507
Rectx< Type > & normalize()
Normalize rectangle.
Definition: rect.h:386
Rectx< Type > & translate(Type x, Type y)
Translate the rect.
Definition: rect.h:327
Rectf(float new_left, float new_top, const Sizex< float > &size)
Definition: rect.h:478
Rectf(const Pointx< float > &p, const Sizex< float > &size)
Definition: rect.h:474
2D (x,y) point structure.
Definition: point.h:53
Rectd(const Sizex< double > &s)
Definition: rect.h:488
Rectf(const Rectx< double > &rect)
Definition: rect.h:477
Pointx< Type > get_bottom_right() const
Returns the bottom-right point outside the rectangle.
Definition: rect.h:159
Rectf(float new_left, float new_top, float new_right, float new_bottom)
Definition: rect.h:473
Rectd(double new_left, double new_top, double new_right, double new_bottom)
Definition: rect.h:489
Rectx(const Pointx< Type > &p, const Sizex< Type > &size)
Constructs an rectangle.
Definition: rect.h:80
Pointx< Type > get_top_left() const
Returns the top-left point inside the rectangle.
Definition: rect.h:147
Rectx< Type > & set_width(Type width)
Sets the width of the rectangle.
Definition: rect.h:222
Rectd(const Sizex< int > &s)
Definition: rect.h:486
Type bottom
Y2-coordinate (point outside the rectange)
Definition: rect.h:128
Pointx< Type > get_bottom_left() const
Returns the bottom-left point outside the rectangle.
Definition: rect.h:165
2D (width,height) size structure.
Definition: size.h:55
Type get_height() const
Returns the height of the rectangle.
Definition: rect.h:134
Type y
Definition: vec2.h:83
Rectd(const Rectx< double > &rect)
Definition: rect.h:493