1 /****************************************************************************** 2 * Warmux is a convivial mass murder game. 3 * Copyright (C) 2001-2011 Warmux Team. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 ****************************************************************************** 19 * Rectangle.h: Standard C++ Rectangle template 20 ****************************************************************************** 21 * 2005/09/21: Jean-Christophe Duberga (jcduberga@gmx.de) 22 * Initial version 23 *****************************************************************************/ 24 25 #ifndef WARMUX_RECTANGLE_H 26 #define WARMUX_RECTANGLE_H 27 28 #include <cmath> 29 #include <WARMUX_error.h> 30 #include <WARMUX_types.h> 31 #include <WARMUX_vector2.h> 32 33 /** 34 * This template handle rectangles. 35 * 36 * @param T Type for position and size of the Rectangle 37 */ 38 template<class T> class rectangle 39 { 40 protected: 41 /** Position of the rectangle. */ 42 Vector2<T> position; 43 /** Size of the rectangle. */ 44 Vector2<T> size; 45 46 public: 47 /** 48 * Default constructor 49 */ rectangle()50 inline rectangle(): 51 position(0, 0), 52 size(0, 0) 53 { } 54 ~rectangle()55 virtual ~rectangle() {}; 56 57 /** 58 * Constructor for building a new rectangle. 59 * 60 * @param x Position among the x axe. 61 * @param y Position among the y axe. 62 * @param width Width of the new rectangle. 63 * @param height Height of the new rectangle. 64 */ rectangle(T x,T y,T width,T height)65 inline rectangle(T x, T y, T width, T height): 66 position(x, y), 67 size(width, height) 68 { } 69 70 /** 71 * Constructor for building a new rectangle with the position and size specified. 72 * 73 * @param thePosition Position of the new rectangle. 74 * @param theSize Size of the new rectangle. 75 */ rectangle(Vector2<T> thePosition,Vector2<T> theSize)76 inline rectangle(Vector2<T> thePosition, Vector2<T> theSize): 77 position(thePosition), 78 size(theSize) 79 {} 80 81 /** 82 * Set the position of the rectangle. 83 * 84 * @param x New X position. 85 * @param y New Y position. 86 */ SetPosition(T x,T y)87 inline void SetPosition(T x, T y){ 88 position.SetValues(x, y); 89 } 90 91 /** 92 * Change the position of the rectangle. 93 * 94 * @param newPos The new position of the rectangle. 95 */ SetPosition(const Vector2<T> & newPos)96 inline void SetPosition(const Vector2<T> &newPos){ 97 position = newPos; 98 } 99 100 /** 101 * Change the x position of the rectangle. 102 * 103 * @param x New X position. 104 */ SetPositionX(T x)105 inline void SetPositionX(T x){ 106 position.x = x; 107 } 108 109 /** 110 * Change the y position of the rectangle. 111 * 112 * @param y New Y position. 113 */ SetPositionY(T y)114 inline void SetPositionY(T y){ 115 position.y = y; 116 } 117 118 /** 119 * Set the size of the rectangle. 120 * 121 * @param sizeX new size among the x axe. 122 * @param sizeY new size among the y axe. 123 */ SetSize(T sizeX,T sizeY)124 inline void SetSize(T sizeX, T sizeY){ 125 size.SetValues(sizeX, sizeY); 126 } 127 128 /** 129 * Change the X size of the rectangle. 130 * 131 * @param x New size among x axe. 132 */ SetSizeX(T sizeX)133 inline void SetSizeX(T sizeX){ 134 size.x = sizeX; 135 } 136 137 /** 138 * Change the Y size of the rectangle. 139 * 140 * @param y New size among y axe. 141 */ SetSizeY(T sizeY)142 inline void SetSizeY(T sizeY){ 143 size.y = sizeY; 144 } 145 SetSize(Vector2<T> newSize)146 inline void SetSize(Vector2<T> newSize){ 147 size = newSize; 148 } 149 GetRectangle()150 inline rectangle<T> GetRectangle() const{ 151 return *this; 152 } 153 154 /** 155 * Return the position of the rectangle. 156 */ GetPosition()157 inline Vector2<T> GetPosition() const{ 158 return position; 159 } 160 GetPositionX()161 inline T GetPositionX() const{ 162 return position.x; 163 } 164 GetPositionY()165 inline T GetPositionY() const{ 166 return position.y; 167 } 168 169 /** 170 * Return the size of the rectangle. 171 */ GetSize()172 inline Vector2<T> GetSize() const{ 173 return size; 174 } 175 GetSizeX()176 inline T GetSizeX() const{ 177 return size.x; 178 } 179 GetSizeY()180 inline T GetSizeY() const{ 181 return size.y; 182 } 183 184 /** 185 * Clip the current rectangle using an other rectangle. 186 * 187 * @param cr The rectangle used for clipping 188 */ Clip(const rectangle & cr)189 void Clip(const rectangle &cr) { 190 if( IsSizeZero() || cr.IsSizeZero() ) { 191 size.x = 0; 192 size.y = 0; 193 return; 194 } 195 196 Vector2<T> r1BR = GetBottomRightPoint(); 197 Vector2<T> r2BR = cr.GetBottomRightPoint(); 198 Vector2<T> r1TL = GetTopLeftPoint(); 199 Vector2<T> r2TL = cr.GetTopLeftPoint(); 200 201 if (r1BR.x < r2TL.x || r1BR.y < r2TL.y || 202 r2BR.x < r1TL.x || r2BR.y < r1TL.y ) { 203 size.x = 0; 204 size.y = 0; 205 return; 206 } 207 208 position.x = std::max(r1TL.x, r2TL.x); 209 position.y = std::max(r1TL.y, r2TL.y); 210 size.x = std::min(r1BR.x, r2BR.x) - position.x + 1; 211 size.y = std::min(r1BR.y, r2BR.y) - position.y + 1; 212 } 213 214 /** 215 * Return true if the point p is contained in the rectangle. 216 * 217 * @param p Point used to perform the check. 218 */ Contains(const Vector2<T> p)219 inline bool Contains( const Vector2<T> p ) const{ 220 if( IsSizeZero() ) 221 return false; 222 223 return p >= GetTopLeftPoint() && 224 p <= GetBottomRightPoint(); 225 } 226 227 /** 228 * Return true if r2 is contained in the current rectangle. 229 * 230 * @param r2 The rectangle for witch the check if performed. 231 */ Contains(const rectangle<T> & r2)232 inline bool Contains( const rectangle<T> &r2 ) const{ 233 if( r2.IsSizeZero() ) 234 return false; 235 236 return Contains( r2.GetTopLeftPoint() ) && 237 Contains( r2.GetBottomRightPoint() ); 238 } 239 240 /** 241 * Return true if there is an intersection between the current rectangle 242 * and the r2 rectangle. 243 * 244 * @param r2 The second rectangle. 245 */ Intersect(const rectangle<T> & r2)246 inline bool Intersect( const rectangle<T> &r2 ) const{ 247 if( IsSizeZero() || r2.IsSizeZero() ) 248 return false; 249 250 Vector2<T> r1BR = GetBottomRightPoint(); 251 Vector2<T> r2BR = r2.GetBottomRightPoint(); 252 Vector2<T> r1TL = GetTopLeftPoint(); 253 Vector2<T> r2TL = r2.GetTopLeftPoint(); 254 255 if( r1BR.x < r2TL.x || r1BR.y < r2TL.y || 256 r2BR.x < r1TL.x || r2BR.y < r1TL.y ) 257 return false; 258 259 return true; 260 } 261 262 /** 263 * Return the point in the top left corner of the rectangle. 264 * 265 * If the rectangle has a size of zero, this point doesn't exist, 266 * so the program crash with a failled ASSERTion. 267 */ GetTopLeftPoint()268 inline Vector2<T> GetTopLeftPoint() const{ 269 ASSERT( !IsSizeZero() ); 270 return position; 271 } 272 273 /** 274 * Return the point in the top right corner of the rectangle. 275 * 276 * If the rectangle has a size of zero, this point doesn't exist, 277 * so the program crash with a failled ASSERTion. 278 */ GetTopRightPoint()279 inline Vector2<T> GetTopRightPoint() const{ 280 ASSERT( !IsSizeZero() ); 281 Vector2<T> r = position; 282 283 r.x += size.x - 1; 284 285 return r; 286 } 287 288 /** 289 * Return the point in the bottom left corner of the rectangle. 290 * 291 * If the rectangle has a size of zero, this point doesn't exist, 292 * so the program crash with a failled ASSERTion. 293 */ GetBottomLeftPoint()294 inline Vector2<T> GetBottomLeftPoint() const{ 295 ASSERT( !IsSizeZero() ); 296 Vector2<T> r = position; 297 298 r.y += size.y - 1; 299 300 return r; 301 } 302 303 /** 304 * Return the point in the top left corner of the rectangle. 305 * 306 * If the rectangle has a size of zero, this point doesn't exist, 307 * so the program crash with a failled ASSERTion. */ GetBottomRightPoint()308 inline Vector2<T> GetBottomRightPoint() const{ 309 ASSERT( !IsSizeZero() ); 310 return position + size - 1; 311 } 312 313 /** 314 * Return true if the rectangle has a size of zero. 315 */ IsSizeZero()316 inline bool IsSizeZero() const{ 317 return size.IsXNull() || size.IsYNull(); 318 } 319 320 inline bool operator==(const rectangle<T> &p2) const{ 321 return size==p2.size && position==p2.position; 322 } 323 }; 324 325 typedef rectangle<int> Rectanglei; 326 typedef rectangle<Double> Rectanglef; 327 typedef rectangle<Double> Rectangled; 328 #endif // _RECTANGLE_H 329