00001
00004
00005
00006
00007
00008 #ifndef _cel_geom_h_
00009 #define _cel_geom_h_
00010
00011 #include "cel_types.h"
00012 #include <algorithm>
00013
00014 namespace Celartem
00015 {
00016 struct Rect;
00017
00018
00022 struct Point
00023 {
00024 ssize_t x;
00025 ssize_t y;
00026
00032 Point(ssize_t inX = 0, ssize_t inY = 0)
00033 : x(inX), y(inY)
00034 {
00035 }
00036
00040 inline void zeroReset()
00041 {
00042 x = y = 0;
00043 }
00044
00045 inline bool operator==(const Point& r) const
00046 {
00047 return (x == r.x && y == r.y);
00048 }
00049
00050 inline bool operator!=(const Point& r) const
00051 {
00052 return (x != r.x || y != r.y);
00053 }
00054
00055 bool isInside(const Rect& inRect) const;
00056 };
00057
00058
00062 struct Size
00063 {
00064 ssize_t width;
00065 ssize_t height;
00066
00074 Size(ssize_t inWidth = 0, ssize_t inHeight = 0)
00075 : width(inWidth), height(inHeight)
00076 {
00077 }
00078
00083 explicit Size(const Rect& inRect);
00084
00085 inline bool operator==(const Size& r) const
00086 {
00087 return (width == r.width && height == r.height);
00088 }
00089
00090 inline bool operator!=(const Size& r) const
00091 {
00092 return (width != r.width || height != r.height);
00093 }
00094 };
00095
00096
00101 struct Rect
00102 {
00103 ssize_t left;
00104 ssize_t top;
00105 ssize_t width;
00106 ssize_t height;
00107
00113 inline ssize_t right() const {return left + width;}
00114
00120 inline ssize_t bottom() const {return top + height;}
00121
00127 inline Point leftTop() const {return Point(left, top);}
00128
00134 inline Point leftBottom() const {return Point(left, bottom());}
00135
00141 inline Point rightTop() const {return Point(right(), top);}
00142
00148 inline Point rightBottom() const {return Point(right(), bottom());}
00149
00162 Rect(
00163 ssize_t inLeft = 0, ssize_t inTop = 0,
00164 ssize_t inWidth = 0, ssize_t inHeight = 0) :
00165 left(inLeft), top(inTop), width(inWidth), height(inHeight)
00166 {
00167 }
00168
00174 Rect(const Rect& inRect)
00175 {
00176 left = inRect.left;
00177 top = inRect.top;
00178 width = inRect.width;
00179 height = inRect.height;
00180 }
00181
00189 Rect& operator=(const Rect& inRect)
00190 {
00191 left = inRect.left;
00192 top = inRect.top;
00193 width = inRect.width;
00194 height = inRect.height;
00195 return *this;
00196 }
00197
00204 bool operator==(const Rect& inRect) const
00205 {
00206 return
00207 (inRect.left == left) && (inRect.top == top) &&
00208 (inRect.width == width) && (inRect.height == height);
00209 }
00210
00217 inline bool operator!=(const Rect& inRect) const
00218 {
00219 return (left != inRect.left || top != inRect.top
00220 || width != inRect.width || height != inRect.height);
00221 }
00222
00226 inline void zeroReset()
00227 {
00228 left = top = 0;
00229 width = height = 0;
00230 }
00231
00238 inline bool isValid() const
00239 {
00240 return (width > 0 && height > 0);
00241 }
00242
00254 inline bool isInside(const Rect& inRect) const
00255 {
00256 if(inRect.left > left || inRect.top > top
00257 || right() > inRect.right() || bottom() > inRect.bottom())
00258 return false;
00259 return true;
00260 }
00261
00271 static void
00272 unionRects(Rect& outRect, const Rect& inRect1, const Rect& inRect2)
00273 {
00274 Rect rc;
00275 rc.left = std::min<ssize_t>(inRect1.left, inRect2.left);
00276 rc.top = std::min<ssize_t>(inRect1.top, inRect2.top);
00277 rc.width = std::max<ssize_t>(
00278 inRect1.right(), inRect2.right()) - rc.left;
00279 rc.height = std::max<ssize_t>(
00280 inRect1.bottom(), inRect2.bottom()) - rc.top;
00281 outRect = rc;
00282 }
00283
00294 static void
00295 unionRects(Rect& outRect, const Rect* inRects, size_t inCount)
00296 {
00297 ssize_t left = SSIZE_MAX;
00298 ssize_t top = SSIZE_MAX;
00299 ssize_t right = SSIZE_MIN;
00300 ssize_t bottom = SSIZE_MIN;
00301 for(size_t i = 0; i < inCount; i++)
00302 {
00303 const Rect& rect = inRects[i];
00304 if(rect.left < left) left = rect.left;
00305 if(rect.top < top) top = rect.top;
00306 if(rect.right() > right) right = rect.right();
00307 if(rect.bottom() > bottom) bottom = rect.bottom();
00308 }
00309 outRect.left = left;
00310 outRect.top = top;
00311 outRect.width = right - left;
00312 outRect.height = bottom - top;
00313 }
00314
00327 static bool
00328 intersection(Rect& outRect, const Rect& inRect1, const Rect& inRect2)
00329 {
00330
00331
00332
00333 Rect rc;
00334
00335 rc.left = std::max<ssize_t>(inRect1.left, inRect2.left);
00336 rc.top = std::max<ssize_t>(inRect1.top, inRect2.top);
00337 rc.width = std::min<ssize_t>(
00338 inRect1.right(), inRect2.right()) - rc.left;
00339 rc.height = std::min<ssize_t>(
00340 inRect1.bottom(), inRect2.bottom()) - rc.top;
00341
00342 outRect = rc;
00343 return outRect.isValid();
00344 }
00345
00355 bool intersectWith(const Rect& inRect) const
00356 {
00357 Rect dummy;
00358 return intersection(dummy, *this, inRect);
00359 }
00360
00368 void
00369 offset(ssize_t inHorzOffset, ssize_t inVertOffset)
00370 {
00371 left += inHorzOffset;
00372 top += inVertOffset;
00373 }
00374
00380 void
00381 offset(const Point& inOffset)
00382 {
00383 offset(inOffset.x, inOffset.y);
00384 }
00385
00394 void inflate(ssize_t size)
00395 {
00396 left -= size;
00397 top -= size;
00398 width += size * 2;
00399 height += size * 2;
00400 }
00401
00412 void deflate(ssize_t size)
00413 {
00414 inflate(-size);
00415 }
00416 };
00417
00418
00419 inline Size::Size(const Rect& inRect)
00420 : width(inRect.width), height(inRect.height)
00421 {
00422 }
00423
00424
00425 inline bool Point::isInside(const Rect& inRect) const
00426 {
00427 if(x >= inRect.left && x < inRect.right() &&
00428 y >= inRect.top && y < inRect.bottom())
00429 return true;
00430 return false;
00431 }
00432
00433 }
00434
00435 #endif // _cel_geom_h_