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
00027
00028 #pragma once
00029
00030 #include <cmath>
00031 #include <cstring>
00032 #include <iostream>
00033 #include <cassert>
00034 #include <limits>
00035
00036 #include "cinder/CinderMath.h"
00037
00038 namespace cinder {
00039
00041 template<typename T>
00042 struct VECTRAIT {
00043 typedef float DIST;
00044 };
00045
00046 template<>
00047 struct VECTRAIT<double> {
00048 typedef double DIST;
00049 };
00050
00051 template<>
00052 struct VECTRAIT<int32_t> {
00053 typedef float DIST;
00054 };
00055
00056 template<typename T, typename Y>
00057 struct VEC3CONV {
00058 static T getX( const Y &v ) { return static_cast<T>( v.x ); }
00059 static T getY( const Y &v ) { return static_cast<T>( v.y ); }
00060 static T getZ( const Y &v ) { return static_cast<T>( v.z ); }
00061 };
00062
00064
00065 template<typename T> class Vec3;
00066
00067 template<typename T>
00068 class Vec2
00069 {
00070 public:
00071 T x,y;
00072
00073 typedef T TYPE;
00074 typedef T value_type;
00075 typedef typename VECTRAIT<T>::DIST DIST;
00076 static const int DIM = 2;
00077
00078 Vec2() :x(0), y(0) {}
00079 Vec2( T nx, T ny ) : x( nx ), y( ny ) {}
00080 Vec2( const Vec2<T>& src ) : x( src.x ), y( src.y ) {}
00081 explicit Vec2( const T *d ) : x( d[0] ), y( d[1] ) {}
00082
00083 template<typename FromT>
00084 Vec2( const Vec2<FromT>& src )
00085 : x( static_cast<T>( src.x ) ),y( static_cast<T>( src.y ) )
00086 {}
00087
00088 void set( T ax, T ay )
00089 {
00090 x = ax; y = ay;
00091 }
00092
00093 void set( const Vec2<T> &rhs )
00094 {
00095 x = rhs.x; y = rhs.y;
00096 }
00097
00098
00099 template<typename FromT>
00100 Vec2<T>& operator=( const Vec2<FromT>& rhs )
00101 {
00102 x = static_cast<T>( rhs.x );
00103 y = static_cast<T>( rhs.y );
00104 return * this;
00105 }
00106
00107 Vec2<T>& operator=( const Vec2<T>& rhs )
00108 {
00109 x = rhs.x;
00110 y = rhs.y;
00111 return * this;
00112 }
00113
00114 T& operator[]( int n )
00115 {
00116 assert( n >= 0 && n <= 1 );
00117 return (&x)[n];
00118 }
00119
00120 const T& operator[]( int n ) const
00121 {
00122 assert( n >= 0 && n <= 1 );
00123 return (&x)[n];
00124 }
00125
00126 T* ptr() const { return &(const_cast<Vec2*>( this )->x); }
00127
00128 const Vec2<T> operator+( const Vec2<T>& rhs ) const { return Vec2<T>( x + rhs.x, y + rhs.y ); }
00129 const Vec2<T> operator-( const Vec2<T>& rhs ) const { return Vec2<T>( x - rhs.x, y - rhs.y ); }
00130 const Vec2<T> operator*( const Vec2<T>& rhs ) const { return Vec2<T>( x * rhs.x, y * rhs.y ); }
00131 const Vec2<T> operator/( const Vec2<T>& rhs ) const { return Vec2<T>( x / rhs.x, y / rhs.y ); }
00132 Vec2<T>& operator+=( const Vec2<T>& rhs ) { x += rhs.x; y += rhs.y; return *this; }
00133 Vec2<T>& operator-=( const Vec2<T>& rhs ) { x -= rhs.x; y -= rhs.y; return *this; }
00134 Vec2<T>& operator*=( const Vec2<T>& rhs ) { x *= rhs.x; y *= rhs.y; return *this; }
00135 Vec2<T>& operator/=( const Vec2<T>& rhs ) { x /= rhs.x; y /= rhs.y; return *this; }
00136 const Vec2<T> operator/( T rhs ) const { return Vec2<T>( x / rhs, y / rhs ); }
00137 Vec2<T>& operator+=( T rhs ) { x += rhs; y += rhs; return *this; }
00138 Vec2<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; return *this; }
00139 Vec2<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; return *this; }
00140 Vec2<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; return *this; }
00141
00142 Vec2<T> operator-() const { return Vec2<T>( -x, -y ); }
00143
00144 bool operator==( const Vec2<T> &rhs ) const
00145 {
00146 return ( x == rhs.x ) && ( y == rhs.y );
00147 }
00148
00149 bool operator!=( const Vec2<T> &rhs ) const
00150 {
00151 return ! ( *this == rhs );
00152 }
00153
00154 T dot( const Vec2<T> &rhs ) const
00155 {
00156 return x * rhs.x + y * rhs.y;
00157 }
00158
00160 T cross( const Vec2<T> &rhs ) const
00161 {
00162 return x * rhs.y - y * rhs.x;
00163 }
00164
00165 DIST distance( const Vec2<T> &rhs ) const
00166 {
00167 return ( *this - rhs ).length();
00168 }
00169
00170 T distanceSquared( const Vec2<T> &rhs ) const
00171 {
00172 return ( *this - rhs ).lengthSquared();
00173 }
00174
00175 DIST length() const
00176 {
00177 return math<DIST>::sqrt( x*x + y*y );
00178 }
00179
00180 void normalize()
00181 {
00182 DIST invS = 1 / length();
00183 x *= invS;
00184 y *= invS;
00185 }
00186
00187 Vec2<T> normalized() const
00188 {
00189 DIST invS = 1 / length();
00190 return Vec2<T>( x * invS, y * invS );
00191 }
00192
00193
00194 void safeNormalize()
00195 {
00196 T s = lengthSquared();
00197 if( s > 0 ) {
00198 DIST invL = 1 / math<DIST>::sqrt( s );
00199 x *= invL;
00200 y *= invL;
00201 }
00202 }
00203
00204 Vec2<T> safeNormalized() const
00205 {
00206 T s = lengthSquared();
00207 if( s > 0 ) {
00208 DIST invL = 1 / math<DIST>::sqrt( s );
00209 return Vec2<T>( x * invL, y * invL );
00210 }
00211 else
00212 return Vec2<T>::zero();
00213 }
00214
00215 void rotate( DIST radians )
00216 {
00217 T cosa = math<T>::cos( radians );
00218 T sina = math<T>::sin( radians );
00219 T rx = x * cosa - y * sina;
00220 y = x * sina + y * cosa;
00221 x = rx;
00222 }
00223
00224 T lengthSquared() const
00225 {
00226 return x * x + y * y;
00227 }
00228
00230 void limit( DIST maxLength )
00231 {
00232 T lengthSquared = x * x + y * y;
00233
00234 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) {
00235 DIST ratio = maxLength / math<DIST>::sqrt( lengthSquared );
00236 x *= ratio;
00237 y *= ratio;
00238 }
00239 }
00240
00242 Vec2<T> limited( T maxLength ) const
00243 {
00244 T lengthSquared = x * x + y * y;
00245
00246 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) {
00247 DIST ratio = maxLength / math<DIST>::sqrt( lengthSquared );
00248 return Vec2<T>( x * ratio, y * ratio );
00249 }
00250 else
00251 return *this;
00252 }
00253
00254 void invert()
00255 {
00256 x = -x;
00257 y = -y;
00258 }
00259
00260 Vec2<T> inverse() const
00261 {
00262 return Vec2<T>( -x, -y );
00263 }
00264
00265 Vec2<T> lerp( T fact, const Vec2<T>& r ) const
00266 {
00267 return (*this) + ( r - (*this) ) * fact;
00268 }
00269
00270 void lerpEq( T fact, const Vec2<T> &rhs )
00271 {
00272 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact;
00273 }
00274
00275
00276 Vec2<T> xx() const { return Vec2<T>(x, x); }
00277 Vec2<T> xy() const { return Vec2<T>(x, y); }
00278 Vec2<T> yx() const { return Vec2<T>(y, x); }
00279 Vec2<T> yy() const { return Vec2<T>(y, y); }
00280
00281 Vec3<T> xxx() const { return Vec3<T>(x, x, x); }
00282 Vec3<T> xxy() const { return Vec3<T>(x, x, y); }
00283 Vec3<T> xyx() const { return Vec3<T>(x, y, x); }
00284 Vec3<T> xyy() const { return Vec3<T>(x, y, y); }
00285 Vec3<T> yxx() const { return Vec3<T>(y, x, x); }
00286 Vec3<T> yxy() const { return Vec3<T>(y, x, y); }
00287 Vec3<T> yyx() const { return Vec3<T>(y, y, x); }
00288 Vec3<T> yyy() const { return Vec3<T>(y, y, y); }
00289
00290 static Vec2<T> max()
00291 {
00292 return Vec2<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00293 }
00294
00295 static Vec2<T> zero()
00296 {
00297 return Vec2<T>( 0, 0 );
00298 }
00299
00300 static Vec2<T> one()
00301 {
00302 return Vec2<T>( 1, 1 );
00303 }
00304
00305 friend std::ostream& operator<<( std::ostream& lhs, const Vec2<T>& rhs )
00306 {
00307 lhs << "[" << rhs.x << "," << rhs.y << "]";
00308 return lhs;
00309 }
00310
00311 static Vec2<T> xAxis() { return Vec2<T>( 1, 0 ); }
00312 static Vec2<T> yAxis() { return Vec2<T>( 0, 1 ); }
00313
00314 static Vec2<T> NaN() { return Vec2<T>( math<T>::NaN(), math<T>::NaN() ); }
00315 };
00316
00317 template<typename T>
00318 class Vec3
00319 {
00320 public:
00321 T x,y,z;
00322
00323 typedef T TYPE;
00324 typedef T value_type;
00325 static const int DIM = 3;
00326
00327 Vec3() :x(0), y(0), z(0) {}
00328 Vec3( T nx, T ny, T nz )
00329 : x( nx ), y( ny ), z( nz )
00330 {}
00331 Vec3( const Vec3<T> &src )
00332 : x( src.x ), y( src.y ), z( src.z )
00333 {}
00334 Vec3( const Vec2<T> &v2, T aZ )
00335 : x( v2.x ), y( v2.y ), z( aZ )
00336 {}
00337 explicit Vec3( const Vec2<T> &v2 )
00338 : x( v2.x ), y( v2.y ), z( 0 )
00339 {}
00340 explicit Vec3( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ) {}
00341 template<typename FromT>
00342 Vec3( const Vec3<FromT> &src )
00343 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) )
00344 {}
00345 template<typename Y>
00346 explicit Vec3( const Y &v )
00347 : x( VEC3CONV<Vec3<typename T::TYPE>,Y>::getX( v ) ), y( VEC3CONV<typename T::TYPE,Y>::getY( v ) ), z( VEC3CONV<typename T::TYPE,Y>::getZ( v ) )
00348 {
00349 }
00350
00351 void set( T ax, T ay, T az )
00352 {
00353 x = ax; y = ay; z = az;
00354 }
00355
00356 void set( const Vec3<T> &rhs )
00357 {
00358 x = rhs.x; y = rhs.y; z = rhs.z;
00359 }
00360
00361 Vec3<T>& operator=( const Vec3<T> &rhs )
00362 {
00363 x = rhs.x;
00364 y = rhs.y;
00365 z = rhs.z;
00366 return * this;
00367 }
00368
00369 template<typename FromT>
00370 Vec3<T>& operator=( const Vec3<FromT> &rhs )
00371 {
00372 x = static_cast<T>( rhs.x );
00373 y = static_cast<T>( rhs.y );
00374 z = static_cast<T>( rhs.z );
00375 return * this;
00376 }
00377
00378 T& operator[]( int n )
00379 {
00380 assert( n >= 0 && n <= 2 );
00381 return (&x)[n];
00382 }
00383
00384 const T& operator[]( int n ) const
00385 {
00386 assert( n >= 0 && n <= 2 );
00387 return (&x)[n];
00388 }
00389
00390 T* ptr() const { return &(const_cast<Vec3*>( this )->x); }
00391
00392 const Vec3<T> operator+( const Vec3<T>& rhs ) const { return Vec3<T>( x + rhs.x, y + rhs.y, z + rhs.z ); }
00393 const Vec3<T> operator-( const Vec3<T>& rhs ) const { return Vec3<T>( x - rhs.x, y - rhs.y, z - rhs.z ); }
00394 const Vec3<T> operator*( const Vec3<T>& rhs ) const { return Vec3<T>( x * rhs.x, y * rhs.y, z * rhs.z ); }
00395 const Vec3<T> operator/( const Vec3<T>& rhs ) const { return Vec3<T>( x / rhs.x, y / rhs.y, z / rhs.z ); }
00396 Vec3<T>& operator+=( const Vec3<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; }
00397 Vec3<T>& operator-=( const Vec3<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; }
00398 Vec3<T>& operator*=( const Vec3<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this; }
00399 Vec3<T>& operator/=( const Vec3<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; return *this; }
00400 const Vec3<T> operator/( T rhs ) const { T invRhs = static_cast<T>( 1.0 ) / rhs; return Vec3<T>( x * invRhs, y * invRhs, z * invRhs ); }
00401 Vec3<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; return *this; }
00402 Vec3<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; return *this; }
00403 Vec3<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; return *this; }
00404 Vec3<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; return *this; }
00405
00406 Vec3<T> operator-() const { return Vec3<T>( -x, -y, -z ); }
00407
00408 bool operator==( const Vec3<T>& rhs ) const
00409 {
00410 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z );
00411 }
00412
00413 bool operator!=( const Vec3<T>& rhs ) const
00414 {
00415 return !( *this == rhs );
00416 }
00417
00418 T dot( const Vec3<T> &rhs ) const
00419 {
00420 return x*rhs.x + y*rhs.y + z*rhs.z;
00421 }
00422
00423 Vec3<T> cross( const Vec3<T> &rhs ) const
00424 {
00425 return Vec3<T>( y * rhs.z - rhs.y * z, z * rhs.x - rhs.z * x, x * rhs.y - rhs.x * y );
00426 }
00427
00428 T distance( const Vec3<T> &rhs ) const
00429 {
00430 return ( *this - rhs ).length();
00431 }
00432
00433 T distanceSquared( const Vec3<T> &rhs ) const
00434 {
00435 return ( *this - rhs ).lengthSquared();
00436 }
00437
00438 T length() const
00439 {
00440 return math<T>::sqrt( x*x + y*y + z*z );
00441 }
00442
00443 T lengthSquared() const
00444 {
00445 return x*x + y*y + z*z;
00446 }
00447
00449 void limit( T maxLength )
00450 {
00451 T lengthSquared = x * x + y * y + z * z;
00452
00453 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) {
00454 T ratio = maxLength / math<T>::sqrt( lengthSquared );
00455 x *= ratio;
00456 y *= ratio;
00457 z *= ratio;
00458 }
00459 }
00460
00462 Vec3<T> limited( T maxLength ) const
00463 {
00464 T lengthSquared = x * x + y * y + z * z;
00465
00466 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) {
00467 T ratio = maxLength / math<T>::sqrt( lengthSquared );
00468 return Vec3<T>( x * ratio, y * ratio, z * ratio );
00469 }
00470 else
00471 return *this;
00472 }
00473
00474 void invert()
00475 {
00476 x = -x; y = -y; z = -z;
00477 }
00478
00479 Vec3<T> inverse() const
00480 {
00481 return Vec3<T>( -x, -y, -z );
00482 }
00483
00484 void normalize()
00485 {
00486 T invS = ((T)1) / length();
00487 x *= invS;
00488 y *= invS;
00489 z *= invS;
00490 }
00491
00492 Vec3<T> normalized() const
00493 {
00494 T invS = ((T)1) / length();
00495 return Vec3<T>( x * invS, y * invS, z * invS );
00496 }
00497
00498
00499 void safeNormalize()
00500 {
00501 T s = lengthSquared();
00502 if( s > 0 ) {
00503 T invS = ((T)1) / math<T>::sqrt( s );
00504 x *= invS;
00505 y *= invS;
00506 z *= invS;
00507 }
00508 }
00509
00510 Vec3<T> safeNormalized() const
00511 {
00512 T s = lengthSquared();
00513 if( s > 0 ) {
00514 float invS = ((T)1) / math<T>::sqrt( s );
00515 return Vec3<T>( x * invS, y * invS, z * invS );
00516 }
00517 else
00518 return *this;
00519 }
00520
00521 Vec3<T> randomOrthogonal() const
00522 {
00523 if( dot( Vec3<T>::xAxis() ) >= (T)0.01 ) {
00524 return cross( Vec3<T>::xAxis() );
00525 }
00526 else
00527 return cross( Vec3<T>::yAxis() );
00528 }
00529
00530 void rotateX( T angle )
00531 {
00532 T sina = math<T>::sin(angle);
00533 T cosa = math<T>::cos(angle);
00534 T ry = y * cosa - z * sina;
00535 T rz = y * sina + z * cosa;
00536 y = ry;
00537 z = rz;
00538 }
00539
00540 void rotateY( T angle )
00541 {
00542 T sina = math<T>::sin(angle);
00543 T cosa = math<T>::cos(angle);
00544 T rx = x * cosa - z * sina;
00545 T rz = x * sina + z * cosa;
00546 x = rx;
00547 z = rz;
00548 }
00549
00550 void rotateZ( T angle )
00551 {
00552 T sina = math<T>::sin(angle);
00553 T cosa = math<T>::cos(angle);
00554 T rx = x * cosa - y * sina;
00555 T ry = x * sina + y * cosa;
00556 x = rx;
00557 y = ry;
00558 }
00559
00560 void rotate( Vec3<T> axis, T angle )
00561 {
00562 T cosa = math<T>::cos(angle);
00563 T sina = math<T>::sin(angle);
00564
00565 T rx = (cosa + (1 - cosa) * axis.x * axis.x) * x;
00566 rx += ((1 - cosa) * axis.x * axis.y - axis.z * sina) * y;
00567 rx += ((1 - cosa) * axis.x * axis.z + axis.y * sina) * z;
00568
00569 T ry = ((1 - cosa) * axis.x * axis.y + axis.z * sina) * x;
00570 ry += (cosa + (1 - cosa) * axis.y * axis.y) * y;
00571 ry += ((1 - cosa) * axis.y * axis.z - axis.x * sina) * z;
00572
00573 T rz = ((1 - cosa) * axis.x * axis.z - axis.y * sina) * x;
00574 rz += ((1 - cosa) * axis.y * axis.z + axis.x * sina) * y;
00575 rz += (cosa + (1 - cosa) * axis.z * axis.z) * z;
00576
00577 x = rx;
00578 y = ry;
00579 z = rz;
00580 }
00581
00582 Vec3<T> lerp( T fact, const Vec3<T> &rhs ) const
00583 {
00584 return (*this) + (rhs - (*this)) * fact;
00585 }
00586
00587 void lerpEq( T fact, const Vec3<T> &rhs )
00588 {
00589 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; z = z + ( rhs.z - z ) * fact;
00590 }
00591
00592 static Vec3<T> max()
00593 {
00594 return Vec3<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00595 }
00596
00597 static Vec3<T> zero()
00598 {
00599 return Vec3<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00600 }
00601
00602 static Vec3<T> one()
00603 {
00604 return Vec3<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) );
00605 }
00606
00607 Vec3<T> slerp( T fact, const Vec3<T> &r ) const
00608 {
00609 T cosAlpha, alpha, sinAlpha;
00610 T t1, t2;
00611 Vec3<T> result;
00612
00613
00614 cosAlpha = this->dot( r );
00615
00616
00617 alpha = math<T>::acos( cosAlpha );
00618
00619
00620 sinAlpha = math<T>::sin( alpha );
00621
00622
00623 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha;
00624 t2 = math<T>::sin( fact * alpha ) / sinAlpha;
00625
00626
00627 return *this * t1 + r * t2;
00628 }
00629
00630
00631 Vec3<T> squad( T t, const Vec3<T> &tangentA, const Vec3<T> &tangentB, const Vec3<T> &end ) const
00632 {
00633 Vec3<T> r1 = this->slerp( t, end );
00634 Vec3<T> r2 = tangentA.slerp( t, tangentB );
00635 return r1.slerp( 2 * t * (1-t), r2 );
00636 }
00637
00638
00639 Vec2<T> xx() const { return Vec2<T>(x, x); }
00640 Vec2<T> xy() const { return Vec2<T>(x, y); }
00641 Vec2<T> xz() const { return Vec2<T>(x, z); }
00642 Vec2<T> yx() const { return Vec2<T>(y, x); }
00643 Vec2<T> yy() const { return Vec2<T>(y, y); }
00644 Vec2<T> yz() const { return Vec2<T>(y, z); }
00645 Vec2<T> zx() const { return Vec2<T>(z, x); }
00646 Vec2<T> zy() const { return Vec2<T>(z, y); }
00647 Vec2<T> zz() const { return Vec2<T>(z, z); }
00648
00649 Vec3<T> xxx() const { return Vec3<T>(x, x, x); }
00650 Vec3<T> xxy() const { return Vec3<T>(x, x, y); }
00651 Vec3<T> xxz() const { return Vec3<T>(x, x, z); }
00652 Vec3<T> xyx() const { return Vec3<T>(x, y, x); }
00653 Vec3<T> xyy() const { return Vec3<T>(x, y, y); }
00654 Vec3<T> xyz() const { return Vec3<T>(x, y, z); }
00655 Vec3<T> xzx() const { return Vec3<T>(x, z, x); }
00656 Vec3<T> xzy() const { return Vec3<T>(x, z, y); }
00657 Vec3<T> xzz() const { return Vec3<T>(x, z, z); }
00658 Vec3<T> yxx() const { return Vec3<T>(y, x, x); }
00659 Vec3<T> yxy() const { return Vec3<T>(y, x, y); }
00660 Vec3<T> yxz() const { return Vec3<T>(y, x, z); }
00661 Vec3<T> yyx() const { return Vec3<T>(y, y, x); }
00662 Vec3<T> yyy() const { return Vec3<T>(y, y, y); }
00663 Vec3<T> yyz() const { return Vec3<T>(y, y, z); }
00664 Vec3<T> yzx() const { return Vec3<T>(y, z, x); }
00665 Vec3<T> yzy() const { return Vec3<T>(y, z, y); }
00666 Vec3<T> yzz() const { return Vec3<T>(y, z, z); }
00667 Vec3<T> zxx() const { return Vec3<T>(z, x, x); }
00668 Vec3<T> zxy() const { return Vec3<T>(z, x, y); }
00669 Vec3<T> zxz() const { return Vec3<T>(z, x, z); }
00670 Vec3<T> zyx() const { return Vec3<T>(z, y, x); }
00671 Vec3<T> zyy() const { return Vec3<T>(z, y, y); }
00672 Vec3<T> zyz() const { return Vec3<T>(z, y, z); }
00673 Vec3<T> zzx() const { return Vec3<T>(z, z, x); }
00674 Vec3<T> zzy() const { return Vec3<T>(z, z, y); }
00675 Vec3<T> zzz() const { return Vec3<T>(z, z, z); }
00676
00677 friend std::ostream& operator<<( std::ostream& lhs, const Vec3<T> rhs )
00678 {
00679 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "]";
00680 return lhs;
00681 }
00682
00683 static Vec3<T> xAxis() { return Vec3<T>( 1, 0, 0 ); }
00684 static Vec3<T> yAxis() { return Vec3<T>( 0, 1, 0 ); }
00685 static Vec3<T> zAxis() { return Vec3<T>( 0, 0, 1 ); }
00686
00687 static Vec3<T> NaN() { return Vec3<T>( math<T>::NaN(), math<T>::NaN(), math<T>::NaN() ); }
00688 };
00689
00690 template <class T>
00691 class Vec4
00692 {
00693 public:
00694 T x,y,z,w;
00695
00696 typedef T TYPE;
00697 typedef T value_type;
00698 static const int DIM = 4;
00699
00700 Vec4()
00701 : x( 0 ), y( 0 ), z( 0 ), w( 0 )
00702 {}
00703 Vec4( T nx, T ny, T nz, T nw = 0 )
00704 : x( nx ), y( ny ), z( nz ), w( nw )
00705 {}
00706 Vec4( const Vec3<T>& src, T aW = 0 )
00707 : x( src.x ), y( src.y ), z( src.z ), w( aW )
00708 {}
00709 Vec4( const Vec4<T>& src )
00710 : x( src.x ), y( src.y ), z( src.z ), w( src.w )
00711 {}
00712 template<typename FromT>
00713 Vec4( const Vec4<FromT>& src )
00714 : x( static_cast<T>( src.x ) ), y( static_cast<T>( src.y ) ), z( static_cast<T>( src.z ) ),w( static_cast<T>( src.w ) )
00715 {}
00716 explicit Vec4( const T *d ) : x( d[0] ), y( d[1] ), z( d[2] ), w( d[3] ) {}
00717
00718 Vec4<T>& operator=( const Vec4<T>& rhs )
00719 {
00720 x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w;
00721 return *this;
00722 }
00723
00724 template<typename FromT>
00725 Vec4<T>& operator=( const Vec4<FromT>& rhs )
00726 {
00727 x = static_cast<T>(rhs.x); y = static_cast<T>(rhs.y); z = static_cast<T>(rhs.z); w = static_cast<T>(rhs.w);
00728 return *this;
00729 }
00730
00731 T& operator[]( int n )
00732 {
00733 assert( n >= 0 && n <= 3 );
00734 return (&x)[n];
00735 }
00736
00737 const T& operator[]( int n ) const
00738 {
00739 assert( n >= 0 && n <= 3 );
00740 return (&x)[n];
00741 }
00742
00743 T* ptr() const { return &(const_cast<Vec4*>( this )->x); }
00744
00745 const Vec4<T> operator+( const Vec4<T>& rhs ) const { return Vec4<T>( x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w ); }
00746 const Vec4<T> operator-( const Vec4<T>& rhs ) const { return Vec4<T>( x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w ); }
00747 const Vec4<T> operator*( const Vec4<T>& rhs ) const { return Vec4<T>( x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w ); }
00748 const Vec4<T> operator/( const Vec4<T>& rhs ) const { return Vec4<T>( x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w ); }
00749 Vec4<T>& operator+=( const Vec4<T>& rhs ) { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this; }
00750 Vec4<T>& operator-=( const Vec4<T>& rhs ) { x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this; }
00751 Vec4<T>& operator*=( const Vec4<T>& rhs ) { x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this; }
00752 Vec4<T>& operator/=( const Vec4<T>& rhs ) { x /= rhs.x; y /= rhs.y; z /= rhs.z; w /= rhs.w; return *this; }
00753 const Vec4<T> operator/( T rhs ) const { return Vec4<T>( x / rhs, y / rhs, z / rhs, w / rhs ); }
00754 Vec4<T>& operator+=( T rhs ) { x += rhs; y += rhs; z += rhs; w += rhs; return *this; }
00755 Vec4<T>& operator-=( T rhs ) { x -= rhs; y -= rhs; z -= rhs; w -= rhs; return * this; }
00756 Vec4<T>& operator*=( T rhs ) { x *= rhs; y *= rhs; z *= rhs; w *= rhs; return * this; }
00757 Vec4<T>& operator/=( T rhs ) { x /= rhs; y /= rhs; z /= rhs; w /= rhs; return * this; }
00758
00759 Vec4<T> operator-() const { return Vec4<T>( -x, -y, -z, -w ); }
00760
00761 bool operator==( const Vec4<T>& rhs ) const
00762 {
00763 return ( x == rhs.x ) && ( y == rhs.y ) && ( z == rhs.z ) && ( w == rhs.w );
00764 }
00765
00766 bool operator!=( const Vec4<T>& rhs ) const
00767 {
00768 return ! (*this == rhs);
00769 }
00770
00771 T dot( const Vec4<T> &rhs ) const
00772 {
00773 return x*rhs.x + y*rhs.y + z*rhs.z;
00774 }
00775
00776 Vec4<T> cross( const Vec4<T> &rhs ) const
00777 {
00778 return Vec4<T>( y*rhs.z - rhs.y*z, z*rhs.x - rhs.z*x, x*rhs.y - rhs.x*y );
00779 }
00780
00781 T distance( const Vec4<T> &rhs ) const
00782 {
00783 return ( *this - rhs ).length();
00784 }
00785
00786 T distanceSquared( const Vec4<T> &rhs ) const
00787 {
00788 return ( *this - rhs ).lengthSquared();
00789 }
00790
00791 T length() const
00792 {
00793
00794 return math<T>::sqrt( x*x + y*y + z*z + w*w );
00795 }
00796
00797 T lengthSquared() const
00798 {
00799
00800 return x*x + y*y + z*z + w*w;
00801 }
00802
00803 void normalize()
00804 {
00805 T invS = ((T)1) / length();
00806 x *= invS;
00807 y *= invS;
00808 z *= invS;
00809 w *= invS;
00810 }
00811
00812 Vec4<T> normalized() const
00813 {
00814 T invS = ((T)1) / length();
00815 return Vec4<T>( x*invS, y*invS, z*invS, w*invS );
00816 }
00817
00818
00819 void safeNormalize()
00820 {
00821 T s = lengthSquared();
00822 if( s > 0 ) {
00823 T invS = ((T)1) / math<T>::sqrt( s );
00824 x *= invS;
00825 y *= invS;
00826 z *= invS;
00827 w = (T)0;
00828 }
00829 }
00830
00832 void limit( T maxLength )
00833 {
00834 T lenSq = lengthSquared();
00835
00836 if( ( lenSq > maxLength * maxLength ) && ( lenSq > 0 ) ) {
00837 T ratio = maxLength / math<T>::sqrt( lenSq );
00838 x *= ratio;
00839 y *= ratio;
00840 z *= ratio;
00841 w *= ratio;
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 }
00856
00858 Vec4<T> limited( T maxLength ) const
00859 {
00860 T lenSq = lengthSquared();
00861
00862 if( ( lenSq > maxLength * maxLength ) && ( lenSq > 0 ) ) {
00863 T ratio = maxLength / math<T>::sqrt( lenSq );
00864 return Vec4<T>( x * ratio, y * ratio, z * ratio, w * ratio );
00865 }
00866 else
00867 return *this;
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 }
00880
00881 void invert()
00882 {
00883 x = -x; y = -y; z = -z; w = -w;
00884 }
00885
00886 Vec4<T> inverse() const
00887 {
00888 return Vec4<T>( -x, -y, -z, -w );
00889 }
00890
00891 Vec4<T> lerp( T fact, const Vec4<T>& r ) const
00892 {
00893 return (*this) + ( r - (*this) ) * fact;
00894 }
00895
00896 void lerpEq( T fact, const Vec4<T> &rhs )
00897 {
00898 x = x + ( rhs.x - x ) * fact; y = y + ( rhs.y - y ) * fact; z = z + ( rhs.z - z ) * fact; w = w + ( rhs.w - w ) * fact;
00899 }
00900
00901 static Vec4<T> max()
00902 {
00903 return Vec4<T>( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max() );
00904 }
00905
00906 static Vec4<T> zero()
00907 {
00908 return Vec4<T>( static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ), static_cast<T>( 0 ) );
00909 }
00910
00911 static Vec4<T> one()
00912 {
00913 return Vec4<T>( static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ), static_cast<T>( 1 ) );
00914 }
00915
00916 Vec4<T> slerp( T fact, const Vec3<T> &r ) const
00917 {
00918 T cosAlpha, alpha, sinAlpha;
00919 T t1, t2;
00920 Vec4<T> result;
00921
00922
00923 cosAlpha = this->dot( r );
00924
00925
00926 alpha = math<T>::acos( cosAlpha );
00927
00928
00929 sinAlpha = math<T>::sin( alpha );
00930
00931
00932 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha;
00933 t2 = math<T>::sin( fact * alpha ) / sinAlpha;
00934
00935
00936 return *this * t1 + r * t2;
00937 }
00938
00939
00940 Vec4<T> squad( T t, const Vec4<T> &tangentA, const Vec4<T> &tangentB, const Vec4<T> &end ) const
00941 {
00942 Vec4<T> r1 = this->slerp( t, end );
00943 Vec4<T> r2 = tangentA.slerp( t, tangentB );
00944 return r1.slerp( 2 * t * (1-t), r2 );
00945 }
00946
00947
00948 Vec2<T> xx() const { return Vec2<T>(x, x); }
00949 Vec2<T> xy() const { return Vec2<T>(x, y); }
00950 Vec2<T> xz() const { return Vec2<T>(x, z); }
00951 Vec2<T> yx() const { return Vec2<T>(y, x); }
00952 Vec2<T> yy() const { return Vec2<T>(y, y); }
00953 Vec2<T> yz() const { return Vec2<T>(y, z); }
00954 Vec2<T> zx() const { return Vec2<T>(z, x); }
00955 Vec2<T> zy() const { return Vec2<T>(z, y); }
00956 Vec2<T> zz() const { return Vec2<T>(z, z); }
00957
00958 Vec3<T> xxx() const { return Vec3<T>(x, x, x); }
00959 Vec3<T> xxy() const { return Vec3<T>(x, x, y); }
00960 Vec3<T> xxz() const { return Vec3<T>(x, x, z); }
00961 Vec3<T> xyx() const { return Vec3<T>(x, y, x); }
00962 Vec3<T> xyy() const { return Vec3<T>(x, y, y); }
00963 Vec3<T> xyz() const { return Vec3<T>(x, y, z); }
00964 Vec3<T> xzx() const { return Vec3<T>(x, z, x); }
00965 Vec3<T> xzy() const { return Vec3<T>(x, z, y); }
00966 Vec3<T> xzz() const { return Vec3<T>(x, z, z); }
00967 Vec3<T> yxx() const { return Vec3<T>(y, x, x); }
00968 Vec3<T> yxy() const { return Vec3<T>(y, x, y); }
00969 Vec3<T> yxz() const { return Vec3<T>(y, x, z); }
00970 Vec3<T> yyx() const { return Vec3<T>(y, y, x); }
00971 Vec3<T> yyy() const { return Vec3<T>(y, y, y); }
00972 Vec3<T> yyz() const { return Vec3<T>(y, y, z); }
00973 Vec3<T> yzx() const { return Vec3<T>(y, z, x); }
00974 Vec3<T> yzy() const { return Vec3<T>(y, z, y); }
00975 Vec3<T> yzz() const { return Vec3<T>(y, z, z); }
00976 Vec3<T> zxx() const { return Vec3<T>(z, x, x); }
00977 Vec3<T> zxy() const { return Vec3<T>(z, x, y); }
00978 Vec3<T> zxz() const { return Vec3<T>(z, x, z); }
00979 Vec3<T> zyx() const { return Vec3<T>(z, y, x); }
00980 Vec3<T> zyy() const { return Vec3<T>(z, y, y); }
00981 Vec3<T> zyz() const { return Vec3<T>(z, y, z); }
00982 Vec3<T> zzx() const { return Vec3<T>(z, z, x); }
00983 Vec3<T> zzy() const { return Vec3<T>(z, z, y); }
00984 Vec3<T> zzz() const { return Vec3<T>(z, z, z); }
00985
00986 Vec4<T> xxxx() const { return Vec4<T>(x, x, x, x); }
00987 Vec4<T> xxxy() const { return Vec4<T>(x, x, x, y); }
00988 Vec4<T> xxxz() const { return Vec4<T>(x, x, x, z); }
00989 Vec4<T> xxxw() const { return Vec4<T>(x, x, x, w); }
00990 Vec4<T> xxyx() const { return Vec4<T>(x, x, y, x); }
00991 Vec4<T> xxyy() const { return Vec4<T>(x, x, y, y); }
00992 Vec4<T> xxyz() const { return Vec4<T>(x, x, y, z); }
00993 Vec4<T> xxyw() const { return Vec4<T>(x, x, y, w); }
00994 Vec4<T> xxzx() const { return Vec4<T>(x, x, z, x); }
00995 Vec4<T> xxzy() const { return Vec4<T>(x, x, z, y); }
00996 Vec4<T> xxzz() const { return Vec4<T>(x, x, z, z); }
00997 Vec4<T> xxzw() const { return Vec4<T>(x, x, z, w); }
00998 Vec4<T> xxwx() const { return Vec4<T>(x, x, w, x); }
00999 Vec4<T> xxwy() const { return Vec4<T>(x, x, w, y); }
01000 Vec4<T> xxwz() const { return Vec4<T>(x, x, w, z); }
01001 Vec4<T> xxww() const { return Vec4<T>(x, x, w, w); }
01002 Vec4<T> xyxx() const { return Vec4<T>(x, y, x, x); }
01003 Vec4<T> xyxy() const { return Vec4<T>(x, y, x, y); }
01004 Vec4<T> xyxz() const { return Vec4<T>(x, y, x, z); }
01005 Vec4<T> xyxw() const { return Vec4<T>(x, y, x, w); }
01006 Vec4<T> xyyx() const { return Vec4<T>(x, y, y, x); }
01007 Vec4<T> xyyy() const { return Vec4<T>(x, y, y, y); }
01008 Vec4<T> xyyz() const { return Vec4<T>(x, y, y, z); }
01009 Vec4<T> xyyw() const { return Vec4<T>(x, y, y, w); }
01010 Vec4<T> xyzx() const { return Vec4<T>(x, y, z, x); }
01011 Vec4<T> xyzy() const { return Vec4<T>(x, y, z, y); }
01012 Vec4<T> xyzz() const { return Vec4<T>(x, y, z, z); }
01013 Vec4<T> xyzw() const { return Vec4<T>(x, y, z, w); }
01014 Vec4<T> xywx() const { return Vec4<T>(x, y, w, x); }
01015 Vec4<T> xywy() const { return Vec4<T>(x, y, w, y); }
01016 Vec4<T> xywz() const { return Vec4<T>(x, y, w, z); }
01017 Vec4<T> xyww() const { return Vec4<T>(x, y, w, w); }
01018 Vec4<T> xzxx() const { return Vec4<T>(x, z, x, x); }
01019 Vec4<T> xzxy() const { return Vec4<T>(x, z, x, y); }
01020 Vec4<T> xzxz() const { return Vec4<T>(x, z, x, z); }
01021 Vec4<T> xzxw() const { return Vec4<T>(x, z, x, w); }
01022 Vec4<T> xzyx() const { return Vec4<T>(x, z, y, x); }
01023 Vec4<T> xzyy() const { return Vec4<T>(x, z, y, y); }
01024 Vec4<T> xzyz() const { return Vec4<T>(x, z, y, z); }
01025 Vec4<T> xzyw() const { return Vec4<T>(x, z, y, w); }
01026 Vec4<T> xzzx() const { return Vec4<T>(x, z, z, x); }
01027 Vec4<T> xzzy() const { return Vec4<T>(x, z, z, y); }
01028 Vec4<T> xzzz() const { return Vec4<T>(x, z, z, z); }
01029 Vec4<T> xzzw() const { return Vec4<T>(x, z, z, w); }
01030 Vec4<T> xzwx() const { return Vec4<T>(x, z, w, x); }
01031 Vec4<T> xzwy() const { return Vec4<T>(x, z, w, y); }
01032 Vec4<T> xzwz() const { return Vec4<T>(x, z, w, z); }
01033 Vec4<T> xzww() const { return Vec4<T>(x, z, w, w); }
01034 Vec4<T> xwxx() const { return Vec4<T>(x, w, x, x); }
01035 Vec4<T> xwxy() const { return Vec4<T>(x, w, x, y); }
01036 Vec4<T> xwxz() const { return Vec4<T>(x, w, x, z); }
01037 Vec4<T> xwxw() const { return Vec4<T>(x, w, x, w); }
01038 Vec4<T> xwyx() const { return Vec4<T>(x, w, y, x); }
01039 Vec4<T> xwyy() const { return Vec4<T>(x, w, y, y); }
01040 Vec4<T> xwyz() const { return Vec4<T>(x, w, y, z); }
01041 Vec4<T> xwyw() const { return Vec4<T>(x, w, y, w); }
01042 Vec4<T> xwzx() const { return Vec4<T>(x, w, z, x); }
01043 Vec4<T> xwzy() const { return Vec4<T>(x, w, z, y); }
01044 Vec4<T> xwzz() const { return Vec4<T>(x, w, z, z); }
01045 Vec4<T> xwzw() const { return Vec4<T>(x, w, z, w); }
01046 Vec4<T> xwwx() const { return Vec4<T>(x, w, w, x); }
01047 Vec4<T> xwwy() const { return Vec4<T>(x, w, w, y); }
01048 Vec4<T> xwwz() const { return Vec4<T>(x, w, w, z); }
01049 Vec4<T> xwww() const { return Vec4<T>(x, w, w, w); }
01050 Vec4<T> yxxx() const { return Vec4<T>(y, x, x, x); }
01051 Vec4<T> yxxy() const { return Vec4<T>(y, x, x, y); }
01052 Vec4<T> yxxz() const { return Vec4<T>(y, x, x, z); }
01053 Vec4<T> yxxw() const { return Vec4<T>(y, x, x, w); }
01054 Vec4<T> yxyx() const { return Vec4<T>(y, x, y, x); }
01055 Vec4<T> yxyy() const { return Vec4<T>(y, x, y, y); }
01056 Vec4<T> yxyz() const { return Vec4<T>(y, x, y, z); }
01057 Vec4<T> yxyw() const { return Vec4<T>(y, x, y, w); }
01058 Vec4<T> yxzx() const { return Vec4<T>(y, x, z, x); }
01059 Vec4<T> yxzy() const { return Vec4<T>(y, x, z, y); }
01060 Vec4<T> yxzz() const { return Vec4<T>(y, x, z, z); }
01061 Vec4<T> yxzw() const { return Vec4<T>(y, x, z, w); }
01062 Vec4<T> yxwx() const { return Vec4<T>(y, x, w, x); }
01063 Vec4<T> yxwy() const { return Vec4<T>(y, x, w, y); }
01064 Vec4<T> yxwz() const { return Vec4<T>(y, x, w, z); }
01065 Vec4<T> yxww() const { return Vec4<T>(y, x, w, w); }
01066 Vec4<T> yyxx() const { return Vec4<T>(y, y, x, x); }
01067 Vec4<T> yyxy() const { return Vec4<T>(y, y, x, y); }
01068 Vec4<T> yyxz() const { return Vec4<T>(y, y, x, z); }
01069 Vec4<T> yyxw() const { return Vec4<T>(y, y, x, w); }
01070 Vec4<T> yyyx() const { return Vec4<T>(y, y, y, x); }
01071 Vec4<T> yyyy() const { return Vec4<T>(y, y, y, y); }
01072 Vec4<T> yyyz() const { return Vec4<T>(y, y, y, z); }
01073 Vec4<T> yyyw() const { return Vec4<T>(y, y, y, w); }
01074 Vec4<T> yyzx() const { return Vec4<T>(y, y, z, x); }
01075 Vec4<T> yyzy() const { return Vec4<T>(y, y, z, y); }
01076 Vec4<T> yyzz() const { return Vec4<T>(y, y, z, z); }
01077 Vec4<T> yyzw() const { return Vec4<T>(y, y, z, w); }
01078 Vec4<T> yywx() const { return Vec4<T>(y, y, w, x); }
01079 Vec4<T> yywy() const { return Vec4<T>(y, y, w, y); }
01080 Vec4<T> yywz() const { return Vec4<T>(y, y, w, z); }
01081 Vec4<T> yyww() const { return Vec4<T>(y, y, w, w); }
01082 Vec4<T> yzxx() const { return Vec4<T>(y, z, x, x); }
01083 Vec4<T> yzxy() const { return Vec4<T>(y, z, x, y); }
01084 Vec4<T> yzxz() const { return Vec4<T>(y, z, x, z); }
01085 Vec4<T> yzxw() const { return Vec4<T>(y, z, x, w); }
01086 Vec4<T> yzyx() const { return Vec4<T>(y, z, y, x); }
01087 Vec4<T> yzyy() const { return Vec4<T>(y, z, y, y); }
01088 Vec4<T> yzyz() const { return Vec4<T>(y, z, y, z); }
01089 Vec4<T> yzyw() const { return Vec4<T>(y, z, y, w); }
01090 Vec4<T> yzzx() const { return Vec4<T>(y, z, z, x); }
01091 Vec4<T> yzzy() const { return Vec4<T>(y, z, z, y); }
01092 Vec4<T> yzzz() const { return Vec4<T>(y, z, z, z); }
01093 Vec4<T> yzzw() const { return Vec4<T>(y, z, z, w); }
01094 Vec4<T> yzwx() const { return Vec4<T>(y, z, w, x); }
01095 Vec4<T> yzwy() const { return Vec4<T>(y, z, w, y); }
01096 Vec4<T> yzwz() const { return Vec4<T>(y, z, w, z); }
01097 Vec4<T> yzww() const { return Vec4<T>(y, z, w, w); }
01098 Vec4<T> ywxx() const { return Vec4<T>(y, w, x, x); }
01099 Vec4<T> ywxy() const { return Vec4<T>(y, w, x, y); }
01100 Vec4<T> ywxz() const { return Vec4<T>(y, w, x, z); }
01101 Vec4<T> ywxw() const { return Vec4<T>(y, w, x, w); }
01102 Vec4<T> ywyx() const { return Vec4<T>(y, w, y, x); }
01103 Vec4<T> ywyy() const { return Vec4<T>(y, w, y, y); }
01104 Vec4<T> ywyz() const { return Vec4<T>(y, w, y, z); }
01105 Vec4<T> ywyw() const { return Vec4<T>(y, w, y, w); }
01106 Vec4<T> ywzx() const { return Vec4<T>(y, w, z, x); }
01107 Vec4<T> ywzy() const { return Vec4<T>(y, w, z, y); }
01108 Vec4<T> ywzz() const { return Vec4<T>(y, w, z, z); }
01109 Vec4<T> ywzw() const { return Vec4<T>(y, w, z, w); }
01110 Vec4<T> ywwx() const { return Vec4<T>(y, w, w, x); }
01111 Vec4<T> ywwy() const { return Vec4<T>(y, w, w, y); }
01112 Vec4<T> ywwz() const { return Vec4<T>(y, w, w, z); }
01113 Vec4<T> ywww() const { return Vec4<T>(y, w, w, w); }
01114 Vec4<T> zxxx() const { return Vec4<T>(z, x, x, x); }
01115 Vec4<T> zxxy() const { return Vec4<T>(z, x, x, y); }
01116 Vec4<T> zxxz() const { return Vec4<T>(z, x, x, z); }
01117 Vec4<T> zxxw() const { return Vec4<T>(z, x, x, w); }
01118 Vec4<T> zxyx() const { return Vec4<T>(z, x, y, x); }
01119 Vec4<T> zxyy() const { return Vec4<T>(z, x, y, y); }
01120 Vec4<T> zxyz() const { return Vec4<T>(z, x, y, z); }
01121 Vec4<T> zxyw() const { return Vec4<T>(z, x, y, w); }
01122 Vec4<T> zxzx() const { return Vec4<T>(z, x, z, x); }
01123 Vec4<T> zxzy() const { return Vec4<T>(z, x, z, y); }
01124 Vec4<T> zxzz() const { return Vec4<T>(z, x, z, z); }
01125 Vec4<T> zxzw() const { return Vec4<T>(z, x, z, w); }
01126 Vec4<T> zxwx() const { return Vec4<T>(z, x, w, x); }
01127 Vec4<T> zxwy() const { return Vec4<T>(z, x, w, y); }
01128 Vec4<T> zxwz() const { return Vec4<T>(z, x, w, z); }
01129 Vec4<T> zxww() const { return Vec4<T>(z, x, w, w); }
01130 Vec4<T> zyxx() const { return Vec4<T>(z, y, x, x); }
01131 Vec4<T> zyxy() const { return Vec4<T>(z, y, x, y); }
01132 Vec4<T> zyxz() const { return Vec4<T>(z, y, x, z); }
01133 Vec4<T> zyxw() const { return Vec4<T>(z, y, x, w); }
01134 Vec4<T> zyyx() const { return Vec4<T>(z, y, y, x); }
01135 Vec4<T> zyyy() const { return Vec4<T>(z, y, y, y); }
01136 Vec4<T> zyyz() const { return Vec4<T>(z, y, y, z); }
01137 Vec4<T> zyyw() const { return Vec4<T>(z, y, y, w); }
01138 Vec4<T> zyzx() const { return Vec4<T>(z, y, z, x); }
01139 Vec4<T> zyzy() const { return Vec4<T>(z, y, z, y); }
01140 Vec4<T> zyzz() const { return Vec4<T>(z, y, z, z); }
01141 Vec4<T> zyzw() const { return Vec4<T>(z, y, z, w); }
01142 Vec4<T> zywx() const { return Vec4<T>(z, y, w, x); }
01143 Vec4<T> zywy() const { return Vec4<T>(z, y, w, y); }
01144 Vec4<T> zywz() const { return Vec4<T>(z, y, w, z); }
01145 Vec4<T> zyww() const { return Vec4<T>(z, y, w, w); }
01146 Vec4<T> zzxx() const { return Vec4<T>(z, z, x, x); }
01147 Vec4<T> zzxy() const { return Vec4<T>(z, z, x, y); }
01148 Vec4<T> zzxz() const { return Vec4<T>(z, z, x, z); }
01149 Vec4<T> zzxw() const { return Vec4<T>(z, z, x, w); }
01150 Vec4<T> zzyx() const { return Vec4<T>(z, z, y, x); }
01151 Vec4<T> zzyy() const { return Vec4<T>(z, z, y, y); }
01152 Vec4<T> zzyz() const { return Vec4<T>(z, z, y, z); }
01153 Vec4<T> zzyw() const { return Vec4<T>(z, z, y, w); }
01154 Vec4<T> zzzx() const { return Vec4<T>(z, z, z, x); }
01155 Vec4<T> zzzy() const { return Vec4<T>(z, z, z, y); }
01156 Vec4<T> zzzz() const { return Vec4<T>(z, z, z, z); }
01157 Vec4<T> zzzw() const { return Vec4<T>(z, z, z, w); }
01158 Vec4<T> zzwx() const { return Vec4<T>(z, z, w, x); }
01159 Vec4<T> zzwy() const { return Vec4<T>(z, z, w, y); }
01160 Vec4<T> zzwz() const { return Vec4<T>(z, z, w, z); }
01161 Vec4<T> zzww() const { return Vec4<T>(z, z, w, w); }
01162 Vec4<T> zwxx() const { return Vec4<T>(z, w, x, x); }
01163 Vec4<T> zwxy() const { return Vec4<T>(z, w, x, y); }
01164 Vec4<T> zwxz() const { return Vec4<T>(z, w, x, z); }
01165 Vec4<T> zwxw() const { return Vec4<T>(z, w, x, w); }
01166 Vec4<T> zwyx() const { return Vec4<T>(z, w, y, x); }
01167 Vec4<T> zwyy() const { return Vec4<T>(z, w, y, y); }
01168 Vec4<T> zwyz() const { return Vec4<T>(z, w, y, z); }
01169 Vec4<T> zwyw() const { return Vec4<T>(z, w, y, w); }
01170 Vec4<T> zwzx() const { return Vec4<T>(z, w, z, x); }
01171 Vec4<T> zwzy() const { return Vec4<T>(z, w, z, y); }
01172 Vec4<T> zwzz() const { return Vec4<T>(z, w, z, z); }
01173 Vec4<T> zwzw() const { return Vec4<T>(z, w, z, w); }
01174 Vec4<T> zwwx() const { return Vec4<T>(z, w, w, x); }
01175 Vec4<T> zwwy() const { return Vec4<T>(z, w, w, y); }
01176 Vec4<T> zwwz() const { return Vec4<T>(z, w, w, z); }
01177 Vec4<T> zwww() const { return Vec4<T>(z, w, w, w); }
01178 Vec4<T> wxxx() const { return Vec4<T>(w, x, x, x); }
01179 Vec4<T> wxxy() const { return Vec4<T>(w, x, x, y); }
01180 Vec4<T> wxxz() const { return Vec4<T>(w, x, x, z); }
01181 Vec4<T> wxxw() const { return Vec4<T>(w, x, x, w); }
01182 Vec4<T> wxyx() const { return Vec4<T>(w, x, y, x); }
01183 Vec4<T> wxyy() const { return Vec4<T>(w, x, y, y); }
01184 Vec4<T> wxyz() const { return Vec4<T>(w, x, y, z); }
01185 Vec4<T> wxyw() const { return Vec4<T>(w, x, y, w); }
01186 Vec4<T> wxzx() const { return Vec4<T>(w, x, z, x); }
01187 Vec4<T> wxzy() const { return Vec4<T>(w, x, z, y); }
01188 Vec4<T> wxzz() const { return Vec4<T>(w, x, z, z); }
01189 Vec4<T> wxzw() const { return Vec4<T>(w, x, z, w); }
01190 Vec4<T> wxwx() const { return Vec4<T>(w, x, w, x); }
01191 Vec4<T> wxwy() const { return Vec4<T>(w, x, w, y); }
01192 Vec4<T> wxwz() const { return Vec4<T>(w, x, w, z); }
01193 Vec4<T> wxww() const { return Vec4<T>(w, x, w, w); }
01194 Vec4<T> wyxx() const { return Vec4<T>(w, y, x, x); }
01195 Vec4<T> wyxy() const { return Vec4<T>(w, y, x, y); }
01196 Vec4<T> wyxz() const { return Vec4<T>(w, y, x, z); }
01197 Vec4<T> wyxw() const { return Vec4<T>(w, y, x, w); }
01198 Vec4<T> wyyx() const { return Vec4<T>(w, y, y, x); }
01199 Vec4<T> wyyy() const { return Vec4<T>(w, y, y, y); }
01200 Vec4<T> wyyz() const { return Vec4<T>(w, y, y, z); }
01201 Vec4<T> wyyw() const { return Vec4<T>(w, y, y, w); }
01202 Vec4<T> wyzx() const { return Vec4<T>(w, y, z, x); }
01203 Vec4<T> wyzy() const { return Vec4<T>(w, y, z, y); }
01204 Vec4<T> wyzz() const { return Vec4<T>(w, y, z, z); }
01205 Vec4<T> wyzw() const { return Vec4<T>(w, y, z, w); }
01206 Vec4<T> wywx() const { return Vec4<T>(w, y, w, x); }
01207 Vec4<T> wywy() const { return Vec4<T>(w, y, w, y); }
01208 Vec4<T> wywz() const { return Vec4<T>(w, y, w, z); }
01209 Vec4<T> wyww() const { return Vec4<T>(w, y, w, w); }
01210 Vec4<T> wzxx() const { return Vec4<T>(w, z, x, x); }
01211 Vec4<T> wzxy() const { return Vec4<T>(w, z, x, y); }
01212 Vec4<T> wzxz() const { return Vec4<T>(w, z, x, z); }
01213 Vec4<T> wzxw() const { return Vec4<T>(w, z, x, w); }
01214 Vec4<T> wzyx() const { return Vec4<T>(w, z, y, x); }
01215 Vec4<T> wzyy() const { return Vec4<T>(w, z, y, y); }
01216 Vec4<T> wzyz() const { return Vec4<T>(w, z, y, z); }
01217 Vec4<T> wzyw() const { return Vec4<T>(w, z, y, w); }
01218 Vec4<T> wzzx() const { return Vec4<T>(w, z, z, x); }
01219 Vec4<T> wzzy() const { return Vec4<T>(w, z, z, y); }
01220 Vec4<T> wzzz() const { return Vec4<T>(w, z, z, z); }
01221 Vec4<T> wzzw() const { return Vec4<T>(w, z, z, w); }
01222 Vec4<T> wzwx() const { return Vec4<T>(w, z, w, x); }
01223 Vec4<T> wzwy() const { return Vec4<T>(w, z, w, y); }
01224 Vec4<T> wzwz() const { return Vec4<T>(w, z, w, z); }
01225 Vec4<T> wzww() const { return Vec4<T>(w, z, w, w); }
01226 Vec4<T> wwxx() const { return Vec4<T>(w, w, x, x); }
01227 Vec4<T> wwxy() const { return Vec4<T>(w, w, x, y); }
01228 Vec4<T> wwxz() const { return Vec4<T>(w, w, x, z); }
01229 Vec4<T> wwxw() const { return Vec4<T>(w, w, x, w); }
01230 Vec4<T> wwyx() const { return Vec4<T>(w, w, y, x); }
01231 Vec4<T> wwyy() const { return Vec4<T>(w, w, y, y); }
01232 Vec4<T> wwyz() const { return Vec4<T>(w, w, y, z); }
01233 Vec4<T> wwyw() const { return Vec4<T>(w, w, y, w); }
01234 Vec4<T> wwzx() const { return Vec4<T>(w, w, z, x); }
01235 Vec4<T> wwzy() const { return Vec4<T>(w, w, z, y); }
01236 Vec4<T> wwzz() const { return Vec4<T>(w, w, z, z); }
01237 Vec4<T> wwzw() const { return Vec4<T>(w, w, z, w); }
01238 Vec4<T> wwwx() const { return Vec4<T>(w, w, w, x); }
01239 Vec4<T> wwwy() const { return Vec4<T>(w, w, w, y); }
01240 Vec4<T> wwwz() const { return Vec4<T>(w, w, w, z); }
01241 Vec4<T> wwww() const { return Vec4<T>(w, w, w, w); }
01242
01243 friend std::ostream& operator<<( std::ostream& lhs, const Vec4<T>& rhs )
01244 {
01245 lhs << "[" << rhs.x << "," << rhs.y << "," << rhs.z << "," << rhs.w << "]";
01246 return lhs;
01247 }
01248
01249 static Vec4<T> xAxis() { return Vec4<T>( 1, 0, 0, 0 ); }
01250 static Vec4<T> yAxis() { return Vec4<T>( 0, 1, 0, 0 ); }
01251 static Vec4<T> zAxis() { return Vec4<T>( 0, 0, 1, 0 ); }
01252 static Vec4<T> wAxis() { return Vec4<T>( 0, 0, 0, 1 ); }
01253
01254 static Vec4<T> NaN() { return Vec4<T>( math<T>::NaN(), math<T>::NaN(), math<T>::NaN(), math<T>::NaN() ); }
01255 };
01256
01258 template<typename T>
01259 Vec2<T> toPolar( Vec2<T> car )
01260 {
01261 const T epsilon = (T)0.0000001;
01262 T theta;
01263 if( math<T>::abs( car.x ) < epsilon ) {
01264 if( math<T>::abs( car.y ) < epsilon ) theta = 0;
01265 else if( car.y > 0 ) theta = (T)M_PI / 2;
01266 else theta = ( (T)M_PI * 3 ) / 2;
01267 }
01268 else if ( car.x > 0 ) {
01269 if( car.y < 0 ) theta = math<T>::atan( car.y / car.x ) + 2 * (T)M_PI;
01270 else theta = math<T>::atan( car.y / car.x );
01271 }
01272 else
01273 theta = (math<T>::atan( car.y / car.x ) + M_PI );
01274
01275 return Vec2<T>( car.length(), theta );
01276 }
01277
01279 template<typename T>
01280 Vec2<T> fromPolar( Vec2<T> pol )
01281 {
01282 return Vec2<T>( math<T>::cos( pol.y ) * pol.x , math<T>::sin( pol.y ) * pol.x );
01283 }
01284
01285 template<typename T,typename Y> inline Vec2<T> operator *( Y s, const Vec2<T> &v ) { return Vec2<T>( v.x * s, v.y * s ); }
01286 template<typename T,typename Y> inline Vec2<T> operator *( const Vec2<T> &v, Y s ) { return Vec2<T>( v.x * s, v.y * s ); }
01287 template<typename T,typename Y> inline Vec3<T> operator *( Y s, const Vec3<T> &v ) { return Vec3<T>( v.x * s, v.y * s, v.z * s ); }
01288 template<typename T,typename Y> inline Vec3<T> operator *( const Vec3<T> &v, Y s ) { return Vec3<T>( v.x * s, v.y * s, v.z * s ); }
01289 template<typename T,typename Y> inline Vec4<T> operator *( Y s, const Vec4<T> &v ) { return Vec4<T>( v.x * s, v.y * s, v.z * s, v.w * s ); }
01290 template<typename T,typename Y> inline Vec4<T> operator *( const Vec4<T> &v, Y s ) { return Vec4<T>( v.x * s, v.y * s, v.z * s, v.w * s ); }
01291
01292 template <typename T> T dot( const Vec2<T>& a, const Vec2<T>& b ) { return a.dot( b ); }
01293 template <typename T> T dot( const Vec3<T>& a, const Vec3<T>& b ) { return a.dot( b ); }
01294 template <typename T> T dot( const Vec4<T>& a, const Vec4<T>& b ) { return a.dot( b ); }
01295
01296 template <typename T> Vec3<T> cross( const Vec3<T>& a, const Vec3<T>& b ) { return a.cross( b ); }
01297 template <typename T> Vec4<T> cross( const Vec4<T>& a, const Vec4<T>& b ) { return a.cross( b ); }
01298
01299 template <typename T> bool isNaN( const Vec2<T>& a ) { return isNaN( a.x ) || isNaN( a.y ); }
01300 template <typename T> bool isNaN( const Vec3<T>& a ) { return isNaN( a.x ) || isNaN( a.y ) || isNaN( a.z ); }
01301 template <typename T> bool isNaN( const Vec4<T>& a ) { return isNaN( a.x ) || isNaN( a.y ) || isNaN( a.z ) || isNaN( a.w ); }
01302
01303 typedef Vec2<int> Vec2i;
01304 typedef Vec2<float> Vec2f;
01305 typedef Vec2<double> Vec2d;
01306 typedef Vec3<int> Vec3i;
01307 typedef Vec3<float> Vec3f;
01308 typedef Vec3<double> Vec3d;
01309 typedef Vec4<int> Vec4i;
01310 typedef Vec4<float> Vec4f;
01311 typedef Vec4<double> Vec4d;
01312
01313 }