cel_geom.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00004 //
00005 // (C) 2003-2006 Celartem Technology Inc. All rights reserved.
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             // NOTE
00331             // We firstly calculate on a temporary buffer; it reduces the
00332             // risk when outRect is same to either inRect1 or inRect2.
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 } // namespace Celartem
00434 
00435 #endif // _cel_geom_h_

This document is automatically generated using doxygen 1.5.4 at Fri Jun 27 18:21:54 2008.