00001 /* 00002 Copyright (c) 2010, The Cinder Project 00003 All rights reserved. 00004 00005 This code is designed for use with the Cinder C++ library, http://libcinder.org 00006 00007 Portions Copyright (c) 2010, The Barbarian Group 00008 All rights reserved. 00009 00010 Redistribution and use in source and binary forms, with or without modification, are permitted provided that 00011 the following conditions are met: 00012 00013 * Redistributions of source code must retain the above copyright notice, this list of conditions and 00014 the following disclaimer. 00015 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 00016 the following disclaimer in the documentation and/or other materials provided with the distribution. 00017 00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 00019 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00021 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00022 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00023 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00024 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 POSSIBILITY OF SUCH DAMAGE. 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 // Operators 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 ); } // unary negation 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 // tests for zero-length 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 // GLSL inspired swizzling functions. 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 ); } // unary negation 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 // tests for zero-length 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 // get cosine of angle between vectors (-1 -> 1) 00614 cosAlpha = this->dot( r ); 00615 00616 // get angle (0 -> pi) 00617 alpha = math<T>::acos( cosAlpha ); 00618 00619 // get sine of angle between vectors (0 -> 1) 00620 sinAlpha = math<T>::sin( alpha ); 00621 00622 // this breaks down when sinAlpha = 0, i.e. alpha = 0 or pi 00623 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha; 00624 t2 = math<T>::sin( fact * alpha ) / sinAlpha; 00625 00626 // interpolate src vectors 00627 return *this * t1 + r * t2; 00628 } 00629 00630 // derived from but not equivalent to Quaternion::squad 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 // GLSL inspired swizzling functions. 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 ); } // unary negation 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 // For most vector operations, this assumes w to be zero. 00794 return math<T>::sqrt( x*x + y*y + z*z + w*w ); 00795 } 00796 00797 T lengthSquared() const 00798 { 00799 // For most vector operations, this assumes w to be zero. 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 // Tests for zero-length 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 T lengthSquared = x * x + y * y + z * z + w * w; 00846 00847 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00848 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00849 x *= ratio; 00850 y *= ratio; 00851 z *= ratio; 00852 w *= ratio; 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 T lengthSquared = x * x + y * y + z * z + w * w; 00871 00872 if( ( lengthSquared > maxLength * maxLength ) && ( lengthSquared > 0 ) ) { 00873 T ratio = maxLength / math<T>::sqrt( lengthSquared ); 00874 return Vec4<T>( x * ratio, y * ratio, z * ratio, w * ratio ); 00875 } 00876 else 00877 return *this; 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 // get cosine of angle between vectors (-1 -> 1) 00923 cosAlpha = this->dot( r ); 00924 00925 // get angle (0 -> pi) 00926 alpha = math<T>::acos( cosAlpha ); 00927 00928 // get sine of angle between vectors (0 -> 1) 00929 sinAlpha = math<T>::sin( alpha ); 00930 00931 // this breaks down when sinAlpha = 0, i.e. alpha = 0 or pi 00932 t1 = math<T>::sin( ((T)1 - fact) * alpha) / sinAlpha; 00933 t2 = math<T>::sin( fact * alpha ) / sinAlpha; 00934 00935 // interpolate src vectors 00936 return *this * t1 + r * t2; 00937 } 00938 00939 // derived from but not equivalent to Quaternion::squad 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 // GLSL inspired swizzling functions. 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 ) { // x == 0 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 // car.x < 0 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 } // namespace cinder