00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00034
00035 #pragma once
00036
00037 #include "../api_core.h"
00038 #include "vec2.h"
00039 #include "size.h"
00040 #include "point.h"
00041 #include "origin.h"
00042 #include "cl_math.h"
00043
00049 template<typename Type>
00050 class CL_API_CORE CL_Rectx
00051 {
00054 public:
00058 CL_Rectx() { left = right = top = bottom = 0; }
00059
00063 CL_Rectx(const CL_Sizex<Type> &s) { left = 0; top = 0; right = s.width; bottom = s.height; }
00064
00071 CL_Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
00072 { left = new_left; top = new_top; right = new_right; bottom = new_bottom; }
00073
00078 CL_Rectx(const CL_Pointx<Type> &p, const CL_Sizex<Type> &size)
00079 { left = p.x; top = p.y; right = left + size.width; bottom = top + size.height; }
00080
00086 CL_Rectx(Type new_left, Type new_top, const CL_Sizex<Type> &size)
00087 { left = new_left; top = new_top; right = left + size.width; bottom = top + size.height; }
00088
00092 CL_Rectx(const CL_Rectx<int> &rect);
00093
00097 CL_Rectx(const CL_Rectx<float> &rect);
00098
00102 CL_Rectx(const CL_Rectx<double> &rect);
00103
00105 bool operator==(const CL_Rectx<Type> &r) const
00106 { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
00107
00109 bool operator!=(const CL_Rectx<Type> &r) const
00110 { return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); }
00111
00115 public:
00117 Type left;
00118
00120 Type top;
00121
00123 Type right;
00124
00126 Type bottom;
00127
00129 Type get_width() const { return right - left; }
00130
00132 Type get_height() const { return bottom - top; }
00133
00135 CL_Sizex<Type> get_size() const { return CL_Sizex<Type>(right - left, bottom - top); }
00136
00138 bool contains(const CL_Vec2<Type> &p) const
00139 {
00140 return ((p.x >= left && p.x <= right) || (p.x <= left && p.x >= right))
00141 && ((p.y >= top && p.y <= bottom) || (p.y <= top && p.y >= bottom));
00142 }
00143
00145 CL_Pointx<Type> get_top_left() const
00146 {
00147 return CL_Pointx<Type>(left, top);
00148 }
00149
00151 CL_Pointx<Type> get_top_right() const
00152 {
00153 return CL_Pointx<Type>(right, top);
00154 }
00155
00157 CL_Pointx<Type> get_bottom_right() const
00158 {
00159 return CL_Pointx<Type>(right, bottom);
00160 }
00161
00163 CL_Pointx<Type> get_bottom_left() const
00164 {
00165 return CL_Pointx<Type>(left, bottom);
00166 }
00167
00169 bool is_overlapped(const CL_Rectx<Type> &r) const
00170 {
00171 return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
00172 }
00173
00175 bool is_inside(const CL_Rectx<Type> &r) const
00176 {
00177 return ((left <= r.left)
00178 && (top <= r.top)
00179 && (right >= r.right)
00180 && (bottom >= r.bottom));
00181 }
00182
00187 CL_Rectx<Type> get_rot_bounds(const CL_Vec2<Type> &hotspot, const CL_Angle &angle) const;
00188
00195 CL_Rectx<Type> get_rot_bounds(CL_Origin origin, Type x, Type y, const CL_Angle &angle) const;
00196
00198 CL_Pointx<Type> get_center() const
00199 {
00200 return CL_Pointx<Type>( (left + right)/2, ( top + bottom)/2 );
00201 }
00202
00206 public:
00210 CL_Rectx<Type> &set_top_left(const CL_Vec2<Type>& p)
00211 {
00212 left = p.x;
00213 top = p.y;
00214 return *this;
00215 }
00216
00220 CL_Rectx<Type> &set_top_right(const CL_Vec2<Type>& p)
00221 {
00222 right = p.x;
00223 top = p.y;
00224 return *this;
00225 }
00226
00230 CL_Rectx<Type> &set_bottom_right(const CL_Vec2<Type>& p)
00231 {
00232 right = p.x;
00233 bottom = p.y;
00234 return *this;
00235 }
00236
00240 CL_Rectx<Type> &set_bottom_left(const CL_Vec2<Type>& p)
00241 {
00242 left = p.x;
00243 bottom = p.y;
00244 return *this;
00245 }
00246
00250 CL_Rectx<Type> &set_width(Type width)
00251 {
00252 right = left + width;
00253 return *this;
00254 }
00255
00259 CL_Rectx<Type> &set_height(Type height)
00260 {
00261 bottom = top + height;
00262 return *this;
00263 }
00264
00268 CL_Rectx<Type> &shrink(const Type &left, const Type &top, const Type &right, const Type &bottom)
00269 {
00270 this->left += left; this->top += top; this->right -= right; this->bottom -= bottom;
00271 return *this;
00272 };
00273
00277 CL_Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
00278 {
00279 this->left += left_right; this->top += top_bottom; this->right -= left_right; this->bottom -= top_bottom;
00280 return *this;
00281 };
00282
00286 CL_Rectx<Type> &shrink(const Type &shrink)
00287 {
00288 this->left += shrink; this->top += shrink; this->right -= shrink; this->bottom -= shrink;
00289 return *this;
00290 };
00291
00295 CL_Rectx<Type> &expand(const Type &left, const Type &top, const Type &right, const Type &bottom)
00296 {
00297 this->left -= left; this->top -= top; this->right += right; this->bottom += bottom;
00298 return *this;
00299 };
00300
00304 CL_Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
00305 {
00306 this->left -= left_and_right;
00307 this->right += left_and_right;
00308 this->top -= top_and_bottom;
00309 this->bottom += top_and_bottom;
00310 return *this;
00311 };
00312
00316 CL_Rectx<Type> &expand(const Type &expand)
00317 {
00318 this->left -= expand;
00319 this->right += expand;
00320 this->top -= expand;
00321 this->bottom += expand;
00322 return *this;
00323 };
00324
00328 CL_Rectx<Type> &translate(const CL_Vec2<Type> &p)
00329 {
00330 left += p.x; top += p.y; right += p.x; bottom += p.y;
00331 return *this;
00332 };
00333
00337 CL_Rectx<Type> &translate(const CL_Rectx<Type> &p)
00338 {
00339 left += p.left; top += p.top; right += p.left; bottom += p.top;
00340 return *this;
00341 };
00342
00346 CL_Rectx<Type> &translate(Type x, Type y)
00347 {
00348 left += x; top += y; right += x; bottom += y;
00349 return *this;
00350 };
00351
00355 CL_Rectx<Type> &set_size(const CL_Sizex<Type> &size)
00356 {
00357 right = left + size.width;
00358 bottom = top + size.height;
00359 return *this;
00360 }
00361
00367 CL_Rectx<Type> &overlap(const CL_Rectx<Type> &rect)
00368 {
00369 CL_Rectx<Type> result;
00370 result.left = cl_max(left, rect.left);
00371 result.right = cl_min(right, rect.right);
00372 result.top = cl_max(top, rect.top);
00373 result.bottom = cl_min(bottom, rect.bottom);
00374 *this = result;
00375 return *this;
00376 }
00377
00383 CL_Rectx<Type> &bounding_rect(const CL_Rectx<Type> &rect)
00384 {
00385 CL_Rectx<Type> result;
00386 result.left = cl_min(left, rect.left);
00387 result.right = cl_max(right, rect.right);
00388 result.top = cl_min(top, rect.top);
00389 result.bottom = cl_max(bottom, rect.bottom);
00390 *this = result;
00391 return *this;
00392 }
00393
00397 CL_Rectx<Type> &normalize()
00398 {
00399 if (left > right)
00400 {
00401 Type temp = right;
00402 right = left;
00403 left = temp;
00404 }
00405
00406 if (top > bottom)
00407 {
00408 Type temp = bottom;
00409 bottom = top;
00410 top = temp;
00411 }
00412 return *this;
00413 }
00414
00421 CL_Rectx<Type> &apply_alignment(CL_Origin origin, Type x, Type y)
00422 {
00423 CL_Vec2<Type> offset = CL_Vec2<Type>::calc_origin(origin, get_size());
00424 offset.x -= x;
00425 offset.y -= y;
00426
00427 left += offset.x;
00428 top += offset.y;
00429 right += offset.x;
00430 bottom += offset.y;
00431 return *this;
00432 }
00433
00437 CL_Rectx<Type> &clip(const CL_Rectx<Type> &cr)
00438 {
00439 top = cl_max(top, cr.top);
00440 left = cl_max(left, cr.left);
00441 right = cl_min(right, cr.right);
00442 bottom = cl_min(bottom, cr.bottom);
00443 top = cl_min(top, bottom);
00444 left = cl_min(left, right);
00445 return *this;
00446 }
00448 };
00449
00450 template<>
00451 inline CL_Rectx<int>::CL_Rectx(const CL_Rectx<float> &rect)
00452 { 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)); }
00453
00454 template<>
00455 inline CL_Rectx<int>::CL_Rectx(const CL_Rectx<double> &rect)
00456 { 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)); }
00457
00458 template<typename Type>
00459 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<int> &rect)
00460 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00461
00462 template<typename Type>
00463 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<float> &rect)
00464 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00465
00466 template<typename Type>
00467 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<double> &rect)
00468 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00469
00473 class CL_Rect : public CL_Rectx<int>
00474 {
00475 public:
00476 CL_Rect() : CL_Rectx<int>() {}
00477 CL_Rect(const CL_Sizex<int> &s) : CL_Rectx<int>(s) {}
00478 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) {}
00479 CL_Rect(const CL_Pointx<int> &p, const CL_Sizex<int> &size) : CL_Rectx<int>(p, size) {}
00480 CL_Rect(const CL_Rectx<int> &rect) : CL_Rectx<int>(rect) {}
00481 CL_Rect(const CL_Rectx<float> &rect) : CL_Rectx<int>(rect) {}
00482 CL_Rect(const CL_Rectx<double> &rect) : CL_Rectx<int>(rect) {}
00483 CL_Rect(int new_left, int new_top, const CL_Sizex<int> &size) : CL_Rectx<int>(new_left, new_top, size) {}
00484 };
00485
00489 class CL_Rectf : public CL_Rectx<float>
00490 {
00491 public:
00492 CL_Rectf() : CL_Rectx<float>() {}
00493 CL_Rectf(const CL_Sizex<int> &s) : CL_Rectx<float>(s) {}
00494 CL_Rectf(const CL_Sizex<float> &s) : CL_Rectx<float>(s) {}
00495 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) {}
00496 CL_Rectf(const CL_Pointx<float> &p, const CL_Sizex<float> &size) : CL_Rectx<float>(p, size) {}
00497 CL_Rectf(const CL_Rectx<int> &rect) : CL_Rectx<float>(rect) {}
00498 CL_Rectf(const CL_Rectx<float> &rect) : CL_Rectx<float>(rect) {}
00499 CL_Rectf(const CL_Rectx<double> &rect) : CL_Rectx<float>(rect) {}
00500 CL_Rectf(float new_left, float new_top, const CL_Sizex<float> &size) : CL_Rectx<float>(new_left, new_top, size) {}
00501 };
00502
00506 class CL_Rectd : public CL_Rectx<double>
00507 {
00508 public:
00509 CL_Rectd() : CL_Rectx<double>() {}
00510 CL_Rectd(const CL_Sizex<int> &s) : CL_Rectx<double>(s) {}
00511 CL_Rectd(const CL_Sizex<float> &s) : CL_Rectx<double>(s) {}
00512 CL_Rectd(const CL_Sizex<double> &s) : CL_Rectx<double>(s) {}
00513 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) {}
00514 CL_Rectd(const CL_Pointx<double> &p, const CL_Sizex<double> &size) : CL_Rectx<double>(p, size) {}
00515 CL_Rectd(const CL_Rectx<int> &rect) : CL_Rectx<double>(rect) {}
00516 CL_Rectd(const CL_Rectx<float> &rect) : CL_Rectx<double>(rect) {}
00517 CL_Rectd(const CL_Rectx<double> &rect) : CL_Rectx<double>(rect) {}
00518 CL_Rectd(double new_left, double new_top, const CL_Sizex<double> &size) : CL_Rectx<double>(new_left, new_top, size) {}
00519 };
00520
00521 inline CL_Rect CL_RectPS(int x, int y, int width, int height)
00522 {
00523 return CL_Rect(x, y, x+width, y+height);
00524 }
00525
00526 inline CL_Rectf CL_RectfPS(float x, float y, float width, float height)
00527 {
00528 return CL_Rectf(x, y, x+width, y+height);
00529 }
00530
00531 inline CL_Rectd CL_RectdPS(double x, double y, double width, double height)
00532 {
00533 return CL_Rectd(x, y, x+width, y+height);
00534 }
00535