ClanLib  2.3.7
rect.h
Go to the documentation of this file.
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2011 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 
34 
35 #pragma once
36 
37 #include "../api_core.h"
38 #include "vec2.h"
39 #include "size.h"
40 #include "point.h"
41 #include "origin.h"
42 #include "cl_math.h"
43 
49 template<typename Type>
51 {
54 public:
58  CL_Rectx() { left = right = top = bottom = 0; }
59 
63  CL_Rectx(const CL_Sizex<Type> &s) { left = 0; top = 0; right = s.width; bottom = s.height; }
64 
71  CL_Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
72  { left = new_left; top = new_top; right = new_right; bottom = new_bottom; }
73 
78  CL_Rectx(const CL_Pointx<Type> &p, const CL_Sizex<Type> &size)
79  { left = p.x; top = p.y; right = left + size.width; bottom = top + size.height; }
80 
86  CL_Rectx(Type new_left, Type new_top, const CL_Sizex<Type> &size)
87  { left = new_left; top = new_top; right = left + size.width; bottom = top + size.height; }
88 
92  CL_Rectx(const CL_Rectx<int> &rect);
93 
97  CL_Rectx(const CL_Rectx<float> &rect);
98 
102  CL_Rectx(const CL_Rectx<double> &rect);
103 
105  bool operator==(const CL_Rectx<Type> &r) const
106  { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
107 
109  bool operator!=(const CL_Rectx<Type> &r) const
110  { return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); }
111 
115 public:
117  Type left;
118 
120  Type top;
121 
123  Type right;
124 
126  Type bottom;
127 
129  Type get_width() const { return right - left; }
130 
132  Type get_height() const { return bottom - top; }
133 
135  CL_Sizex<Type> get_size() const { return CL_Sizex<Type>(right - left, bottom - top); }
136 
138  bool contains(const CL_Vec2<Type> &p) const
139  {
140  return ((p.x >= left && p.x <= right) || (p.x <= left && p.x >= right))
141  && ((p.y >= top && p.y <= bottom) || (p.y <= top && p.y >= bottom));
142  }
143 
146  {
147  return CL_Pointx<Type>(left, top);
148  }
149 
152  {
153  return CL_Pointx<Type>(right, top);
154  }
155 
158  {
159  return CL_Pointx<Type>(right, bottom);
160  }
161 
164  {
165  return CL_Pointx<Type>(left, bottom);
166  }
167 
169  bool is_overlapped(const CL_Rectx<Type> &r) const
170  {
171  return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
172  }
173 
175  bool is_inside(const CL_Rectx<Type> &r) const
176  {
177  return ((left <= r.left)
178  && (top <= r.top)
179  && (right >= r.right)
180  && (bottom >= r.bottom));
181  }
182 
187  CL_Rectx<Type> get_rot_bounds(const CL_Vec2<Type> &hotspot, const CL_Angle &angle) const;
188 
195  CL_Rectx<Type> get_rot_bounds(CL_Origin origin, Type x, Type y, const CL_Angle &angle) const;
196 
199  {
200  return CL_Pointx<Type>( (left + right)/2, ( top + bottom)/2 );
201  }
202 
206 public:
211  {
212  left = p.x;
213  top = p.y;
214  return *this;
215  }
216 
221  {
222  right = p.x;
223  top = p.y;
224  return *this;
225  }
226 
231  {
232  right = p.x;
233  bottom = p.y;
234  return *this;
235  }
236 
241  {
242  left = p.x;
243  bottom = p.y;
244  return *this;
245  }
246 
251  {
252  right = left + width;
253  return *this;
254  }
255 
260  {
261  bottom = top + height;
262  return *this;
263  }
264 
268  CL_Rectx<Type> &shrink(const Type &left, const Type &top, const Type &right, const Type &bottom)
269  {
270  this->left += left; this->top += top; this->right -= right; this->bottom -= bottom;
271  return *this;
272  };
273 
277  CL_Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
278  {
279  this->left += left_right; this->top += top_bottom; this->right -= left_right; this->bottom -= top_bottom;
280  return *this;
281  };
282 
286  CL_Rectx<Type> &shrink(const Type &shrink)
287  {
288  this->left += shrink; this->top += shrink; this->right -= shrink; this->bottom -= shrink;
289  return *this;
290  };
291 
295  CL_Rectx<Type> &expand(const Type &left, const Type &top, const Type &right, const Type &bottom)
296  {
297  this->left -= left; this->top -= top; this->right += right; this->bottom += bottom;
298  return *this;
299  };
300 
304  CL_Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
305  {
306  this->left -= left_and_right;
307  this->right += left_and_right;
308  this->top -= top_and_bottom;
309  this->bottom += top_and_bottom;
310  return *this;
311  };
312 
316  CL_Rectx<Type> &expand(const Type &expand)
317  {
318  this->left -= expand;
319  this->right += expand;
320  this->top -= expand;
321  this->bottom += expand;
322  return *this;
323  };
324 
329  {
330  left += p.x; top += p.y; right += p.x; bottom += p.y;
331  return *this;
332  };
333 
338  {
339  left += p.left; top += p.top; right += p.left; bottom += p.top;
340  return *this;
341  };
342 
346  CL_Rectx<Type> &translate(Type x, Type y)
347  {
348  left += x; top += y; right += x; bottom += y;
349  return *this;
350  };
351 
356  {
357  right = left + size.width;
358  bottom = top + size.height;
359  return *this;
360  }
361 
368  {
369  CL_Rectx<Type> result;
370  result.left = cl_max(left, rect.left);
371  result.right = cl_min(right, rect.right);
372  result.top = cl_max(top, rect.top);
373  result.bottom = cl_min(bottom, rect.bottom);
374  *this = result;
375  return *this;
376  }
377 
384  {
385  CL_Rectx<Type> result;
386  result.left = cl_min(left, rect.left);
387  result.right = cl_max(right, rect.right);
388  result.top = cl_min(top, rect.top);
389  result.bottom = cl_max(bottom, rect.bottom);
390  *this = result;
391  return *this;
392  }
393 
398  {
399  if (left > right)
400  {
401  Type temp = right;
402  right = left;
403  left = temp;
404  }
405 
406  if (top > bottom)
407  {
408  Type temp = bottom;
409  bottom = top;
410  top = temp;
411  }
412  return *this;
413  }
414 
421  CL_Rectx<Type> &apply_alignment(CL_Origin origin, Type x, Type y)
422  {
423  CL_Vec2<Type> offset = CL_Vec2<Type>::calc_origin(origin, get_size());
424  offset.x -= x;
425  offset.y -= y;
426 
427  left += offset.x;
428  top += offset.y;
429  right += offset.x;
430  bottom += offset.y;
431  return *this;
432  }
433 
438  {
439  top = cl_max(top, cr.top);
440  left = cl_max(left, cr.left);
441  right = cl_min(right, cr.right);
442  bottom = cl_min(bottom, cr.bottom);
443  top = cl_min(top, bottom);
444  left = cl_min(left, right);
445  return *this;
446  }
448 };
449 
450 template<>
452 { 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)); }
453 
454 template<>
456 { 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)); }
457 
458 template<typename Type>
460 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
461 
462 template<typename Type>
464 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
465 
466 template<typename Type>
468 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
469 
473 class CL_Rect : public CL_Rectx<int>
474 {
475 public:
476  CL_Rect() : CL_Rectx<int>() {}
477  CL_Rect(const CL_Sizex<int> &s) : CL_Rectx<int>(s) {}
478  CL_Rect(int new_left, int new_top, int new_right, int new_bottom) : CL_Rectx<int>(new_left, new_top, new_right, new_bottom) {}
479  CL_Rect(const CL_Pointx<int> &p, const CL_Sizex<int> &size) : CL_Rectx<int>(p, size) {}
480  CL_Rect(const CL_Rectx<int> &rect) : CL_Rectx<int>(rect) {}
481  CL_Rect(const CL_Rectx<float> &rect) : CL_Rectx<int>(rect) {}
482  CL_Rect(const CL_Rectx<double> &rect) : CL_Rectx<int>(rect) {}
483  CL_Rect(int new_left, int new_top, const CL_Sizex<int> &size) : CL_Rectx<int>(new_left, new_top, size) {}
484 };
485 
489 class CL_Rectf : public CL_Rectx<float>
490 {
491 public:
492  CL_Rectf() : CL_Rectx<float>() {}
493  CL_Rectf(const CL_Sizex<int> &s) : CL_Rectx<float>(s) {}
494  CL_Rectf(const CL_Sizex<float> &s) : CL_Rectx<float>(s) {}
495  CL_Rectf(float new_left, float new_top, float new_right, float new_bottom) : CL_Rectx<float>(new_left, new_top, new_right, new_bottom) {}
496  CL_Rectf(const CL_Pointx<float> &p, const CL_Sizex<float> &size) : CL_Rectx<float>(p, size) {}
497  CL_Rectf(const CL_Rectx<int> &rect) : CL_Rectx<float>(rect) {}
498  CL_Rectf(const CL_Rectx<float> &rect) : CL_Rectx<float>(rect) {}
499  CL_Rectf(const CL_Rectx<double> &rect) : CL_Rectx<float>(rect) {}
500  CL_Rectf(float new_left, float new_top, const CL_Sizex<float> &size) : CL_Rectx<float>(new_left, new_top, size) {}
501 };
502 
506 class CL_Rectd : public CL_Rectx<double>
507 {
508 public:
509  CL_Rectd() : CL_Rectx<double>() {}
510  CL_Rectd(const CL_Sizex<int> &s) : CL_Rectx<double>(s) {}
511  CL_Rectd(const CL_Sizex<float> &s) : CL_Rectx<double>(s) {}
512  CL_Rectd(const CL_Sizex<double> &s) : CL_Rectx<double>(s) {}
513  CL_Rectd(double new_left, double new_top, double new_right, double new_bottom) : CL_Rectx<double>(new_left, new_top, new_right, new_bottom) {}
514  CL_Rectd(const CL_Pointx<double> &p, const CL_Sizex<double> &size) : CL_Rectx<double>(p, size) {}
515  CL_Rectd(const CL_Rectx<int> &rect) : CL_Rectx<double>(rect) {}
516  CL_Rectd(const CL_Rectx<float> &rect) : CL_Rectx<double>(rect) {}
517  CL_Rectd(const CL_Rectx<double> &rect) : CL_Rectx<double>(rect) {}
518  CL_Rectd(double new_left, double new_top, const CL_Sizex<double> &size) : CL_Rectx<double>(new_left, new_top, size) {}
519 };
520 
521 inline CL_Rect CL_RectPS(int x, int y, int width, int height)
522 {
523  return CL_Rect(x, y, x+width, y+height);
524 }
525 
526 inline CL_Rectf CL_RectfPS(float x, float y, float width, float height)
527 {
528  return CL_Rectf(x, y, x+width, y+height);
529 }
530 
531 inline CL_Rectd CL_RectdPS(double x, double y, double width, double height)
532 {
533  return CL_Rectd(x, y, x+width, y+height);
534 }
535