GeoBases.h

00001 //Base classes for the primitives
00002 //Luke Lenhart, 2007
00003 //See /docs/License.txt for details on how this code may be used.
00004 
00005 //This file is only meant to be included by Geo.h.
00006 
00007 #pragma once
00008 #include "../base/Vary.h"
00009 
00010 namespace
00011 {
00012     // -- helpers shared between VectorN and MatrixN
00013     
00014     template <typename VecType>
00015     inline void AssignFromArray(VecType &v, const float *arr)
00016     {
00017         for (uint i=0; i<v.ElementCount(); ++i)
00018             v[i]=arr[i];
00019     }
00020     
00021     template <typename VecType>
00022     inline void AssignFromValue(VecType &v, float val)
00023     {
00024         for (uint i=0; i<v.ElementCount(); ++i)
00025             v[i]=val;
00026     }
00027 
00028     template <typename VecType>
00029     inline VecType Scale(const VecType &v, const float &s)
00030     {
00031         VecType r;
00032         for (uint i=0; i<v.ElementCount(); ++i)
00033             r[i]=v[i]*s;
00034         return r;
00035     }
00036 
00037     template <typename VecType>
00038     inline VecType Scale(const VecType &v1, const VecType &v2)
00039     {
00040         VecType r;
00041         for (uint i=0; i<v1.ElementCount(); ++i)
00042             r[i]=v1[i]*v2[i];
00043         return r;
00044     }
00045 
00046     template <typename VecType>
00047     inline VecType Add(const VecType &v1, const VecType &v2)
00048     {
00049         VecType r;
00050         for (uint i=0; i<v1.ElementCount(); ++i)
00051             r[i]=v1[i]+v2[i];
00052         return r;
00053     }
00054 
00055     template <typename VecType>
00056     inline VecType Sub(const VecType &v1, const VecType &v2)
00057     {
00058         VecType r;
00059         for (uint i=0; i<v1.ElementCount(); ++i)
00060             r[i]=v1[i]-v2[i];
00061         return r;
00062     }
00063 
00064     template <typename VecType>
00065     inline VecType Neg(const VecType &v)
00066     {
00067         VecType r;
00068         for (uint i=0; i<v.ElementCount(); ++i)
00069             r[i]=-v[i];
00070         return r;
00071     }
00072 
00073     template <typename VecType>
00074     inline VecType Div(const VecType &v1, const VecType &v2)
00075     {
00076         VecType r;
00077         for (uint i=0; i<v1.ElementCount(); ++i)
00078             r[i]=v1[i]/v2[i];
00079         return r;
00080     }
00081 
00082     template <typename VecType>
00083     inline void ScaleSelf(VecType &v, const float &s)
00084     {
00085         for (uint i=0; i<v.ElementCount(); ++i)
00086             v[i]*=s;
00087     }
00088 
00089     template <typename VecType>
00090     inline void ScaleSelf(VecType &v1, const VecType &v2)
00091     {
00092         for (uint i=0; i<v1.ElementCount(); ++i)
00093             v1[i]*=v2[i];
00094     }
00095 
00096     template <typename VecType>
00097     inline void AddSelf(VecType &v1, const VecType &v2)
00098     {
00099         for (uint i=0; i<v1.ElementCount(); ++i)
00100             v1[i]+=v2[i];
00101     }
00102 
00103     template <typename VecType>
00104     inline void SubSelf(VecType &v1, const VecType &v2)
00105     {
00106         for (uint i=0; i<v1.ElementCount(); ++i)
00107             v1[i]-=v2[i];
00108     }
00109 
00110     template <typename VecType>
00111     inline void NegSelf(VecType &v)
00112     {
00113         for (uint i=0; i<v.ElementCount(); ++i)
00114             v[i]=-v[i];
00115     }
00116 
00117     template <typename VecType>
00118     inline void DivSelf(VecType &v1, const VecType &v2)
00119     {
00120         for (uint i=0; i<v1.ElementCount(); ++i)
00121             v1[i]/=v2[i];
00122     }
00123 }
00124 
00125 namespace GEO
00126 {
00127     template <uint elemCount> struct MatrixN; //predef
00128 
00129     
00130     // -- VectorN
00131     
00133     template <uint elemCount>
00134     struct VectorN
00135     {
00136         typedef MatrixN<elemCount> MatrixType; 
00137         typedef MatrixN<elemCount+1> GreaterMatrixType; 
00138         
00139         float elements[elemCount]; 
00140         inline uint ElementCount() const { return elemCount; } 
00141         
00142         //ctors
00143         inline VectorN() {} 
00144         inline VectorN(const float *array) { AssignFromArray(*this,array); } 
00145         inline VectorN(float c) { AssignFromValue(*this,c); } 
00146         
00147         //access operators
00148         inline float& operator[](uint index) { return elements[index]; } 
00149         inline const float& operator[](uint index) const { return elements[index]; } 
00150         
00151         //binary non-altering operators
00152         inline VectorN operator*(const VectorN &o) const { return Scale(*this,o); } 
00153         inline VectorN operator*(const float &o) const { return Scale<VectorN>(*this,o); } 
00154         friend inline VectorN operator*(const float &o, const VectorN &me) { return Scale<VectorN>(me,o); } 
00155         inline VectorN operator/(const VectorN &o) const { return Div(*this,o); } 
00156         inline VectorN operator/(const float &o) const { return Scale<VectorN>(*this,1/o); } 
00157         inline VectorN operator+(const VectorN &o) const { return Add(*this,o); } 
00158         inline VectorN operator+(const float &o) const { return Add(*this,VectorN(o)); } 
00159         inline VectorN operator-(const VectorN &o) const { return Sub(*this,o); } 
00160         inline VectorN operator-(const float &o) const { return Sub(*this,VectorN(o)); } 
00161         
00162         //binary self modifying operators
00163         inline void operator*=(const VectorN &o) { ScaleSelf(*this,o); } 
00164         inline void operator*=(const float &o) { ScaleSelf<VectorN>(*this,o); } 
00165         inline void operator/=(const VectorN &o) { DivSelf(*this,o); } 
00166         inline void operator/=(const float &o) { ScaleSelf<VectorN>(*this,1/o); } 
00167         inline void operator+=(const VectorN &o) { AddSelf(*this,o); } 
00168         inline void operator+=(const float &o) { AddSelf(*this,VectorN(o)); } 
00169         inline void operator-=(const VectorN &o) { SubSelf(*this,o); } 
00170         inline void operator-=(const float &o) { SubSelf(*this,VectorN(o)); } 
00171         
00172         //unary operators
00173         inline VectorN operator-() const { return Neg(*this); } 
00174         
00175         //comparison
00176         inline friend bool operator==(const VectorN &v1, const VectorN &v2) { return NearEqual(v1,v2); } 
00177         inline friend bool operator==(const VectorN &v, const float &c) { return NearEqual(v,c); } 
00178         
00179         inline friend bool operator!=(const VectorN &v1, const VectorN &v2) { return !NearEqual(v1,v2); } 
00180         inline friend bool operator!=(const VectorN &v, const float &c) { return !NearEqual(v,c); } 
00181         
00182         //other functions
00183         inline float LengthSquared() const { return VecDot(*this,*this); } 
00184         inline float Length() const { return std::sqrt(LengthSquared()); } 
00185         inline VectorN Normal() const { return VecNormal(*this); } 
00186         inline void Normalize() { VecNormalize(*this); } 
00187         inline float Dot(const VectorN &o) const { return VecDot(*this,o); } 
00188         inline float AngleBetween(const VectorN &o) const { return VecAngleBetween(*this,o); } 
00189         inline void Transform(const MatrixType &m) const { *this=TransformVector(m,*this); } 
00190         
00191         //human readable conversion
00192         operator const std::string() const; 
00193     };
00194     
00195     template <uint elemCount>
00196     VectorN<elemCount>::operator const std::string() const
00197     {
00198         std::string s="(";
00199 
00200         for (uint i=0; i<ElementCount(); ++i)
00201         {
00202             s+=MPMA::Vary(elements[i]);
00203             if (i!=ElementCount()-1) s+=", ";
00204         }
00205 
00206         s+=")";
00207         return s;
00208     }
00209     
00210 
00211     // -- MatrixN
00212     
00214     template <uint rowCount>
00215     struct MatrixN
00216     {
00217         typedef VectorN<rowCount> VectorType; 
00218         typedef VectorN<rowCount-1> LesserVectorType; 
00219         
00220         union
00221         {
00222             float elements[rowCount*rowCount]; 
00223             float rowcol[rowCount][rowCount]; 
00224         };
00225         inline uint RowColCount() const { return rowCount; } 
00226         inline uint ElementCount() const { return rowCount*rowCount; } 
00227         
00228         //ctors
00229         inline MatrixN() {} 
00230         inline MatrixN(const float *array) { AssignFromArray(*this,array); } 
00231         inline MatrixN(float c) { AssignFromValue(*this,c); } 
00232         
00233         //proxy access class, to allow for both 1d and 2d array notation to work
00234         template <typename T, typename TRet>
00235         class Proxy
00236         {
00237         public:
00238             inline Proxy(T &mat, int ind): mat(mat), ind(ind) {}
00239             inline operator TRet&() { return mat.elements[ind]; }
00240             inline TRet& operator[](uint offset) { return mat.rowcol[ind][offset]; }
00241             void operator=(const float val) {mat.elements[ind]=val;}
00242         
00243         private:
00244             T &mat;
00245             int ind;
00246         };
00247         
00248         //access operators
00249         inline Proxy<MatrixN, float> operator[](uint ind) { return Proxy<MatrixN, float>(*this,ind); } 
00250         inline Proxy<const MatrixN, const float> operator[](uint ind) const { return Proxy<const MatrixN, const float>(*this,ind); } 
00251         
00252         inline float m(int row, int col) const { return rowcol[row][col]; } 
00253         inline float& m(int row, int col) { return rowcol[row][col]; } 
00254         
00255         //equality operators
00256         inline friend bool operator==(const MatrixN &m1, const MatrixN &m2) { return NearEqual(m1,m2); } 
00257         inline friend bool operator!=(const MatrixN &m1, const MatrixN &m2) { return !NearEqual(m1,m2); } 
00258         
00259         //access a row(direct) or column(copied out) in the matrix as a vector
00260         inline VectorType& Row(uint r) { return *(VectorType*)rowcol[r]; } 
00261         inline const VectorType& Row(uint r) const { return *(const VectorType*)rowcol[r]; } 
00262         inline const VectorType GetColumn(uint col) const; 
00263         inline void SetColumn(uint col, const VectorType &vec); 
00264         inline void SetColumn(uint col, const LesserVectorType &vec); 
00265         
00266         //binary non-altering operators
00267         inline MatrixN operator*(const float &o) const { return Scale<MatrixN>(*this,o); } 
00268         inline MatrixN operator*(const int &o) const { return Scale<MatrixN>(*this,(float)o); } 
00269         friend inline MatrixN operator*(const float &o, const MatrixN &me) { return Scale(me,o); } 
00270         inline MatrixN operator/(const float &o) const { return Scale<MatrixN>(*this,1/o); } 
00271         inline MatrixN operator/(const int &o) const { return Scale<MatrixN>(*this,1.0f/o); } 
00272         inline MatrixN operator+(const MatrixN &o) const { return Add(*this,o); } 
00273         inline MatrixN operator+(const float &o) const { return Add(*this,MatrixN(o)); } 
00274         inline MatrixN operator-(const MatrixN &o) const { return Sub(*this,o); } 
00275         inline MatrixN operator-(const float &o) const { return Sub(*this,MatrixN(o)); } 
00276         
00277         inline MatrixN operator-() const { return Neg(*this); } 
00278         
00279         //binary self-modifying operators
00280         inline void operator*=(const float &o) { ScaleSelf<MatrixN>(*this,o); } 
00281         inline void operator/=(const float &o) { ScaleSelf<MatrixN>(*this,1/o); } 
00282         inline void operator+=(const MatrixN &o) { AddSelf(*this,o); } 
00283         inline void operator+=(const float &o) { AddSelf(*this,MatrixN(o)); } 
00284         inline void operator-=(const MatrixN &o) { SubSelf(*this,o); } 
00285         inline void operator-=(const float &o) { SubSelf(*this,MatrixN(o)); } 
00286         
00287         //other operators
00288         inline MatrixN operator*(const MatrixN &o) const { return MatMul(*this,o); } 
00289         inline void operator*=(const MatrixN &o) { *this=MatMul(*this,o); } 
00290         inline VectorType operator*(const VectorType &v) const { return TransformVector(*this,v); } 
00291         
00292         //other operations
00293         inline MatrixN Transpose() const; 
00294         inline void SetTranspose(); 
00295         inline void MakeIdentity(); 
00296         inline LesserVectorType GetTranslation() const { return LesserVectorType(GetColumn(RowColCount()-1)); } 
00297         inline void SetTranslation(const LesserVectorType &v) { SetColumn(RowColCount()-1,v); } 
00298 
00299         //human readable conversion
00300         operator const std::string() const; 
00301     };
00302     
00303     template <uint rowCount>
00304     inline const typename MatrixN<rowCount>::VectorType MatrixN<rowCount>::GetColumn(uint col) const
00305     {
00306         VectorType vec;
00307         for (uint i=0; i<RowColCount(); ++i)
00308             vec[i]=rowcol[i][col];
00309         return vec;
00310     }
00311     
00312     template <uint rowCount>
00313     inline void MatrixN<rowCount>::SetColumn(uint col, const VectorType &vec)
00314     {
00315         for (uint i=0; i<RowColCount(); ++i)
00316             rowcol[i][col]=vec[i];
00317     }
00318     
00319     template <uint rowCount>
00320     inline void MatrixN<rowCount>::SetColumn(uint col, const LesserVectorType &vec)
00321     {
00322         for (uint i=0; i<vec.ElementCount(); ++i)
00323             rowcol[i][col]=vec[i];
00324     }
00325     
00326     template <uint rowCount>
00327     MatrixN<rowCount> MatrixN<rowCount>::Transpose() const
00328     {
00329         return MatTranspose(*this);
00330     }
00331     
00332     template <uint rowCount>
00333     void MatrixN<rowCount>::SetTranspose()
00334     {
00335         //swap the rows and cols, leaving the diagonal alone
00336         for (uint r=1; r<RowColCount(); ++r)
00337         {
00338             for (uint c=0; c<r; ++c)
00339             {
00340                 float tmp=rowcol[r][c];
00341                 rowcol[r][c]=rowcol[c][r];
00342                 rowcol[c][r]=tmp;
00343             }
00344         }
00345     }
00346     
00347     template <uint rowCount>
00348     inline void MatrixN<rowCount>::MakeIdentity()
00349     {
00350         for (uint x=0; x<RowColCount(); ++x)
00351             for (uint y=0; y<RowColCount(); ++y)
00352                 rowcol[x][y]=0;
00353 
00354         for (uint i=0; i<RowColCount(); ++i)
00355             rowcol[i][i]=1;
00356     }
00357     
00358     template <uint rowCount>
00359     MatrixN<rowCount>::operator const std::string() const
00360     {
00361         std::string s="[";
00362         for (uint i=0; i<RowColCount(); ++i)
00363         {
00364             s+=Row(i);
00365             if (i!=RowColCount()-1) s+=", ";
00366         }
00367 
00368         s+="]";
00369         return s;
00370     }
00371     
00372 } //namespace GEO

Generated on Sat Aug 9 15:05:05 2008 for MPMA Framework by  doxygen 1.5.6