|
IrrlichtEngine
|
00001 // Copyright (C) 2002-2011 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