AnimaL |
Tutorial |
Documentation |
00001 #include "ParametersCalculus.h" 00002 #include "SFVec3fCellConstrained.h" 00003 #include "ConstrainedVertex.h" 00004 00005 00006 #include <animal/vectorVec.h> 00007 #include "octree_instanciation.h" 00008 00009 namespace animal 00010 { 00011 namespace octree 00012 { 00013 00014 ParametersCalculus::ParametersCalculus( Cell *cell, HermiteFunction hf ) : 00015 _cell(cell), _hf(hf) 00016 { 00017 } 00018 ParametersCalculus::~ParametersCalculus() 00019 { 00020 } 00021 00022 /* 00023 * Get alpha, beta, gamma in the cell given the 3d points Q 00024 */ 00025 Vec3d ParametersCalculus::getParameters( Vec3d Q, Vec3d initialParameters, unsigned int maxIterations, FloatingPointType threshold ) 00026 { 00027 00028 Vec3d res; 00029 00030 00031 /* 00032 res = initialParameters; 00033 00034 00035 unsigned int it=0; 00036 CellFrames cf( _cell ); 00037 Vec3d Fx; 00038 FloatingPointType precNorm = INFINITY; 00039 do 00040 { 00041 FloatingPointType fAlpha = _hf.compute( res[0] ); 00042 FloatingPointType fBeta = _hf.compute( res[1] ); 00043 FloatingPointType fGamma = _hf.compute( res[2] ); 00044 00045 FloatingPointType fAlpha_ = _hf.computeDerivative( res[0] ); 00046 FloatingPointType fBeta_ = _hf.computeDerivative( res[1] ); 00047 FloatingPointType fGamma_ = _hf.computeDerivative( res[2] ); 00048 00049 00050 //dAlphaCoeffs stores the i coefficients associated to 00051 //f'({1-,}alpha) . f({1-,}beta) . f({1-,}gamma). 00052 //They're the same for x, y and z 00053 //As we know that f(1-x) = 1-f(x) so we can say that f'(1-x) = (1-f(x))' = -f'(x) 00054 FloatingPointType dAlphaCoeffs[8], dBetaCoeffs[8], dGammaCoeffs[8]; 00055 for( unsigned int i=0 ; i<8 ; ++i ) 00056 { 00057 // (((i%2)==0)?1:-1) will give 1 if we have alpha and -1 if we have 1-alpha 00058 // And so on 00059 dAlphaCoeffs[i] = (((i%2)==0)?1:-1)*fAlpha_ * LINEARFACTORBETA(i,fBeta) * LINEARFACTORGAMMA(i,fGamma); 00060 dBetaCoeffs[i] = LINEARFACTORALPHA(i,fAlpha) * (((i%4)<=1)?1:-1)*fBeta_ * LINEARFACTORGAMMA(i,fGamma); 00061 dGammaCoeffs[i] = LINEARFACTORALPHA(i,fAlpha) * LINEARFACTORBETA(i,fBeta) * ((i<=3)?1:-1)*fGamma_; 00062 } 00063 00064 // Ok, now these are the second part coefficients namely f({1-,}alpha) . f({1-,}beta) . f({1-,}gamma) 00065 // They're constant for d alpha, d beta and d gamma and the 3 dimensions 00066 FloatingPointType secondCoeffs[8]; 00067 for( unsigned int i=0 ; i<8 ; ++i ) 00068 { 00069 secondCoeffs[i] = LINEARFACTORALPHA(i,fAlpha) * LINEARFACTORBETA(i,fBeta) * LINEARFACTORGAMMA(i,fGamma); 00070 } 00071 00072 Vec3d Qi[8]; 00073 for( unsigned int i=0 ; i<8 ; ++i ) 00074 { 00075 Qi[i] = _cell->vertex(i)->getPosition() + LINEARFACTORALPHA(i,res[0])*cf.getFrame(i)[0] + LINEARFACTORBETA(i,res[1])*cf.getFrame(i)[1] + LINEARFACTORGAMMA(i,res[2])*cf.getFrame(i)[2]; 00076 } 00077 00078 // Now, d Qi(alpha,beta,gamma) / d alpha is quite easily 00079 // +- ui 00080 // where ui is the frame's vector associated to x 00081 // so ((i%2)==0)?1:-1) will give the good sign and cf.getFrame(i)[0] will give ui 00082 // and so on 00083 00084 Vec3d jacOnAlpha, jacOnBeta, jacOnGamma; 00085 for( unsigned int i=0 ; i<8 ; ++i ) 00086 { 00087 jacOnAlpha += dAlphaCoeffs[i]*Qi[i] + secondCoeffs[i] * (((i%2)==0)?1:-1) * cf.getFrame(i,false)[0]; 00088 jacOnBeta += dBetaCoeffs[i]*Qi[i] + secondCoeffs[i] * (((i%4)<=1)?1:-1) * cf.getFrame(i,false)[1]; 00089 jacOnGamma += dGammaCoeffs[i]*Qi[i] + secondCoeffs[i] * ((i<=3)?1:-1) * cf.getFrame(i,false)[2]; 00090 } 00091 00092 Mat Jx(3,3); 00093 for(unsigned int i=0 ; i<3 ; ++i ) 00094 { 00095 Jx[i][0] = jacOnAlpha[i]; 00096 Jx[i][1] = jacOnBeta[i]; 00097 Jx[i][2] = jacOnGamma[i]; 00098 } 00099 00100 Vec3d pos = computePosition( res ); 00101 00102 Fx = pos - Q; 00103 00104 00105 // Compute delta 00106 Mat JxtJx(3,3), LU(3,3), LU_1(3,3); 00107 m_eq_AtB(JxtJx,Jx,Jx); 00108 m_eq_ludcmp( LU, JxtJx ); 00109 animal::Vec3 aux; 00110 m_eq_luinv( LU_1, LU, aux ); 00111 00112 Mat B(3,3); 00113 m_eq_ABt(B,LU_1,Jx); 00114 00115 animal::Vec3 Fxv; Fxv[0] = Fx[0]; Fxv[1] = Fx[1]; Fxv[2] = Fx[2]; 00116 m_teq( B, -1.0 ); 00117 00118 animal::Vec3 deltaResv; 00119 v_eq_Ab(deltaResv,B,Fxv); 00120 00121 Vec3d deltaRes; deltaRes[0] = deltaResv[0]; deltaRes[1] = deltaResv[1]; deltaRes[2] = deltaResv[2]; 00122 00123 res += deltaRes/2; 00124 it++; 00125 00126 //Require( Fx.norm() < precNorm ); 00127 precNorm = Fx.norm(); 00128 } 00129 while( (Fx.norm() > threshold) && (it<maxIterations) ); 00130 00131 if( it == maxIterations ) 00132 { 00133 std::cerr << "MAx iterations reached !\n"; 00134 } 00135 00136 //std::cerr << "Final params are " << res << "\n"; 00137 */ 00138 return res; 00139 } 00140 00141 00142 Vec3d ParametersCalculus::computePosition( Vec3d parameters ) 00143 { 00144 00145 Vec3d vRes; 00146 /* 00147 CellFrames cf( _cell ); 00148 Vec3d P[8]; 00149 for( unsigned short i=0 ; i<8 ; ++i ) 00150 { 00151 Vec3d localParams( LINEARFACTORALPHA(i,parameters[0]), LINEARFACTORBETA(i,parameters[1]), LINEARFACTORGAMMA(i,parameters[2]) ); 00152 00153 P[i] = cf.computePosition( i, false, localParams ); 00154 } 00155 00156 FloatingPointType weightSum = 0.0; 00157 for( unsigned short i=0 ; i<8 ; ++i ) 00158 { 00159 Vec3d localParams( LINEARFACTORALPHA(i,parameters[0]), LINEARFACTORBETA(i,parameters[1]), LINEARFACTORGAMMA(i,parameters[2]) ); 00160 00161 FloatingPointType weight = hf.compute(localParams[0]) * hf.compute(localParams[1]) * hf.compute(localParams[2]); 00162 00163 vRes += weight * P[i]; 00164 weightSum += weight; 00165 } 00166 00167 vRes /= weightSum; 00168 00169 return vRes; 00170 00171 */ 00172 } 00173 00174 00175 00176 } 00177 }