GeoBases.h

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