00001
00002
00003
00004 #include "jmath/ublasExtra.hpp"
00005
00006 namespace jafar {
00007 namespace geom {
00008
00009 template<int dimension>
00010 Repere<dimension>::VectorsDriver::VectorsDriver(const Repere<dimension>* ref) :
00011 Driver( )
00012 {
00013 m_matrix = jblas::identity_mat(dimension + 1, dimension + 1);
00014 m_reference = ref;
00015 }
00016
00017 template<int dimension>
00018 Repere<dimension>::VectorsDriver::VectorsDriver(const Repere<dimension>* ref, const typename Repere<dimension>::HomogenousVecD* repere, const typename Repere<dimension>::HomogenousVecD& origin) : Driver( )
00019 {
00020 for(int i = 0; i < dimension; i++)
00021 {
00022 ublas::matrix_column<MatrixD> mc( m_matrix, i);
00023 HomogenousVecD v = repere[i];
00024 for(int j = 0; j < i; j++)
00025 {
00026 ublas::matrix_column<MatrixD> u( m_matrix, j);
00027 v -= ublas::inner_prod(repere[i], u) * u;
00028 }
00029 v(dimension) = 0.0;
00030 mc = v / ublas::norm_2(v);
00031 }
00032 ublas::matrix_column<MatrixD> mcOrig( m_matrix, dimension);
00033 mcOrig = origin;
00034 mcOrig /= mcOrig( dimension);
00035 m_reference = ref;
00036 }
00037 template<int dimension>
00038 const Repere<dimension>* Repere<dimension>::VectorsDriver::reference() const
00039 {
00040 return m_reference;
00041 }
00042 template<int dimension>
00043 typename Repere<dimension>::HomogenousVecD Repere<dimension>::VectorsDriver::origin() const
00044 {
00045 return ublas::matrix_column<const MatrixD>( m_matrix, dimension);
00046 }
00047 template<int dimension>
00048 typename Repere<dimension>::HomogenousVecD Repere<dimension>::VectorsDriver::vec(unsigned int index) const
00049 {
00050 return ublas::matrix_column<const MatrixD>( m_matrix, index);
00051 }
00052 template<int dimension>
00053 void Repere<dimension>::VectorsDriver::localToReference(typename Repere<dimension>::MatrixD& dst) const
00054 {
00055 dst.assign(m_matrix);
00056 }
00057
00058
00059 template<int dimension>
00060 Repere<dimension>* Repere<dimension>::s_globalRef = 0;
00061 template<int dimension>
00062 inline const Repere<dimension>* Repere<dimension>::global()
00063 {
00064 return (s_globalRef == 0) ? (s_globalRef = new Repere<dimension>( )) : s_globalRef;
00065 }
00066
00067
00068 template<int dimension>
00069 Repere<dimension>::Repere() : Atom<dimension>(0), m_driver(new VectorsDriver(0))
00070 {
00071 Atom<dimension>::setDriver( m_driver);
00072 JFR_ASSERT(not s_globalRef, "Global reference allready exist");
00073 }
00074 template<int dimension>
00075 Repere<dimension>::Repere(Driver* driver) : Atom<dimension>(driver), m_driver(driver)
00076 {
00077 JFR_ASSERT(reference(), "Repere can't have a null reference, unless its the global reference");
00078 }
00079 template<int dimension>
00080 Repere<dimension>::~Repere()
00081 {
00082 }
00083 template<int dimension>
00084 inline BoundingBox<dimension> Repere<dimension>::boundingBox() const
00085 {
00086 HomogenousVecD v = this->reference()->convertInGlobal( this->origin());
00087 return BoundingBox<dimension>(v, v);
00088 }
00089 template<int dimension>
00090 inline const Repere<dimension>* Repere<dimension>::reference() const
00091 {
00092 return m_driver->reference();
00093 }
00094 template<int dimension>
00095 inline typename Repere<dimension>::HomogenousVecD Repere<dimension>::origin() const
00096 {
00097 return m_driver->origin();
00098 }
00099 template<int dimension>
00100 inline typename Repere<dimension>::HomogenousVecD Repere<dimension>::vec(unsigned int index) const
00101 {
00102 JFR_ASSERT(index < dimension, "Index bigger than dimension");
00103 return m_driver->vec(index);
00104 }
00105 template<int dimension>
00106 inline typename Repere<dimension>::HomogenousVecD Repere<dimension>::convertIn( const HomogenousVecD& v, const Repere* dstRepere) const
00107 {
00108 if(dstRepere == this)
00109 {
00110 return v;
00111 } else {
00112 MatrixD m;
00113 this->localToRepere( m, dstRepere);
00114 return ublas::prod(m, v );
00115 }
00116 }
00117 template<int dimension>
00118 inline typename Repere<dimension>::HomogenousVecD Repere<dimension>::convertInGlobal( const HomogenousVecD& v) const
00119 {
00120 if( this == global())
00121 {
00122 return v;
00123 } else {
00124 MatrixD m;
00125 this->localToGlobal( m);
00126 return ublas::prod(m, v );
00127 }
00128 }
00129 template<int dimension>
00130 inline void Repere<dimension>::localToReference(typename Repere<dimension>::MatrixD& dst) const
00131 {
00132 JFR_ASSERT(m_driver, "No driver");
00133 return m_driver->localToReference(dst);
00134 }
00135 template<int dimension>
00136 inline void Repere<dimension>::referenceToLocal(typename Repere<dimension>::MatrixD& dst) const
00137 {
00138 MatrixD lTR;
00139 localToReference(lTR);
00140 jmath::ublasExtra::inv(lTR, dst );
00141 }
00142 template<int dimension>
00143 inline void Repere<dimension>::localToGlobal(typename Repere<dimension>::MatrixD& dst) const
00144 {
00145 localToReference( dst );
00146 if(this == global() ) return;
00147 const Repere<dimension>* ref = this;
00148 MatrixD m;
00149 while( (ref = ref->reference() ) != global() ) {
00150 ref->localToReference( m );
00151 dst = ublas::prod( m, dst);
00152 }
00153 }
00154 template<int dimension>
00155 inline void Repere<dimension>::globalToLocal(typename Repere<dimension>::MatrixD& dst) const
00156 {
00157 MatrixD lTG;
00158 localToGlobal(lTG);
00159 jmath::ublasExtra::inv(lTG, dst );
00160 }
00161 template<int dimension>
00162 inline void Repere<dimension>::localToRepere(typename Repere<dimension>::MatrixD& dst, const Repere* r) const
00163 {
00164 if( r == global() )
00165 {
00166 localToGlobal(dst);
00167 } else {
00168
00169 MatrixD gTR;
00170 r->globalToLocal(gTR);
00171
00172 MatrixD lTG;
00173 localToGlobal(lTG);
00174
00175 dst = ublas::prod( gTR, lTG );
00176 }
00177 }
00178 template<int dimension>
00179 inline void Repere<dimension>::repereToLocal(typename Repere<dimension>::MatrixD& dst, const Repere* r) const
00180 {
00181 if( r == global() )
00182 {
00183 globalToLocal(dst);
00184 } else {
00185
00186 MatrixD gTL;
00187 globalToLocal(gTL);
00188
00189 MatrixD rTG;
00190 r->localToGlobal(rTG);
00191
00192 dst = ublas::prod( gTL, rTG );
00193 }
00194 }
00195 }
00196 }
00197