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 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 };
00313
00314
00315 #endif