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 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