InteractionEllipsoidForceField.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_FORCEFIELD_INTERACTION_ELLIPSOIDFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_INTERACTION_ELLIPSOIDFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include "InteractionEllipsoidForceField.h"
00030 #include <sofa/helper/gl/template.h>
00031 #include <sofa/helper/system/config.h>
00032 #include <sofa/helper/system/glut.h>
00033 #include <sofa/helper/rmath.h>
00034 #include <assert.h>
00035 #include <iostream>
00036 
00037 namespace sofa
00038 {
00039 
00040 namespace component
00041 {
00042 
00043 namespace interactionforcefield
00044 {
00045 
00046 // v = sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1
00047 // dv/dxj = xj/rj� * 1/sqrt(x0�/r0�+x1�/r1�+x2�/r2�)
00048 
00049 // f  = -stiffness * v * (dv/dp) / norm(dv/dp)
00050 
00051 // fi = -stiffness * (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1) * (xi/ri�) / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00052 
00053 // dfi/dxj = -stiffness * [ d(sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)/dxj *   (xi/ri�) / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00054 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)     * d(xi/ri�)/dxj / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00055 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)     *  (xi/ri�) * d(1/sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4))/dxj ]
00056 // dfi/dxj = -stiffness * [ xj/rj� * 1/sqrt(x0�/r0�+x1�/r1�+x2�/r2�) * (xi/ri�) / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00057 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)       * (i==j)/ri� / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00058 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)       * (xi/ri�) * (-1/2*2xj/rj^4*1/(x0�/r0^4+x1�/r1^4+x2�/r2^4) ]
00059 // dfi/dxj = -stiffness * [ xj/rj� * 1/sqrt(x0�/r0�+x1�/r1�+x2�/r2�) * (xi/ri�) / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00060 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)       * (i==j)/ri� / sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4)
00061 //                          +  (sqrt(x0�/r0�+x1�/r1�+x2�/r2�)-1)       * (xi/ri�) * (-xj/rj^4*1/(x0�/r0^4+x1�/r1^4+x2�/r2^4) ]
00062 
00063 // dfi/dxj = -stiffness * [ (xj/rj�) * (xi/ri�) * 1/(sqrt(x0�/r0�+x1�/r1�+x2�/r2�) * sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4))
00064 //                          +  v       * (i==j) / (ri�*sqrt(x0�/r0^4+x1�/r1^4+x2�/r2^4))
00065 //                          +  v       * (xi/ri�) * (xj/rj�) * 1/(rj�*(x0�/r0^4+x1�/r1^4+x2�/r2^4) ]
00066 
00067 
00068 template<class DataTypes1, class DataTypes2>
00069 void InteractionEllipsoidForceField<DataTypes1, DataTypes2>::initCalcF()
00070 {
00071     vars.r = this->vradius.getValue();
00072     vars.stiffness = this->stiffness.getValue();
00073     vars.stiffabs =  helper::rabs(vars.stiffness);
00074     for (int j=0; j<N; j++) vars.inv_r2[j] = 1/(vars.r[j]*vars.r[j]);
00075 
00076     //printf("\n **********************");
00077     //printf("\n vars.inv_r2 = %f %f %f", vars.inv_r2[0], vars.inv_r2[1], vars.inv_r2[2]);
00078 }
00079 
00080 template<class DataTypes1, class DataTypes2>
00081 bool InteractionEllipsoidForceField<DataTypes1, DataTypes2>::calcF(const Coord1& p1, const Deriv1& v1, Deriv1 &f1, Mat& dfdx)
00082 {
00083         Coord1 dp = p1 - vars.center;
00084         Real1 norm2 = 0;
00085         for (int j=0; j<N; j++) norm2 += (dp[j]*dp[j])*vars.inv_r2[j];
00086         //Real1 d = (norm2-1)*s2;
00087         if ((norm2-1)*vars.stiffness<0)
00088         {
00089             //printf("\n norm2 = %f", norm2);
00090             //printf("\n dp = %f %f %f   p1 = %f %f %f   vars.center = %f %f %f", dp[0], dp[1], dp[2],
00091             //  p1.x(),p1.y(), p1.z(), vars.center.x(), vars.center.y(), vars.center.z());
00092 
00093             Real1 norm = helper::rsqrt(norm2);
00094             Real1 v = norm-1;
00095             Deriv1 grad;
00096             for (int j=0; j<N; j++) grad[j] = dp[j]*vars.inv_r2[j];
00097             Real1 gnorm2 = grad.norm2();
00098             Real1 gnorm = helper::rsqrt(gnorm2);
00099             //grad /= gnorm; //.normalize();
00100             Real1 forceIntensity = -vars.stiffabs*v/gnorm;
00101             Real1 dampingIntensity = this->damping.getValue()*helper::rabs(v);
00102             Deriv1 force = grad*forceIntensity - v1*dampingIntensity;
00103             f1=force;
00104             Real1 fact1 = -vars.stiffabs / (norm * gnorm);
00105             Real1 fact2 = -vars.stiffabs*v / gnorm;
00106             Real1 fact3 = -vars.stiffabs*v / gnorm2;
00107             for (int ci = 0; ci < N; ++ci)
00108             {
00109                 for (int cj = 0; cj < N; ++cj)
00110                     dfdx[ci][cj] = grad[ci]*grad[cj] * (fact1 + fact3*vars.inv_r2[cj]);
00111                 dfdx[ci][ci] += fact2*vars.inv_r2[ci];
00112             }
00113             return true;
00114         }
00115         else
00116             return false;
00117 }
00118 
00119 template<class DataTypes1, class DataTypes2>
00120 void InteractionEllipsoidForceField<DataTypes1, DataTypes2>::addForce(VecDeriv1& f1, VecDeriv2& f2, 
00121                                                                       const VecCoord1& p1, const VecCoord2& p2, 
00122                                                                       const VecDeriv1& v1, const VecDeriv2& v2)
00123 {
00124 
00125     // debug;
00126     X1 = p1;
00127     X2 = p2;
00128 
00129     vars.pos6D = p2[object2_dof_index.getValue()];
00130     Quat Cq = vars.pos6D.getOrientation();
00131     Vec3d Cx = (Coord1) vars.pos6D.getCenter();
00132     Deriv2 V6D = v2[object2_dof_index.getValue()];
00133     Vec3d Cv = (Vec3d) V6D.getVCenter();
00134     Cv.clear();
00135 
00137     _orientation = Cq;
00138     //_orientation.clear();
00139     //Cq.clear();
00141 
00142 
00143     if(_update_pos_relative)
00144     {
00145         //_update_pos_relative = false;
00146         //Vec3d OC = (Vec3d) center.getValue() - Cx;
00147         //OC = Cq.inverseRotate(OC);
00148         vars.center = (Vec3d) center.getValue(); // position locale du point 
00149         //printf("\n OC : %f %f %f",OC.x(),OC.y(),OC.z());
00150         Cv.clear();
00151     }
00152 
00153     initCalcF();
00154 
00155     //const Real1 s2 = (stiff < 0 ? - stiff*stiff : stiff*stiff );
00156     sofa::helper::vector<Contact>* contacts = this->contacts.beginEdit();
00157     contacts->clear();
00158     f1.resize(p1.size());
00159     for (unsigned int i=0; i<p1.size(); i++)
00160     {
00161         Coord1 p1Xform = Cq.inverseRotate(p1[i] - Cx);
00162 
00163         Deriv1 v1Xform = Cq.inverseRotate(v1[i]);
00164         Deriv1 f1Xform;
00165         f1Xform.clear();
00166         Mat dfdx;
00167         if (calcF(p1Xform, v1Xform, f1Xform, dfdx) && !_update_pos_relative)
00168         {
00169             //printf("\n p1[%d] : %f %f %f p1Xform[%d] : %f %f %f",i, p1[i].x(), p1[i].y(), p1[i].z(),i, p1Xform.x(),p1Xform.y(),p1Xform.z());
00170 
00171             Contact c;
00172             c.pos = p1[i];
00173             c.index = i;
00174             c.m = dfdx;
00175 
00176             Vec3d contactForce =  Cq.rotate(f1Xform);
00177             f1[i]+=contactForce;
00178             f2[object2_dof_index.getValue()].getVCenter() -= contactForce;
00179             c.bras_levier = p1[i] - Cx;
00180             //f2[object2_dof_index.getValue()].getVOrientation() -= c.bras_levier.cross(contactForce);
00181             contacts->push_back(c);
00182             /*
00183             printf("\n contactForce : %f %f %f, bras_Levier : %f %f %f, f2 = %f %f %f - %f %f %f", 
00184                 contactForce.x(), contactForce.y(), contactForce.z(),
00185                 c.bras_levier.x(), c.bras_levier.y(), c.bras_levier.z(),
00186                 f2[object2_dof_index.getValue()].getVCenter().x(), f2[object2_dof_index.getValue()].getVCenter().y(), f2[object2_dof_index.getValue()].getVCenter().z(),
00187                 f2[object2_dof_index.getValue()].getVOrientation().x(), f2[object2_dof_index.getValue()].getVOrientation().y(), f2[object2_dof_index.getValue()].getVOrientation().z());
00188             */
00189 
00190         }
00191     }
00192 /*
00193     printf("\n f2 = %f %f %f - %f %f %f", 
00194         f2[object2_dof_index.getValue()].getVCenter().x(), f2[object2_dof_index.getValue()].getVCenter().y(), f2[object2_dof_index.getValue()].getVCenter().z(),
00195         f2[object2_dof_index.getValue()].getVOrientation().x(), f2[object2_dof_index.getValue()].getVOrientation().y(), f2[object2_dof_index.getValue()].getVOrientation().z());
00196 */
00197 /*
00198     printf("\n verify addForce2 : ");
00199     addForce2(f1, f2, p1, p2, v1, v2);
00200     printf("\n f2 = %f %f %f - %f %f %f", 
00201         f2[object2_dof_index.getValue()].getVCenter().x(), f2[object2_dof_index.getValue()].getVCenter().y(), f2[object2_dof_index.getValue()].getVCenter().z(),
00202         f2[object2_dof_index.getValue()].getVOrientation().x(), f2[object2_dof_index.getValue()].getVOrientation().y(), f2[object2_dof_index.getValue()].getVOrientation().z());
00203 */
00204 
00205 
00206     if(_update_pos_relative)
00207     {
00208         f2[object2_dof_index.getValue()].getVCenter().clear();
00209         f2[object2_dof_index.getValue()].getVOrientation().clear();
00210         _update_pos_relative = false;
00211     }
00212     this->contacts.endEdit();
00213 }
00214 
00215 template<class DataTypes1, class DataTypes2>
00216 void InteractionEllipsoidForceField<DataTypes1, DataTypes2>::addForce2(VecDeriv1& f1, VecDeriv2& f2, 
00217                                                                       const VecCoord1& p1, const VecCoord2& p2, 
00218                                                                       const VecDeriv1& v1, const VecDeriv2& /* v2 */)
00219 {
00220 
00221     Quat Cq = p2[object2_dof_index.getValue()].getOrientation();
00222     Vec3d Cx = (Coord1) p2[object2_dof_index.getValue()].getCenter();
00223 
00224     f1.clear();
00225     f2.clear();
00226     f1.resize(p1.size());
00227     f2.resize(p2.size());
00228     for (unsigned int i=0; i<p1.size(); i++)
00229     {
00230         Coord1 p1Xform = Cq.inverseRotate(p1[i] - Cx);
00231 
00232         Deriv1 v1Xform = Cq.inverseRotate(v1[i]);
00233         Deriv1 f1Xform;
00234         f1Xform.clear();
00235         Mat dfdx;
00236         if (calcF(p1Xform, v1Xform, f1Xform, dfdx))
00237         {
00238 
00239 
00240             Vec3d contactForce =  Cq.rotate(f1Xform);
00241             Vec3d bras_levier;
00242             bras_levier = p1[i] - Cx;
00243             f1[i]+=contactForce;
00244             f2[object2_dof_index.getValue()].getVCenter() -= contactForce;
00245             f2[object2_dof_index.getValue()].getVOrientation() -= bras_levier.cross(contactForce);
00246 
00247 
00248         }
00249     }
00250 
00251 
00252 
00253 }
00254 
00255 
00256 template<class DataTypes1, class DataTypes2>
00257 void InteractionEllipsoidForceField<DataTypes1, DataTypes2>::addDForce(VecDeriv1& df1, VecDeriv2& df2, const VecDeriv1& dx1, const VecDeriv2& dx2)
00258 {
00259     
00260     df1.resize(dx1.size());
00261     df2.resize(dx2.size());
00262     const sofa::helper::vector<Contact>& contacts = this->contacts.getValue();
00263     //printf("\n");
00264     for (unsigned int i=0; i<contacts.size(); i++)
00265     {
00266         const Contact& c = contacts[i];
00267         assert((unsigned)c.index<dx1.size());
00268         Vec3d du;
00269         du = (Vec3d) dx1[c.index] - (Vec3d) dx2[object2_dof_index.getValue()].getVCenter(); //- c.bras_levier.cross(dx2[object2_dof_index.getValue()].getVOrientation());
00270         Deriv1 dforce = c.m * _orientation.inverseRotate(du);
00271         Vec3d DF = _orientation.rotate(dforce);
00272         df1[c.index] += DF;
00273         df2[object2_dof_index.getValue()].getVCenter()  -= DF;
00274         //df2[object2_dof_index.getValue()].getVOrientation()  -= c.bras_levier.cross(DF);
00275         //printf(" bras_levier[%d] = %f %f %f  - ", i, c.bras_levier.x(), c.bras_levier.y(), c.bras_levier.z());
00276     }
00277    
00278 
00279 }
00280 
00281 template <class DataTypes1, class DataTypes2> 
00282     double InteractionEllipsoidForceField<DataTypes1, DataTypes2>::getPotentialEnergy(const VecCoord1& /* x1 */, const VecCoord2& /* x2 */)
00283 {
00284     std::cerr<<"InteractionEllipsoidForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00285     return 0;
00286 }
00287 
00288 template<class DataTypes1, class DataTypes2>
00289 void InteractionEllipsoidForceField<DataTypes1, DataTypes2>::draw()
00290 {
00291     if (!getContext()->getShowForceFields()) return;
00292     if (!bDraw.getValue()) return;
00293 
00294     Real1 cx1=0, cy1=0, cz1=0;
00295     Real1 cx2=0, cy2=0, cz2=0;
00296     DataTypes1::get(cx1, cy1, cz1, vars.center );
00297 
00298     //cx1 -=vars.pos6D.getCenter()[0];
00299     //cy1 -=vars.pos6D.getCenter()[1];
00300     //cz1 -=vars.pos6D.getCenter()[2];
00301 
00302     cx2=vars.pos6D.getCenter()[0];
00303     cy2=vars.pos6D.getCenter()[1];
00304     cz2=vars.pos6D.getCenter()[2];
00305 
00306 
00307     Real1 rx=1, ry=1, rz=1;
00308     DataTypes1::get(rx, ry, rz, vradius.getValue());
00309     glEnable(GL_CULL_FACE);
00310     glEnable(GL_LIGHTING);
00311     glEnable(GL_COLOR_MATERIAL);
00312     glColor3f(color.getValue()[0],color.getValue()[1],color.getValue()[2]);
00313 
00314 
00315     Quat q=vars.pos6D.getOrientation();
00316 #ifdef SOFA_FLOAT
00317     GLfloat R[4][4];
00318 #else
00319     GLdouble R[4][4];
00320 #endif
00321     Quat q1=q.inverse();
00322     q1.buildRotationMatrix(R);
00323 
00324     glPushMatrix();
00325     helper::gl::glTranslate(cx2, cy2, cz2);
00326     helper::gl::glMultMatrix( &(R[0][0]) );
00327     helper::gl::glTranslate(cx1, cy1, cz1);
00328     helper::gl::glScale(rx, ry, (stiffness.getValue()>0?rz:-rz));
00329     glutSolidSphere(1,32,16);
00330     //glTranslated(-cx2, -cy2, -cz2);
00331 
00332     glPopMatrix();
00333     glDisable(GL_CULL_FACE);
00334     glDisable(GL_LIGHTING);
00335     glDisable(GL_COLOR_MATERIAL);
00336 
00337     const sofa::helper::vector<Contact>& contacts = this->contacts.getValue();
00338     for (unsigned int i=0; i<contacts.size(); i++)
00339     {   
00340          glPointSize(10);
00341          glColor4f (1,0.5,0.5,1);
00342         glBegin (GL_POINTS);
00343         glVertex3d(contacts[i].pos[0],contacts[i].pos[1],contacts[i].pos[2] );
00344         glEnd();
00345     }
00346 
00347 }
00348 
00349 
00350 } // namespace forcefield
00351 
00352 } // namespace component
00353 
00354 } // namespace sofa
00355 
00356 #endif

Generated on Sun Nov 23 03:23:44 2008 for Sofa by  doxygen 1.5.7.1