glvector.h

00001 /*
00002 Copyright (c) 2000-2003 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         void Subtract( const Vector3<T>& vec ) {
00196                 x -= vec.x;
00197                 y -= vec.y;
00198                 z -= vec.z;
00199         }
00200 
00201         void Multiply( T scalar ) {
00202                 x *= scalar;
00203                 y *= scalar;
00204                 z *= scalar;
00205         }
00206 
00207         friend Vector3<T> operator-( const Vector3<T>& head, const Vector3<T>& tail ) {
00208                 Vector3<T> vec = {
00209                         vec.x = head.x - tail.x,
00210                         vec.y = head.y - tail.y,
00211                         vec.z = head.z - tail.z
00212                 };
00213                 return vec;
00214         }
00215 
00216         friend Vector3<T> operator+( const Vector3<T>& head, const Vector3<T>& tail ) {
00217                 Vector3<T> vec = {
00218                         vec.x = head.x + tail.x,
00219                         vec.y = head.y + tail.y,
00220                         vec.z = head.z + tail.z,
00221                 };
00222                 return vec;
00223         }
00224         
00225         friend Vector3<T> operator*( Vector3<T> head, T scalar ) { head.Multiply( scalar ); return head; }
00226         friend Vector3<T> operator*( T scalar, Vector3<T> head ) { head.Multiply( scalar ); return head; }
00227 
00228         void operator+=( const Vector3<T>& vec )                { Add( vec ); }
00229         void operator-=( const Vector3<T>& vec )                { Subtract( vec ); }
00230         bool operator==( const Vector3<T>& rhs ) const  { return x == rhs.x && y == rhs.y && z == rhs.z; }
00231         bool operator!=( const Vector3<T>& rhs ) const  { return x != rhs.x || y != rhs.y || z != rhs.z; }
00232 
00233         friend bool Equal( const Vector3<T>& a, const Vector3<T>& b, T epsilon ) {
00234                 return ( Equal( a.x, b.x, epsilon ) && Equal( a.y, b.y, epsilon ) && Equal( a.z, b.z, epsilon ) );
00235         }
00236 
00237         int Compare( const Vector3<T>& r, T epsilon ) const
00238         {
00239                 if ( Equal( this->x, r.x, epsilon ) ) {
00240                         if ( Equal( this->y, r.y, epsilon ) ) {
00241                                 if ( Equal( this->z, r.z, epsilon ) ) {
00242                                         return 0;
00243                                 }
00244                                 else if ( this->z < r.z ) return -1;
00245                                 else                                      return 1;
00246                         }
00247                         else if ( this->y < r.y ) return -1;
00248                         else                                      return 1;
00249                 }
00250                 else if ( this->x < r.x ) return -1;
00251                 else                                      return 1;
00252         }
00253 
00254         void Set( T x, T y, T z ) {
00255                 this->x = x;
00256                 this->y = y;
00257                 this->z = z;
00258         }
00259 
00260         void Zero() {
00261                 x = (T)0;
00262                 y = (T)0;
00263                 z = (T)0;
00264         }
00265 
00266         void Normalize()        
00267         { 
00268                 GLASSERT( grinliz::Length( x, y, z ) > 0.001f );
00269                 T lenInv = static_cast<T>(1) / grinliz::Length( x, y, z );
00270                 x *= lenInv; 
00271                 y *= lenInv;
00272                 z *= lenInv;
00273                 #ifdef DEBUG
00274                 T len = x*x + y*y + z*z;
00275                 GLASSERT( len > (T)(.9999) && len < (T)(1.0001) );
00276                 #endif
00277         }
00278 
00279         T Length() const { return grinliz::Length( x, y, z ); };
00280 
00281         friend T Length( const Vector3<T>& a, const Vector3<T>& b ) {
00282                 return grinliz::Length( a.x-b.x, a.y-b.y, a.z-b.z );
00283         }
00284 
00285         #ifdef DEBUG
00286         void Dump( const char* name ) const
00287         {
00288                 GLOUTPUT(( "Vec%4s: %6.2f %6.2f %6.2f\n", name, (float)x, (float)y, (float)z ));
00289         }
00290         #endif
00291 };
00292 
00293 template< class T >
00294 inline void Convert( const Vector3<T>& v3, Vector2<T>* v2 )
00295 {
00296         v2->x = v3.x;
00297         v2->y = v3.y;
00298 }
00299 
00300 
00301 typedef Vector3< int > Vector3I;
00302 typedef Vector3< float > Vector3F;
00303 
00304 
00305 struct Vector4F
00306 {
00307         float x, y, z, w;
00308 
00309         void operator+=( const Vector4F& rhs )  { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; }
00310 };
00311 
00312 };      // namespace grinliz
00313 
00314 
00315 #endif

Generated on Thu Jul 20 20:45:32 2006 for Kyra by  doxygen 1.4.7