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_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;
00163 T d;
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
00183
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 };
00334
00335 #endif