glvector.h

00001 /*
00002 Copyright (c) 2000-2007 Lee Thomason (www.grinninglizard.com)
00003 Grinning Lizard Utilities.
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any 
00010 purpose, including commercial applications, and to alter it and 
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must 
00014 not claim that you wrote the original software. If you use this 
00015 software in a product, an acknowledgment in the product documentation 
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and 
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source 
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef GRINLIZ_VECTOR_INCLUDED
00027 #define GRINLIZ_VECTOR_INCLUDED
00028 
00029 #include <math.h>
00030 #include "gldebug.h"
00031 #include "glmath.h"
00032 #include "glutil.h"
00033 
00034 
00035 namespace grinliz {
00036 
00037 template< class T >
00038 struct Vector2
00039 {
00040         enum { COMPONENTS = 2 };
00041 
00042         T x;
00043         T y;
00044 
00045         T& X( int i )                   {       GLASSERT( InRange( i, 0, COMPONENTS-1 ));
00046                                                                 return *( &x + i ); }
00047         T  X( int i ) const             {       GLASSERT( InRange( i, 0, COMPONENTS-1 ));
00048                                                                 return *( &x + i ); }
00049 
00050         void Add( const Vector2<T>& vec ) {
00051                 x += vec.x;
00052                 y += vec.y;
00053         }
00054 
00055         void Subtract( const Vector2<T>& vec ) {
00056                 x -= vec.x;
00057                 y -= vec.y;
00058         }
00059 
00060         void Multiply( T scalar ) {
00061                 x *= scalar;
00062                 y *= scalar;
00063         }
00064 
00065         friend Vector2<T> operator-( const Vector2<T>& head, const Vector2<T>& tail ) {
00066                 Vector2<T> vec = {
00067                         vec.x = head.x - tail.x,
00068                         vec.y = head.y - tail.y,
00069                 };
00070                 return vec;
00071         }
00072 
00073         friend Vector2<T> operator+( const Vector2<T>& head, const Vector2<T>& tail ) {
00074                 Vector2<T> vec = {
00075                         vec.x = head.x + tail.x,
00076                         vec.y = head.y + tail.y,
00077                 };
00078                 return vec;
00079         }
00080                 
00081         friend Vector2<T> operator*( Vector2<T> head, T scalar ) { head.Multiply( scalar ); return head; }
00082         friend Vector2<T> operator*( T scalar, Vector2<T> head ) { head.Multiply( scalar ); return head; }
00083 
00084         void operator+=( const Vector2<T>& vec )                { Add( vec ); }
00085         void operator-=( const Vector2<T>& vec )                { Subtract( vec ); }
00086         bool operator==( const Vector2<T>& rhs ) const  { return (x == rhs.x) && (y == rhs.y); }
00087         bool operator!=( const Vector2<T>& rhs ) const  { return (x != rhs.x) || (y != rhs.y); }
00088 
00089         friend bool Equal( const Vector2<T>& a, const Vector2<T>& b, T epsilon ) {
00090                 return ( Equal( a.x, b.x, epsilon ) && Equal( a.y, b.y, epsilon ) );
00091         }
00092 
00093         int Compare( const Vector2<T>& r, T epsilon ) const
00094         {
00095                 if ( Equal( this->x, r.x, epsilon ) ) {
00096                         if ( Equal( this->y, r.y, epsilon ) ) {
00097                                 return 0;
00098                         }
00099                         else if ( this->y < r.y ) return -1;
00100                         else                                      return 1;
00101                 }
00102                 else if ( this->x < r.x ) return -1;
00103                 else                                      return 1;
00104         }       
00105 
00106         void Set( T _x, T _y ) {
00107                 this->x = _x;
00108                 this->y = _y;
00109         }
00110         void Zero() {
00111                 x = (T)0;
00112                 y = (T)0;
00113         }
00114 
00115         T Length() const { return grinliz::Length( x, y ); };
00116 
00117         friend T Length( const Vector2<T>& a, const Vector2<T>& b ) {
00118                 return grinliz::Length( a.x-b.x, a.y-b.y );
00119         }
00120 
00121         void Normalize()        
00122         { 
00123                 T lenInv = static_cast<T>(1) / grinliz::Length( x, y );
00124                 x *= lenInv; y *= lenInv;
00125                 #ifdef DEBUG
00126                 float len = x*x + y*y;
00127                 GLASSERT( len > .9999f && len < 1.0001f );
00128                 #endif
00129         }
00130 
00131         void RotatePos90()
00132         {
00133                 T a = x;
00134                 T b = y;
00135                 x = -b;
00136                 y = a;
00137         }
00138         void RotateNeg90()
00139         {
00140                 T a = x;
00141                 T b = y;
00142                 x = b;
00143                 y = -a;
00144         }
00145 };
00146 
00147 typedef Vector2< int > Vector2I;
00148 typedef Vector2< float > Vector2F;
00149 
00150 
00151 inline void DegreeToVector( float degree, Vector2<float>* vec )
00152 {
00153         float rad = ToRadian( degree );
00154         vec->x = cosf( rad );
00155         vec->y = sinf( rad );
00156 }
00157 
00158 
00159 template< class T >
00160 struct Line2
00161 {
00162         Vector2<T>      n;      // normal
00163         T                       d;              // offset
00164 
00165         T EvaluateX( T y )              { return ( -d - y*n.y ) / n.x; }
00166         T EvaluateY( T x )              { return ( -d - x*n.x ) / n.y; }
00167 };
00168 
00169 typedef Line2< float > Line2F;
00170 
00171 
00172 
00173 template< class T >
00174 struct Vector3
00175 {
00176         enum { COMPONENTS = 3 };
00177 
00178         T x;
00179         T y;
00180         T z;
00181 
00182         // I avoid non-const references - but this one is just so handy! And, in
00183         // use in the code, it is clear it is an assignment.
00184         T& X( int i )                   {       GLASSERT( InRange( i, 0, COMPONENTS-1 ));
00185                                                                 return *( &x + i ); }
00186         T  X( int i ) const             {       GLASSERT( InRange( i, 0, COMPONENTS-1 ));
00187                                                                 return *( &x + i ); }
00188 
00189         void Add( const Vector3<T>& vec ) {
00190                 x += vec.x;
00191                 y += vec.y;
00192                 z += vec.z;
00193         }
00194 
00195         friend void Add( const Vector3<T>& a, const Vector3<T>& b, Vector3<T>* c )
00196         {
00197                 c->x = a.x + b.x;
00198                 c->y = a.y + b.y;
00199                 c->z = a.z + b.z;
00200         }
00201 
00202         void Subtract( const Vector3<T>& vec ) {
00203                 x -= vec.x;
00204                 y -= vec.y;
00205                 z -= vec.z;
00206         }
00207 
00208         void Multiply( T scalar ) {
00209                 x *= scalar;
00210                 y *= scalar;
00211                 z *= scalar;
00212         }
00213 
00214         friend Vector3<T> operator-( const Vector3<T>& head, const Vector3<T>& tail ) {
00215                 Vector3<T> vec = {
00216                         vec.x = head.x - tail.x,
00217                         vec.y = head.y - tail.y,
00218                         vec.z = head.z - tail.z
00219                 };
00220                 return vec;
00221         }
00222 
00223         friend Vector3<T> operator+( const Vector3<T>& head, const Vector3<T>& tail ) {
00224                 Vector3<T> vec = {
00225                         vec.x = head.x + tail.x,
00226                         vec.y = head.y + tail.y,
00227                         vec.z = head.z + tail.z,
00228                 };
00229                 return vec;
00230         }
00231         
00232         friend Vector3<T> operator*( Vector3<T> head, T scalar ) { head.Multiply( scalar ); return head; }
00233         friend Vector3<T> operator*( T scalar, Vector3<T> head ) { head.Multiply( scalar ); return head; }
00234 
00235         Vector3<T> operator-() const {
00236                 Vector3<T> vec = { -x, -y, -z };
00237                 return vec;
00238         }
00239 
00240         void operator+=( const Vector3<T>& vec )                { Add( vec ); }
00241         void operator-=( const Vector3<T>& vec )                { Subtract( vec ); }
00242         bool operator==( const Vector3<T>& rhs ) const  { return x == rhs.x && y == rhs.y && z == rhs.z; }
00243         bool operator!=( const Vector3<T>& rhs ) const  { return x != rhs.x || y != rhs.y || z != rhs.z; }
00244 
00245         friend bool Equal( const Vector3<T>& a, const Vector3<T>& b, T epsilon ) {
00246                 return ( Equal( a.x, b.x, epsilon ) && Equal( a.y, b.y, epsilon ) && Equal( a.z, b.z, epsilon ) );
00247         }
00248 
00249         int Compare( const Vector3<T>& r, T epsilon ) const
00250         {
00251                 if ( Equal( this->x, r.x, epsilon ) ) {
00252                         if ( Equal( this->y, r.y, epsilon ) ) {
00253                                 if ( Equal( this->z, r.z, epsilon ) ) {
00254                                         return 0;
00255                                 }
00256                                 else if ( this->z < r.z ) return -1;
00257                                 else                                      return 1;
00258                         }
00259                         else if ( this->y < r.y ) return -1;
00260                         else                                      return 1;
00261                 }
00262                 else if ( this->x < r.x ) return -1;
00263                 else                                      return 1;
00264         }
00265 
00266         void Set( T _x, T _y, T _z ) {
00267                 this->x = _x;
00268                 this->y = _y;
00269                 this->z = _z;
00270         }
00271 
00272         void Zero() {
00273                 x = (T)0;
00274                 y = (T)0;
00275                 z = (T)0;
00276         }
00277 
00278         void Normalize()        
00279         { 
00280                 GLASSERT( grinliz::Length( x, y, z ) > 0.001f );
00281                 T lenInv = static_cast<T>(1) / grinliz::Length( x, y, z );
00282                 x *= lenInv; 
00283                 y *= lenInv;
00284                 z *= lenInv;
00285                 #ifdef DEBUG
00286                 T len = x*x + y*y + z*z;
00287                 GLASSERT( len > (T)(.9999) && len < (T)(1.0001) );
00288                 #endif
00289         }
00290 
00291         T Length() const { return grinliz::Length( x, y, z ); };
00292 
00293         friend T Length( const Vector3<T>& a, const Vector3<T>& b ) {
00294                 return grinliz::Length( a.x-b.x, a.y-b.y, a.z-b.z );
00295         }
00296 
00297         #ifdef DEBUG
00298         void Dump( const char* name ) const
00299         {
00300                 GLOUTPUT(( "Vec%4s: %6.2f %6.2f %6.2f\n", name, (float)x, (float)y, (float)z ));
00301         }
00302         #endif
00303 };
00304 
00305 inline void DegreeToVector( float degree, Vector3<float>* vec )
00306 {
00307         Vector2<float> v;
00308         DegreeToVector( degree, &v );
00309         vec->Set( v.x, v.y, 0.0f );
00310 }
00311 
00312 template< class T >
00313 inline void Convert( const Vector3<T>& v3, Vector2<T>* v2 )
00314 {
00315         v2->x = v3.x;
00316         v2->y = v3.y;
00317 }
00318 
00319 
00320 typedef Vector3< int > Vector3I;
00321 typedef Vector3< float > Vector3F;
00322 
00323 
00324 struct Vector4F
00325 {
00326         float x, y, z, w;
00327 
00328         void operator+=( const Vector4F& rhs )  { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; }
00329 };
00330 
00331 
00332 
00333 };      // namespace grinliz
00334 
00335 #endif

Generated on Fri Mar 23 19:36:21 2007 for Lilith3D by  doxygen 1.5.1-p1