Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/Vector.h

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