Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Vector.h

Go to the documentation of this file.
00001 
00002 /*
00003     TEDDY - General graphics application library
00004     Copyright (C) 1999-2002  Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007         Adapted from
00008 
00009         The Universe Development Kit
00010         Copyright (C) 2000  Sean O'Neil
00011         s_p_oneil@hotmail.com
00012 
00013     This library is free software; you can redistribute it and/or
00014     modify it under the terms of the GNU Lesser General Public
00015     License as published by the Free Software Foundation; either
00016     version 2.1 of the License, or (at your option) any later version.
00017 
00018     This library is distributed in the hope that it will be useful,
00019     but WITHOUT ANY WARRANTY; without even the implied warranty of
00020     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021     Lesser General Public License for more details.
00022 
00023     You should have received a copy of the GNU Lesser General Public
00024     License along with this library; if not, write to the Free Software
00025     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026 
00027     $Id: Vector.h,v 1.5 2002/01/17 18:57:37 tksuoran Exp $
00028 */
00029 
00030 
00031 #ifndef TEDDY__MATHS__VECTOR__H
00032 #define TEDDY__MATHS__VECTOR__H
00033 
00034 
00035 #include "Teddy/Maths/Quaternion.h"
00036 #include "Teddy/SysSupport/StdMaths.h"
00037 
00038 
00039 namespace Teddy {
00040 namespace Maths {
00041 
00042 
00043 /*
00044     \class   Vector
00045     \author  Sean O'Neil
00046 
00047     This template class implements a simple 3D vector with v[0], v[1], and v[2] coordinates.
00048     Several functions and operators are defined to make working with vectors easier,
00049     and because it's templatized, any numeric type can be used with it. Macros are
00050     defined for the most common types.
00051 */
00052 #ifndef SWIG
00053 #define Vector       TVector<float>
00054 #define IntVector    TVector<int>
00055 #define FloatVector  TVector<float>
00056 #define DoubleVector TVector<double>
00057 #define CByteVector  TVector<unsigned char>
00058 
00059 #define VECTOR_EPSILON 0.00001
00060 #endif
00061 
00062 
00074 template <typename T> class TVector {
00075 public:
00076     T v[3];
00077 
00078     // Constructors
00079     TVector(){}
00080 /*  TVector( const T a, const T b, const T c ){
00081         v[0] = a;
00082         v[1] = b;
00083         v[2] = c;
00084     }*/
00085     TVector( const int a, const int b, const int c ){
00086         v[0] = T(a);
00087         v[1] = T(b);
00088         v[2] = T(c);
00089     }
00090     TVector( const float a, const float b, const float c ){
00091         v[0] = T(a);
00092         v[1] = T(b);
00093         v[2] = T(c);
00094     }
00095     TVector( const double a, const double b, const double c ){
00096         v[0] = T(a);
00097         v[1] = T(b);
00098         v[2] = T(c);
00099     }
00100 
00101     TVector( const T            t  ){ *this = t;  }
00102     TVector( const T           *pt ){ *this = pt; }
00103     TVector( const TVector<double> &v  ){ this->v[0] = (T)(v.v[0]); this->v[1] = (T)(v.v[1]); this->v[2] = (T)(v.v[2]); }
00104     TVector( const TVector<float>  &v  ){ this->v[0] = (T)(v.v[0]); this->v[1] = (T)(v.v[1]); this->v[2] = (T)(v.v[2]); }
00105     TVector( const TVector<int>    &v  ){ this->v[0] = (T)(v.v[0]); this->v[1] = (T)(v.v[1]); this->v[2] = (T)(v.v[2]); }
00106 //  TVector( const TVector <T> &v  ){ *this = v;  }
00107     TVector( const Quaternion  &q  ){ v[0] = (T)q.v[0]; v[1] = (T)q.v[1]; v[2] = (T)q.v[2]; }
00108 
00109     // Casting and unary operators
00110 //              operator TVector<float>  ()                    { return TVector<float>((float)v[0], (float)v[1], (float)v[2]); }
00111 //              operator TVector<double> ()                    { return TVector<double>((double)v[0], (double)v[1], (double)v[2]); }
00112                 operator              T* ()                    { return &v[0]; }
00113     T          &operator              [] ( const int n )       { return (&v[0])[n]; }
00114                 operator const        T* ()              const { return &v[0]; }
00115     T           operator              [] ( const int n ) const { return (&v[0])[n]; }
00116     TVector<T>  operator               - ()              const { return TVector<T>(-v[0], -v[1], -v[2]); }
00117 
00118     // Equal and comparison operators
00119     void operator= ( const T            t   )       { v[0] = v[1] = v[2] = t; }
00120     void operator= ( const T           *pt  )       { v[0] = pt[0]; v[1] = pt[1]; v[2] = pt[2]; }
00121     void operator= ( const TVector <T> &vec )       { v[0] = vec.v[0]; v[1] = vec.v[1]; v[2] = vec.v[2]; }
00122     bool operator==( const TVector <T> &vec ) const { return (Abs(v[0] - vec.v[0]) <= (T)0.00001f && Abs(v[1] - vec.v[1]) <= 0.00001f && Abs(v[2] - vec.v[2]) <= 0.00001f); }
00123     bool operator!=( const TVector <T> &vec ) const { return !(*this == vec); }
00124 
00125     int getMaxIndex() const {
00126         double l0 = Abs( v[0] );
00127         double l1 = Abs( v[1] );
00128         double l2 = Abs( v[2] );
00129         if( (l0 > l1) && (l0 > l2) ){
00130             return 0;
00131         }else if( (l1 > l0) && (l1 > l2) ){
00132             return 1;
00133         }else{
00134             return 2;
00135         }
00136     }
00137 
00138     // Arithmetic operators (vector with scalar)
00139           TVector<T>  operator+ ( const T t ) const { return TVector<T>(v[0]+t, v[1]+t, v[2]+t); }
00140           TVector<T>  operator- ( const T t ) const { return TVector<T>(v[0]-t, v[1]-t, v[2]-t); }
00141           TVector<T>  operator* ( const T t ) const { return TVector<T>(v[0]*t, v[1]*t, v[2]*t); }
00142           TVector<T>  operator/ ( const T t ) const { return TVector<T>(v[0]/t, v[1]/t, v[2]/t); }
00143     const TVector<T> &operator+=( const T t )       { v[0] += t; v[1] += t; v[2] += t; return *this; }
00144     const TVector<T> &operator-=( const T t )       { v[0] -= t; v[1] -= t; v[2] -= t; return *this; }
00145     const TVector<T> &operator*=( const T t )       { v[0] *= t; v[1] *= t; v[2] *= t; return *this; }
00146     const TVector<T> &operator/=( const T t )       { v[0] /= t; v[1] /= t; v[2] /= t; return *this; }
00147 
00148     // Arithmetic operators (vector with vector)
00149           TVector<T>  operator+ ( const TVector<T> &vec ) const { return TVector<T>(v[0]+vec.v[0], v[1]+vec.v[1], v[2]+vec.v[2]); }
00150           TVector<T>  operator- ( const TVector<T> &vec ) const { return TVector<T>(v[0]-vec.v[0], v[1]-vec.v[1], v[2]-vec.v[2]); }
00151           TVector<T>  operator* ( const TVector<T> &vec ) const { return TVector<T>(v[0]*vec.v[0], v[1]*vec.v[1], v[2]*vec.v[2]); }
00152           TVector<T>  operator/ ( const TVector<T> &vec ) const { return TVector<T>(v[0]/vec.v[0], v[1]/vec.v[1], v[2]/vec.v[2]); }
00153     const TVector<T> &operator+=( const TVector<T> &vec )       { v[0] += vec.v[0]; v[1] += vec.v[1]; v[2] += vec.v[2]; return *this; }
00154     const TVector<T> &operator-=( const TVector<T> &vec )       { v[0] -= vec.v[0]; v[1] -= vec.v[1]; v[2] -= vec.v[2]; return *this; }
00155     const TVector<T> &operator*=( const TVector<T> &vec )       { v[0] *= vec.v[0]; v[1] *= vec.v[1]; v[2] *= vec.v[2]; return *this; }
00156     const TVector<T> &operator/=( const TVector<T> &vec )       { v[0] /= vec.v[0]; v[1] /= vec.v[1]; v[2] /= vec.v[2]; return *this; }
00157 
00158     // Dot and cross product operators
00159           T           operator| ( const TVector<T> &vec ) const { return v[0]*vec.v[0] + v[1]*vec.v[1] + v[2]*vec.v[2]; }
00160           TVector<T>  operator^ ( const TVector<T> &vec ) const { return TVector<T>(v[1]*vec.v[2] - v[2]*vec.v[1], v[2]*vec.v[0] - v[0]*vec.v[2], v[0]*vec.v[1] - v[1]*vec.v[0]); }
00161     const TVector<T> &operator^=( const TVector<T> &vec )       { *this = *this ^ vec; return *this; }
00162 
00163     // Magnitude/distance methods
00164     T          magnitudeSquared()                        const { return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; }
00165     T          magnitude       ()                        const { return (T)sqrt(magnitudeSquared()); }
00166     T          distanceSquared ( const TVector<T> &vec ) const { return (*this - vec).magnitudeSquared(); }
00167     T          distance        ( const TVector<T> &vec ) const { return (*this - vec).magnitude(); }
00168     TVector<T> midpoint        ( const TVector<T> &vec ) const { return Vector((*this - vec) / 2 + v); }
00169     TVector<T> average         ( const TVector<T> &vec ) const { return Vector((*this + vec) / 2); }
00170 
00171     // Advanced methods (should only be used with float or double types)
00172     void       normalize()                              { *this /= magnitude(); }
00173     double     angle    ( const TVector<T> &vec ) const { return acos(*this | vec); }
00174     TVector<T> reflect  ( const TVector<T> &n   ) const {
00175         T t = (T)magnitude();
00176         TVector<T> v = *this / t;
00177         return (v - n * (2 * (v | n))) * t;
00178     }
00179 
00180     TVector<T> rotate( const T tAngle, const Vector &n ) const {
00181         T cosinus = (T)cos( tAngle );
00182         T sininus = (T)sin( tAngle );
00183         return TVector<T>(*this * tCos + ((n * *this) * (1 - tCos)) * n + (*this ^ n) * tSin);
00184     }
00185 };
00186 
00187 // Returns the normal vector of two vectors (the normalized cross product)
00188 template <class T> inline TVector<T> normalVector( const TVector<T> &v1, const TVector<T> &v2 ){
00189     TVector<T> v = v1 ^ v2;
00190     v.normalize();
00191     return v;
00192 }
00193 
00194 // Returns the normal vector of a triangle or 3 points on a plane (assumes counter-clockwise orientation)
00195 template <class T> inline TVector<T> normalVector( const TVector<T> &p1, const TVector<T> &p2, const TVector<T> &p3 ){
00196     return normalVector( p2-p1, p3-p1 );
00197 }
00198 
00199 // Returns the direction vector between two points
00200 template <class T> inline TVector<T> directionVector( const TVector<T> &p1, const TVector<T> &p2 ){
00201     TVector<T> vec = p2 - p1;
00202     vec.normalize();
00203     return vec;
00204 }
00205 
00206 
00207 #ifdef SWIG
00208 %template(Vector2)         TVector2<float>;
00209 %template(DoubleVector2)   TVector2<double>;
00210 %template(IntVector2)      TVector2<int>;
00211 #endif
00212 
00213 
00214 };  //  namespace Maths
00215 };  //  namespace Teddy
00216 
00217 
00218 #endif  //  TEDDY__MATHS__VECTOR__H
00219