00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef GRINLIZ_RECTANGLE_INCLUDED
00027 #define GRINLIZ_RECTANGLE_INCLUDED
00028
00029 #include <limits.h>
00030 #include "glvector.h"
00031
00032 namespace grinliz {
00033
00036 template< class T >
00037 struct Rectangle2
00038 {
00039 Vector2< T > min;
00040 Vector2< T > max;
00041
00043 void Set( T _xmin, T _ymin, T _xmax, T _ymax ) {
00044 min.x = _xmin; min.y = _ymin; max.x = _xmax; max.y = _ymax;
00045 }
00047 void Zero() {
00048 min.x = min.y = max.x = max.y = (T) 0;
00049 }
00050
00054 void FromPair( T x0, T y0, T x1, T y1 )
00055 {
00056 min.x = grinliz::Min( x0, x1 );
00057 max.x = grinliz::Max( x0, x1 );
00058 min.y = grinliz::Min( y0, y1 );
00059 max.y = grinliz::Max( y0, y1 );
00060 }
00061
00063 bool Intersect( const Rectangle2<T>& rect ) const
00064 {
00065 if ( rect.max.x < min.x
00066 || rect.min.x > max.x
00067 || rect.max.y < min.y
00068 || rect.min.y > max.y )
00069 {
00070 return false;
00071 }
00072 return true;
00073 }
00074
00075 bool Intersect( const Vector2<T>& point ) const
00076 {
00077 if ( point.x < min.x
00078 || point.x > max.x
00079 || point.y < min.y
00080 || point.y > max.y )
00081 {
00082 return false;
00083 }
00084 return true;
00085 }
00086
00087 bool Intersect( T x, T y ) const
00088 {
00089 if ( x < min.x
00090 || x > max.x
00091 || y < min.y
00092 || y > max.y )
00093 {
00094 return false;
00095 }
00096 return true;
00097 }
00098
00099
00101 bool Contains( const Rectangle2<T>& rect ) const
00102 {
00103 if ( rect.min.x >= min.x
00104 && rect.max.x <= max.x
00105 && rect.min.y >= min.y
00106 && rect.max.y <= max.y )
00107 {
00108 return true;
00109 }
00110 return false;
00111 }
00112
00113 bool Contains( const Vector2<T>& point ) const
00114 {
00115 if ( point.x >= min.x
00116 && point.x <= max.x
00117 && point.y >= min.y
00118 && point.y <= max.y )
00119 {
00120 return true;
00121 }
00122 return false;
00123 }
00124
00126 void DoUnion( const Rectangle2<T>& rect )
00127 {
00128 min.x = grinliz::Min( min.x, rect.min.x );
00129 max.x = grinliz::Max( max.x, rect.max.x );
00130 min.y = grinliz::Min( min.y, rect.min.y );
00131 max.y = grinliz::Max( max.y, rect.max.y );
00132 }
00133
00135 void DoUnion( T x, T y )
00136 {
00137 min.x = grinliz::Min( min.x, x );
00138 max.x = grinliz::Max( max.x, x );
00139 min.y = grinliz::Min( min.y, y );
00140 max.y = grinliz::Max( max.y, y );
00141 }
00142
00144 void DoIntersection( const Rectangle2<T>& rect )
00145 {
00146 min.x = grinliz::Max( min.x, rect.min.x );
00147 max.x = grinliz::Min( max.x, rect.max.x );
00148 min.y = grinliz::Max( min.y, rect.min.y );
00149 max.y = grinliz::Min( max.y, rect.max.y );
00150 }
00151
00153 void DoClip( const Rectangle2<T>& rect )
00154 {
00155 min.x = rect.min.x > min.x ? rect.min.x : min.x;
00156 max.x = rect.max.x < max.x ? rect.max.x : max.x;
00157 min.y = rect.min.y > min.y ? rect.min.y : min.y;
00158 max.y = rect.max.y < max.y ? rect.max.y : max.y;
00159 }
00160
00161
00163 void Scale( T x, T y )
00164 {
00165 min.x = ( x * min.x );
00166 min.y = ( y * min.y );
00167 max.x = ( x * max.x );
00168 max.y = ( y * max.y );
00169 }
00170
00172 void EdgeAdd( T i )
00173 {
00174 min.x -= i;
00175 max.x += i;
00176 min.y -= i;
00177 max.y += i;
00178 }
00179
00181 void Edge( int i, Vector2< T >* head, Vector2< T >* tail )
00182 {
00183 switch ( i ) {
00184 case 0: tail->Set( min.x, min.y ); head->Set( max.x, min.y ); break;
00185 case 1: tail->Set( max.x, min.y ); head->Set( max.x, max.y ); break;
00186 case 2: tail->Set( max.x, max.y ); head->Set( min.x, max.y ); break;
00187 case 3: tail->Set( min.x, max.y ); head->Set( min.x, min.y ); break;
00188 default: GLASSERT( 0 );
00189 }
00190 }
00191
00192 bool operator==( const Rectangle2<T>& that ) const { return ( min.x == that.min.x )
00193 && ( max.x == that.max.x )
00194 && ( min.y == that.min.y )
00195 && ( max.y == that.max.y ); }
00196 bool operator!=( const Rectangle2<T>& that ) const { return ( min.x != that.min.x )
00197 || ( max.x != that.max.x )
00198 || ( min.y != that.min.y )
00199 || ( max.y != that.max.y ); }
00200
00201 };
00202
00203
00204 struct Rectangle2I : public Rectangle2< int >
00205 {
00206 enum { INVALID = INT_MIN };
00207
00208 int Width() const { return max.x - min.x + 1; }
00209 int Height() const { return max.y - min.y + 1; }
00210 int Area() const { return Width() * Height(); }
00211
00213 void SetInvalid() { min.x = INVALID + 1; max.x = INVALID; min.y = INVALID + 1; max.y = INVALID; }
00214
00216 bool IsValid() const {
00217 return ( min.x <= max.x ) && ( min.y <= max.y );
00218 }
00219
00221 void DoUnionV( int x, int y )
00222 {
00223 if ( !IsValid() ) {
00224 min.x = max.x = x;
00225 min.y = max.y = y;
00226 }
00227 else {
00228 min.x = Min( min.x, x );
00229 max.x = Max( max.x, x );
00230 min.y = Min( min.y, y );
00231 max.y = Max( max.y, y );
00232 }
00233 }
00234 };
00235
00236 struct Rectangle2F : public Rectangle2< float >
00237 {
00238 float Width() const { return max.x - min.x; }
00239 float Height() const { return max.y - min.y; }
00240 float Area() const { return Width() * Height(); }
00241 };
00242
00243
00244 template< class T >
00245 struct Rectangle3
00246 {
00247 Vector3< T > min;
00248 Vector3< T > max;
00249
00251 const Vector3< T >& Vec( int i ) { return (i==0) ? min : max; }
00252
00254 void Set( T _xmin, T _ymin, T _zmin, T _xmax, T _ymax, T _zmax ) {
00255 min.x = _xmin; min.y = _ymin; min.z = _zmin;
00256 max.x = _xmax; max.y = _ymax; max.z = _zmax;
00257 }
00259 void Zero() {
00260 min.x = min.y = max.x = max.y = min.z = max.z = (T) 0;
00261 }
00262
00264 bool Intersect( const Rectangle3<T>& rect ) const
00265 {
00266 if ( rect.max.x < min.x
00267 || rect.min.x > max.x
00268 || rect.max.y < min.y
00269 || rect.min.y > max.y
00270 || rect.max.z < min.z
00271 || rect.min.z > max.z )
00272 {
00273 return false;
00274 }
00275 return true;
00276 }
00277
00278 bool Intersect( const Vector3<T>& point ) const
00279 {
00280 if ( point.x < min.x
00281 || point.x > max.x
00282 || point.y < min.y
00283 || point.y > max.y
00284 || point.z < min.z
00285 || point.z > max.z )
00286 {
00287 return false;
00288 }
00289 return true;
00290 }
00291
00292 bool Intersect( T x, T y, T z ) const
00293 {
00294 if ( x < min.x
00295 || x > max.x
00296 || y < min.y
00297 || y > max.y
00298 || z < min.z
00299 || z > max.z )
00300 {
00301 return false;
00302 }
00303 return true;
00304 }
00305
00306
00308 bool Contains( const Rectangle3<T>& rect ) const
00309 {
00310 if ( rect.min.x >= min.x
00311 && rect.max.x <= max.x
00312 && rect.min.y >= min.y
00313 && rect.max.y <= max.y
00314 && rect.min.z >= min.z
00315 && rect.max.z <= max.z )
00316 {
00317 return true;
00318 }
00319 return false;
00320 }
00321
00322 bool Contains( const Vector3<T>& point ) const
00323 {
00324 if ( point.x >= min.x
00325 && point.x <= max.x
00326 && point.y >= min.y
00327 && point.y <= max.y
00328 && point.z >= min.z
00329 && point.z <= max.z )
00330 {
00331 return true;
00332 }
00333 return false;
00334 }
00335
00337 void DoUnion( const Rectangle3<T>& rect )
00338 {
00339 min.x = grinliz::Min( min.x, rect.min.x );
00340 max.x = grinliz::Max( max.x, rect.max.x );
00341 min.y = grinliz::Min( min.y, rect.min.y );
00342 max.y = grinliz::Max( max.y, rect.max.y );
00343 min.z = grinliz::Min( min.z, rect.min.z );
00344 max.z = grinliz::Max( max.z, rect.max.z );
00345 }
00346
00348 void DoUnion( const Vector3<T>& vec )
00349 {
00350 min.x = grinliz::Min( min.x, vec.x );
00351 max.x = grinliz::Max( max.x, vec.x );
00352 min.y = grinliz::Min( min.y, vec.y );
00353 max.y = grinliz::Max( max.y, vec.y );
00354 min.z = grinliz::Min( min.z, vec.z );
00355 max.z = grinliz::Max( max.z, vec.z );
00356 }
00357
00359 void DoIntersection( const Rectangle2<T>& rect )
00360 {
00361 min.x = grinliz::Max( min.x, rect.min.x );
00362 max.x = grinliz::Min( max.x, rect.max.x );
00363 min.y = grinliz::Max( min.y, rect.min.y );
00364 max.y = grinliz::Min( max.y, rect.max.y );
00365 min.z = grinliz::Max( min.z, rect.min.z );
00366 max.z = grinliz::Min( max.z, rect.max.z );
00367 }
00368
00370 void DoClip( const Rectangle3<T>& rect )
00371 {
00372 min.x = rect.min.x > min.x ? rect.min.x : min.x;
00373 max.x = rect.max.x < max.x ? rect.max.x : max.x;
00374 min.y = rect.min.y > min.y ? rect.min.y : min.y;
00375 max.y = rect.max.y < max.y ? rect.max.y : max.y;
00376 min.z = rect.min.z > min.z ? rect.min.z : min.z;
00377 max.z = rect.max.z < max.z ? rect.max.z : max.z;
00378 }
00379
00380
00382 void Scale( T x, T y, T z )
00383 {
00384 min.x = ( x * min.x );
00385 max.x = ( x * max.x );
00386 min.y = ( y * min.y );
00387 max.y = ( y * max.y );
00388 min.z = ( z * min.z );
00389 max.z = ( z * max.z );
00390 }
00391
00393 void EdgeAdd( T i )
00394 {
00395 min.x -= i;
00396 max.x += i;
00397 min.y -= i;
00398 max.y += i;
00399 min.z -= i;
00400 max.z += i;
00401 }
00402
00403 bool operator==( const Rectangle2<T>& that ) const { return ( min.x == that.min.x )
00404 && ( max.x == that.max.x )
00405 && ( min.y == that.min.y )
00406 && ( max.y == that.max.y )
00407 && ( min.z == that.min.z )
00408 && ( max.z == that.max.z ); }
00409 bool operator!=( const Rectangle2<T>& that ) const { return ( min.x != that.min.x )
00410 || ( max.x != that.max.x )
00411 || ( min.y != that.min.y )
00412 || ( max.y != that.max.y )
00413 || ( min.z != that.min.z )
00414 || ( max.z != that.max.z ); }
00415
00416 };
00417
00418
00419
00420 struct Rectangle3I : public Rectangle3< int >
00421 {
00422 enum { INVALID = INT_MIN };
00423
00424 int SizeX() const { return max.x - min.x + 1; }
00425 int SizeY() const { return max.y - min.y + 1; }
00426 int SizeZ() const { return max.z - min.z + 1; }
00427 int Volume() const { return SizeX() * SizeY() * SizeZ(); }
00428 int Size( int i ) const { return max.X(i) - min.X(i) + 1; }
00429 #ifdef DEBUG
00430 void Dump() { GLOUTPUT(( "(%d,%d,%d)-(%d,%d,%d)", min.x, min.y, min.z, max.x, max.y, max.z )); }
00431 #endif
00432 };
00433
00434
00435 struct Rectangle3F : public Rectangle3< float >
00436 {
00437 float SizeX() const { return max.x - min.x; }
00438 float SizeY() const { return max.y - min.y; }
00439 float SizeZ() const { return max.z - min.z; }
00440 float Volume()const { return SizeX() * SizeY() * SizeZ(); }
00441 float Size( int i ) const { return max.X(i) - min.X(i); }
00442
00443 #ifdef DEBUG
00444 void Dump() {
00445 GLOUTPUT(( "(%.1f,%.1f,%.1f)-(%.1f,%.1f,%.1f)", min.x, min.y, min.z, max.x, max.y, max.z ));
00446 }
00447 #endif
00448 };
00449
00450
00451 };
00452
00453
00454
00455 #endif
00456