Irrlicht 3D Engine
rect.h
Go to the documentation of this file.
00001 // Copyright (C) 2002-2012 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
00004 
00005 #ifndef __IRR_RECT_H_INCLUDED__
00006 #define __IRR_RECT_H_INCLUDED__
00007 
00008 #include "irrTypes.h"
00009 #include "dimension2d.h"
00010 #include "position2d.h"
00011 
00012 namespace irr
00013 {
00014 namespace core
00015 {
00016 
00018 
00025     template <class T>
00026     class rect
00027     {
00028     public:
00029 
00031         rect() : UpperLeftCorner(0,0), LowerRightCorner(0,0) {}
00032 
00034         rect(T x, T y, T x2, T y2)
00035             : UpperLeftCorner(x,y), LowerRightCorner(x2,y2) {}
00036 
00038         rect(const position2d<T>& upperLeft, const position2d<T>& lowerRight)
00039             : UpperLeftCorner(upperLeft), LowerRightCorner(lowerRight) {}
00040 
00042         template <class U>
00043         rect(const position2d<T>& pos, const dimension2d<U>& size)
00044             : UpperLeftCorner(pos), LowerRightCorner(pos.X + size.Width, pos.Y + size.Height) {}
00045 
00047         rect<T> operator+(const position2d<T>& pos) const
00048         {
00049             rect<T> ret(*this);
00050             return ret+=pos;
00051         }
00052 
00054         rect<T>& operator+=(const position2d<T>& pos)
00055         {
00056             UpperLeftCorner += pos;
00057             LowerRightCorner += pos;
00058             return *this;
00059         }
00060 
00062         rect<T> operator-(const position2d<T>& pos) const
00063         {
00064             rect<T> ret(*this);
00065             return ret-=pos;
00066         }
00067 
00069         rect<T>& operator-=(const position2d<T>& pos)
00070         {
00071             UpperLeftCorner -= pos;
00072             LowerRightCorner -= pos;
00073             return *this;
00074         }
00075 
00077         bool operator==(const rect<T>& other) const
00078         {
00079             return (UpperLeftCorner == other.UpperLeftCorner &&
00080                 LowerRightCorner == other.LowerRightCorner);
00081         }
00082 
00084         bool operator!=(const rect<T>& other) const
00085         {
00086             return (UpperLeftCorner != other.UpperLeftCorner ||
00087                 LowerRightCorner != other.LowerRightCorner);
00088         }
00089 
00091         bool operator<(const rect<T>& other) const
00092         {
00093             return getArea() < other.getArea();
00094         }
00095 
00097         T getArea() const
00098         {
00099             return getWidth() * getHeight();
00100         }
00101 
00103 
00105         bool isPointInside(const position2d<T>& pos) const
00106         {
00107             return (UpperLeftCorner.X <= pos.X &&
00108                 UpperLeftCorner.Y <= pos.Y &&
00109                 LowerRightCorner.X >= pos.X &&
00110                 LowerRightCorner.Y >= pos.Y);
00111         }
00112 
00114 
00116         bool isRectCollided(const rect<T>& other) const
00117         {
00118             return (LowerRightCorner.Y > other.UpperLeftCorner.Y &&
00119                 UpperLeftCorner.Y < other.LowerRightCorner.Y &&
00120                 LowerRightCorner.X > other.UpperLeftCorner.X &&
00121                 UpperLeftCorner.X < other.LowerRightCorner.X);
00122         }
00123 
00125 
00126         void clipAgainst(const rect<T>& other)
00127         {
00128             if (other.LowerRightCorner.X < LowerRightCorner.X)
00129                 LowerRightCorner.X = other.LowerRightCorner.X;
00130             if (other.LowerRightCorner.Y < LowerRightCorner.Y)
00131                 LowerRightCorner.Y = other.LowerRightCorner.Y;
00132 
00133             if (other.UpperLeftCorner.X > UpperLeftCorner.X)
00134                 UpperLeftCorner.X = other.UpperLeftCorner.X;
00135             if (other.UpperLeftCorner.Y > UpperLeftCorner.Y)
00136                 UpperLeftCorner.Y = other.UpperLeftCorner.Y;
00137 
00138             // correct possible invalid rect resulting from clipping
00139             if (UpperLeftCorner.Y > LowerRightCorner.Y)
00140                 UpperLeftCorner.Y = LowerRightCorner.Y;
00141             if (UpperLeftCorner.X > LowerRightCorner.X)
00142                 UpperLeftCorner.X = LowerRightCorner.X;
00143         }
00144 
00146 
00147         bool constrainTo(const rect<T>& other)
00148         {
00149             if (other.getWidth() < getWidth() || other.getHeight() < getHeight())
00150                 return false;
00151 
00152             T diff = other.LowerRightCorner.X - LowerRightCorner.X;
00153             if (diff < 0)
00154             {
00155                 LowerRightCorner.X += diff;
00156                 UpperLeftCorner.X  += diff;
00157             }
00158 
00159             diff = other.LowerRightCorner.Y - LowerRightCorner.Y;
00160             if (diff < 0)
00161             {
00162                 LowerRightCorner.Y += diff;
00163                 UpperLeftCorner.Y  += diff;
00164             }
00165 
00166             diff = UpperLeftCorner.X - other.UpperLeftCorner.X;
00167             if (diff < 0)
00168             {
00169                 UpperLeftCorner.X  -= diff;
00170                 LowerRightCorner.X -= diff;
00171             }
00172 
00173             diff = UpperLeftCorner.Y - other.UpperLeftCorner.Y;
00174             if (diff < 0)
00175             {
00176                 UpperLeftCorner.Y  -= diff;
00177                 LowerRightCorner.Y -= diff;
00178             }
00179 
00180             return true;
00181         }
00182 
00184         T getWidth() const
00185         {
00186             return LowerRightCorner.X - UpperLeftCorner.X;
00187         }
00188 
00190         T getHeight() const
00191         {
00192             return LowerRightCorner.Y - UpperLeftCorner.Y;
00193         }
00194 
00196         void repair()
00197         {
00198             if (LowerRightCorner.X < UpperLeftCorner.X)
00199             {
00200                 T t = LowerRightCorner.X;
00201                 LowerRightCorner.X = UpperLeftCorner.X;
00202                 UpperLeftCorner.X = t;
00203             }
00204 
00205             if (LowerRightCorner.Y < UpperLeftCorner.Y)
00206             {
00207                 T t = LowerRightCorner.Y;
00208                 LowerRightCorner.Y = UpperLeftCorner.Y;
00209                 UpperLeftCorner.Y = t;
00210             }
00211         }
00212 
00214 
00216         bool isValid() const
00217         {
00218             return ((LowerRightCorner.X >= UpperLeftCorner.X) &&
00219                 (LowerRightCorner.Y >= UpperLeftCorner.Y));
00220         }
00221 
00223         position2d<T> getCenter() const
00224         {
00225             return position2d<T>(
00226                     (UpperLeftCorner.X + LowerRightCorner.X) / 2,
00227                     (UpperLeftCorner.Y + LowerRightCorner.Y) / 2);
00228         }
00229 
00231         dimension2d<T> getSize() const
00232         {
00233             return dimension2d<T>(getWidth(), getHeight());
00234         }
00235 
00236 
00238 
00241         void addInternalPoint(const position2d<T>& p)
00242         {
00243             addInternalPoint(p.X, p.Y);
00244         }
00245 
00247 
00251         void addInternalPoint(T x, T y)
00252         {
00253             if (x>LowerRightCorner.X)
00254                 LowerRightCorner.X = x;
00255             if (y>LowerRightCorner.Y)
00256                 LowerRightCorner.Y = y;
00257 
00258             if (x<UpperLeftCorner.X)
00259                 UpperLeftCorner.X = x;
00260             if (y<UpperLeftCorner.Y)
00261                 UpperLeftCorner.Y = y;
00262         }
00263 
00265         position2d<T> UpperLeftCorner;
00267         position2d<T> LowerRightCorner;
00268     };
00269 
00271     typedef rect<f32> rectf;
00273     typedef rect<s32> recti;
00274 
00275 } // end namespace core
00276 } // end namespace irr
00277 
00278 #endif
00279