- Main Page
- Classes
- Files
- Directories
- Related Pages

# 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