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
00065 CL_Rectx(const CL_Sizex<Type> &s) { left = 0; top = 0; right = s.width; bottom = s.height; }
00066
00073 CL_Rectx(Type new_left, Type new_top, Type new_right, Type new_bottom)
00074 { left = new_left; top = new_top; right = new_right; bottom = new_bottom; }
00075
00080 CL_Rectx(const CL_Pointx<Type> &p, const CL_Sizex<Type> &size)
00081 { left = p.x; top = p.y; right = left + size.width; bottom = top + size.height; }
00082
00088 CL_Rectx(Type new_left, Type new_top, const CL_Sizex<Type> &size)
00089 { left = new_left; top = new_top; right = left + size.width; bottom = top + size.height; }
00090
00094 CL_Rectx(const CL_Rectx<int> &rect);
00095
00099 CL_Rectx(const CL_Rectx<float> &rect);
00100
00104 CL_Rectx(const CL_Rectx<double> &rect);
00105
00107 bool operator==(const CL_Rectx<Type> &r) const
00108 { return (left == r.left && top == r.top && right == r.right && bottom == r.bottom); }
00109
00111 bool operator!=(const CL_Rectx<Type> &r) const
00112 { return (left != r.left || top != r.top || right != r.right || bottom != r.bottom); }
00113
00117 public:
00119 Type left;
00120
00122 Type top;
00123
00125 Type right;
00126
00128 Type bottom;
00129
00131 Type get_width() const { return right - left; }
00132
00134 Type get_height() const { return bottom - top; }
00135
00137 CL_Sizex<Type> get_size() const { return CL_Sizex<Type>(right - left, bottom - top); }
00138
00140 bool contains(const CL_Vec2<Type> &p) const
00141 {
00142 return ((p.x >= left && p.x <= right) || (p.x <= left && p.x >= right))
00143 && ((p.y >= top && p.y <= bottom) || (p.y <= top && p.y >= bottom));
00144 }
00145
00147 CL_Pointx<Type> get_top_left() const
00148 {
00149 return CL_Pointx<Type>(left, top);
00150 }
00151
00153 CL_Pointx<Type> get_top_right() const
00154 {
00155 return CL_Pointx<Type>(right, top);
00156 }
00157
00159 CL_Pointx<Type> get_bottom_right() const
00160 {
00161 return CL_Pointx<Type>(right, bottom);
00162 }
00163
00165 CL_Pointx<Type> get_bottom_left() const
00166 {
00167 return CL_Pointx<Type>(left, bottom);
00168 }
00169
00171 bool is_overlapped(const CL_Rectx<Type> &r) const
00172 {
00173 return (r.left < right && r.right > left && r.top < bottom && r.bottom > top);
00174 }
00175
00182 CL_Rectx<Type> get_rot_bounds(const CL_Vec2<Type> &hotspot, const CL_Angle &angle) const;
00183 CL_Rectx<Type> get_rot_bounds(CL_Origin origin, Type x, Type y, const CL_Angle &angle) const;
00184
00186 CL_Pointx<Type> get_center() const
00187 {
00188 return CL_Pointx<Type>( (left + right)/2, ( top + bottom)/2 );
00189 }
00190
00194 public:
00198 CL_Rectx<Type> &set_top_left(const CL_Vec2<Type>& p)
00199 {
00200 left = p.x;
00201 top = p.y;
00202 return *this;
00203 }
00204
00208 CL_Rectx<Type> &set_top_right(const CL_Vec2<Type>& p)
00209 {
00210 right = p.x;
00211 top = p.y;
00212 return *this;
00213 }
00214
00218 CL_Rectx<Type> &set_bottom_right(const CL_Vec2<Type>& p)
00219 {
00220 right = p.x;
00221 bottom = p.y;
00222 return *this;
00223 }
00224
00228 CL_Rectx<Type> &set_bottom_left(const CL_Vec2<Type>& p)
00229 {
00230 left = p.x;
00231 bottom = p.y;
00232 return *this;
00233 }
00234
00238 CL_Rectx<Type> &set_width(Type width)
00239 {
00240 right = left + width;
00241 return *this;
00242 }
00243
00247 CL_Rectx<Type> &set_height(Type height)
00248 {
00249 bottom = top + height;
00250 return *this;
00251 }
00252
00256 CL_Rectx<Type> &shrink(const Type &left, const Type &top, const Type &right, const Type &bottom)
00257 {
00258 this->left += left; this->top += top; this->right -= right; this->bottom -= bottom;
00259 return *this;
00260 };
00261
00265 CL_Rectx<Type> &shrink(const Type &left_right, const Type &top_bottom)
00266 {
00267 this->left += left_right; this->top += top_bottom; this->right -= left_right; this->bottom -= top_bottom;
00268 return *this;
00269 };
00270
00274 CL_Rectx<Type> &shrink(const Type &shrink)
00275 {
00276 this->left += shrink; this->top += shrink; this->right -= shrink; this->bottom -= shrink;
00277 return *this;
00278 };
00279
00283 CL_Rectx<Type> &expand(const Type &left, const Type &top, const Type &right, const Type &bottom)
00284 {
00285 this->left -= left; this->top -= top; this->right += right; this->bottom += bottom;
00286 return *this;
00287 };
00288
00292 CL_Rectx<Type> &expand(const Type &left_and_right, const Type &top_and_bottom)
00293 {
00294 this->left -= left_and_right;
00295 this->right += left_and_right;
00296 this->top -= top_and_bottom;
00297 this->bottom += top_and_bottom;
00298 return *this;
00299 };
00300
00304 CL_Rectx<Type> &expand(const Type &expand)
00305 {
00306 this->left -= expand;
00307 this->right += expand;
00308 this->top -= expand;
00309 this->bottom += expand;
00310 return *this;
00311 };
00312
00316 CL_Rectx<Type> &translate(const CL_Vec2<Type> &p)
00317 {
00318 left += p.x; top += p.y; right += p.x; bottom += p.y;
00319 return *this;
00320 };
00321
00325 CL_Rectx<Type> &translate(const CL_Rectx<Type> &p)
00326 {
00327 left += p.left; top += p.top; right += p.left; bottom += p.top;
00328 return *this;
00329 };
00330
00334 CL_Rectx<Type> &translate(Type x, Type y)
00335 {
00336 left += x; top += y; right += x; bottom += y;
00337 return *this;
00338 };
00339
00343 CL_Rectx<Type> &set_size(const CL_Sizex<Type> &size)
00344 {
00345 right = left + size.width;
00346 bottom = top + size.height;
00347 return *this;
00348 }
00349
00355 CL_Rectx<Type> &overlap(const CL_Rectx<Type> &rect)
00356 {
00357 CL_Rectx<Type> result;
00358 result.left = cl_max(left, rect.left);
00359 result.right = cl_min(right, rect.right);
00360 result.top = cl_max(top, rect.top);
00361 result.bottom = cl_min(bottom, rect.bottom);
00362 *this = result;
00363 return *this;
00364 }
00365
00371 CL_Rectx<Type> &bounding_rect(const CL_Rectx<Type> &rect)
00372 {
00373 CL_Rectx<Type> result;
00374 result.left = cl_min(left, rect.left);
00375 result.right = cl_max(right, rect.right);
00376 result.top = cl_min(top, rect.top);
00377 result.bottom = cl_max(bottom, rect.bottom);
00378 *this = result;
00379 return *this;
00380 }
00381
00385 CL_Rectx<Type> &normalize()
00386 {
00387 if (left > right)
00388 {
00389 Type temp = right;
00390 right = left;
00391 left = temp;
00392 }
00393
00394 if (top > bottom)
00395 {
00396 Type temp = bottom;
00397 bottom = top;
00398 top = temp;
00399 }
00400 return *this;
00401 }
00402
00409 CL_Rectx<Type> &apply_alignment(CL_Origin origin, Type x, Type y)
00410 {
00411 CL_Vec2<Type> offset = CL_Vec2<Type>::calc_origin(origin, get_size());
00412 offset.x -= x;
00413 offset.y -= y;
00414
00415 left += offset.x;
00416 top += offset.y;
00417 right += offset.x;
00418 bottom += offset.y;
00419 return *this;
00420 }
00421
00425 CL_Rectx<Type> &clip(const CL_Rectx<Type> &cr)
00426 {
00427 top = cl_max(top, cr.top);
00428 left = cl_max(left, cr.left);
00429 right = cl_min(right, cr.right);
00430 bottom = cl_min(bottom, cr.bottom);
00431 top = cl_min(top, bottom);
00432 left = cl_min(left, right);
00433 return *this;
00434 }
00436 };
00437
00438 template<>
00439 inline CL_Rectx<int>::CL_Rectx(const CL_Rectx<float> &rect)
00440 { 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)); }
00441
00442 template<>
00443 inline CL_Rectx<int>::CL_Rectx(const CL_Rectx<double> &rect)
00444 { 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)); }
00445
00446 template<typename Type>
00447 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<int> &rect)
00448 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00449
00450 template<typename Type>
00451 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<float> &rect)
00452 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00453
00454 template<typename Type>
00455 inline CL_Rectx<Type>::CL_Rectx(const CL_Rectx<double> &rect)
00456 { left = (Type) rect.left; top = (Type) rect.top; right = (Type) rect.right; bottom = (Type) rect.bottom; }
00457
00461 class CL_Rect : public CL_Rectx<int>
00462 {
00463 public:
00464 CL_Rect() : CL_Rectx<int>() {}
00465 CL_Rect(const CL_Sizex<int> &s) : CL_Rectx<int>(s) {}
00466 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) {}
00467 CL_Rect(const CL_Pointx<int> &p, const CL_Sizex<int> &size) : CL_Rectx<int>(p, size) {}
00468 CL_Rect(const CL_Rectx<int> &rect) : CL_Rectx<int>(rect) {}
00469 CL_Rect(const CL_Rectx<float> &rect) : CL_Rectx<int>(rect) {}
00470 CL_Rect(const CL_Rectx<double> &rect) : CL_Rectx<int>(rect) {}
00471 CL_Rect(int new_left, int new_top, const CL_Sizex<int> &size) : CL_Rectx<int>(new_left, new_top, size) {}
00472 };
00473
00477 class CL_Rectf : public CL_Rectx<float>
00478 {
00479 public:
00480 CL_Rectf() : CL_Rectx<float>() {}
00481 CL_Rectf(const CL_Sizex<int> &s) : CL_Rectx<float>(s) {}
00482 CL_Rectf(const CL_Sizex<float> &s) : CL_Rectx<float>(s) {}
00483 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) {}
00484 CL_Rectf(const CL_Pointx<float> &p, const CL_Sizex<float> &size) : CL_Rectx<float>(p, size) {}
00485 CL_Rectf(const CL_Rectx<int> &rect) : CL_Rectx<float>(rect) {}
00486 CL_Rectf(const CL_Rectx<float> &rect) : CL_Rectx<float>(rect) {}
00487 CL_Rectf(const CL_Rectx<double> &rect) : CL_Rectx<float>(rect) {}
00488 CL_Rectf(float new_left, float new_top, const CL_Sizex<float> &size) : CL_Rectx<float>(new_left, new_top, size) {}
00489 };
00490
00494 class CL_Rectd : public CL_Rectx<double>
00495 {
00496 public:
00497 CL_Rectd() : CL_Rectx<double>() {}
00498 CL_Rectd(const CL_Sizex<int> &s) : CL_Rectx<double>(s) {}
00499 CL_Rectd(const CL_Sizex<float> &s) : CL_Rectx<double>(s) {}
00500 CL_Rectd(const CL_Sizex<double> &s) : CL_Rectx<double>(s) {}
00501 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) {}
00502 CL_Rectd(const CL_Pointx<double> &p, const CL_Sizex<double> &size) : CL_Rectx<double>(p, size) {}
00503 CL_Rectd(const CL_Rectx<int> &rect) : CL_Rectx<double>(rect) {}
00504 CL_Rectd(const CL_Rectx<float> &rect) : CL_Rectx<double>(rect) {}
00505 CL_Rectd(const CL_Rectx<double> &rect) : CL_Rectx<double>(rect) {}
00506 CL_Rectd(double new_left, double new_top, const CL_Sizex<double> &size) : CL_Rectx<double>(new_left, new_top, size) {}
00507 };
00508
00509 inline CL_Rect CL_RectPS(int x, int y, int width, int height)
00510 {
00511 return CL_Rect(x, y, x+width, y+height);
00512 }
00513
00514 inline CL_Rectf CL_RectfPS(float x, float y, float width, float height)
00515 {
00516 return CL_Rectf(x, y, x+width, y+height);
00517 }
00518
00519 inline CL_Rectd CL_RectdPS(double x, double y, double width, double height)
00520 {
00521 return CL_Rectd(x, y, x+width, y+height);
00522 }
00523