ConicalForceField.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_SPHEREFORCEFIELD_INL
00026 #define SOFA_COMPONENT_FORCEFIELD_SPHEREFORCEFIELD_INL
00027 
00028 #include <sofa/core/componentmodel/behavior/ForceField.inl>
00029 #include <sofa/component/forcefield/ConicalForceField.h>
00030 #include <sofa/defaulttype/Quat.h>
00031 
00032 #include <sofa/helper/system/config.h>
00033 #include <sofa/helper/rmath.h>
00034 #include <sofa/helper/system/gl.h>
00035 #include <sofa/helper/system/glut.h>
00036 #include <assert.h>
00037 #include <iostream>
00038 
00039 namespace sofa
00040 {
00041 
00042 namespace component
00043 {
00044 
00045 namespace forcefield
00046 {
00047 
00048 template<class DataTypes>
00049 void ConicalForceField<DataTypes>::addForce(VecDeriv& f1, const VecCoord& p1, const VecDeriv& v1)
00050 {
00051     const Coord center = coneCenter.getValue();
00052     Real d = 0.0;
00053     Real alpha = 0.0;
00054     Real length_cp_prime = 0.0;
00055     Coord p, p_prime, cp, dir, n_cp, cp_new, cp_prime, pp_prime, t;
00056     Coord n = coneHeight.getValue();
00057     n.normalize();
00058     Deriv force;
00059     
00060     this->contacts.beginEdit()->clear();
00061     f1.resize(p1.size());
00062     for (unsigned int i=0; i<p1.size(); i++)
00063     {
00064         p = p1[i];
00065         if (!isIn(p))
00066     {
00067         cp = p - center;
00068         //below the cone
00069         if (cp.norm() >  coneHeight.getValue().norm())
00070             {
00071             Real norm = cp.norm();
00072                 d = norm - coneHeight.getValue().norm();
00073             dir = cp / norm;
00074                     Real forceIntensity = -this->stiffness.getValue()*d;
00075                     Real dampingIntensity = -this->damping.getValue()*d;
00076                     force = cp*(forceIntensity/norm) - v1[i]*dampingIntensity;
00077                     f1[i]+=force;
00078                     Contact c;
00079                     c.index = i;
00080                     c.normal = cp / norm;
00081                     c.pos = p;
00082                     this->contacts.beginEdit()->push_back(c);
00083         
00084         }   
00085         else {
00086             //side of the cone
00087             if (dot(cp,n) > 0)
00088             {
00089                 n_cp = cp/cp.norm();
00090                 alpha = acos(n_cp*n) - coneAngle.getValue()*3.1459/180 ;
00091                 t = n.cross(cp) ;
00092                 t /= t.norm();
00093                 defaulttype::Quat q(t, -alpha);
00094                 cp_new = q.rotate(cp);
00095                 
00096                 cp_new.normalize();
00097                 length_cp_prime = dot(cp_new, cp);
00098                 cp_prime = cp_new * length_cp_prime;
00099                 p_prime = cp_prime + center;
00100                 
00101                 pp_prime = p_prime - p;
00102                 d = pp_prime.norm();
00103                 dir = pp_prime/pp_prime.norm();
00104                 //std::cout << t << " " << alpha << std::endl;
00105             }
00106             //top of the cone
00107             else
00108             {
00109                 d = cp.norm();
00110                 dir = (-cp)/cp.norm();
00111             }
00112 
00113         force = dir * (stiffness.getValue()*d);
00114         force += dir * (damping.getValue() * (-dot(dir,v1[i])));
00115         f1[i] += force;
00116         Contact c;
00117         c.index = i;
00118         c.normal = dir;
00119         c.pos = p;
00120         //c.fact = r / norm;
00121             this->contacts.beginEdit()->push_back(c);
00122         }
00123         }
00124     }
00125     this->contacts.endEdit();
00126 }
00127 
00128 template<class DataTypes>
00129 void ConicalForceField<DataTypes>::addDForce(VecDeriv& df1, const VecDeriv& dx1)
00130 {
00131     df1.resize(dx1.size());
00132     for (unsigned int i=0; i<this->contacts.getValue().size(); i++)
00133     {
00134         const Contact& c = (*this->contacts.beginEdit())[i];
00135         assert((unsigned)c.index<dx1.size());
00136         Deriv du = dx1[c.index];
00137         Deriv dforce; dforce = -this->stiffness.getValue()*(c.normal * ((du*c.normal)));
00138         df1[c.index] += dforce;
00139     }
00140     this->contacts.endEdit();
00141 }
00142 
00143 template<class DataTypes>
00144 void ConicalForceField<DataTypes>::updateStiffness( const VecCoord&  )
00145 {
00146     std::cerr<<"SphereForceField::updateStiffness-not-implemented !!!"<<std::endl;
00147 }
00148 
00149 template <class DataTypes> 
00150     double ConicalForceField<DataTypes>::getPotentialEnergy(const VecCoord&)
00151 {
00152     std::cerr<<"ConicalForceField::getPotentialEnergy-not-implemented !!!"<<std::endl;
00153     return 0;
00154 }
00155 
00156 template<class DataTypes>
00157 void ConicalForceField<DataTypes>::draw()
00158 {
00159     if (!getContext()->getShowForceFields()) return;
00160     if (!bDraw.getValue()) return;
00161 
00162     const Real a = coneAngle.getValue();
00163     Coord height = coneHeight.getValue();
00164     const Real h = sqrt(pow(coneHeight.getValue()[0],2) + pow(coneHeight.getValue()[1],2) + pow(coneHeight.getValue()[2],2));
00165     const Real b = tan((a/180*3.14)) * h;
00166     const Coord c = coneCenter.getValue();
00167     Coord axis = height.cross(Coord(0,0,1));
00168     
00169     glEnable(GL_LIGHTING);
00170     glEnable(GL_COLOR_MATERIAL);
00171     glEnable(GL_BLEND) ;
00172     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; 
00173     glColor4f(color.getValue()[0],color.getValue()[1],color.getValue()[2], 0.5);
00174     
00175     glPushMatrix();
00176     glTranslated(c[0], c[1], c[2]); 
00177     glRotated(acos(height*Coord(0,0,1)/h)*180/3.14 ,-axis[0], axis[1], axis[2]);
00178     glRotatef(180.0,1.0,0.0,0.0);
00179     glTranslated(0.0, 0.0, -h); 
00180 
00181     glutSolidCone( b, h, 32, 16);
00182     glPopMatrix();
00183 
00184 /*    glPushMatrix();
00185 
00186     glColor3f(1.0,0.0,0.0);
00187     glPointSize (16.0); 
00188     glBegin (GL_POINTS);
00189     for (unsigned int i = 0 ; i <contacts.getValue().size() ; i++)
00190     {
00191     
00192     glVertex3f(contacts.getValue()[i].pos[0], contacts.getValue()[i].pos[1],contacts.getValue()[i].pos[2]);
00193     //glVertex3f(contacts.getValue()[i].pos[0]+contacts.getValue()[i].normal[0],
00194     //     contacts.getValue()[i].pos[1]+contacts.getValue()[i].normal[1],
00195     //     contacts.getValue()[i].pos[2]+contacts.getValue()[i].normal[2]);
00196     
00197     }
00198     glEnd();
00199     glPopMatrix();*/
00200     glDisable(GL_BLEND) ;
00201     glDisable(GL_LIGHTING);
00202     glDisable(GL_COLOR_MATERIAL);
00203 }
00204 
00205 template<class DataTypes>
00206 bool ConicalForceField<DataTypes>::isIn(Coord p)
00207 {
00208     const Coord c = coneCenter.getValue();
00209     const Coord height = coneHeight.getValue();
00210     const Real h = sqrt(pow(height[0],2) + pow(height[1],2) + pow(height[2],2));
00211     const Real distP = sqrt(pow(p[0] - c[0], 2) + pow(p[1] - c[1], 2) + pow(p[2] - c[2], 2));
00212 
00213     if (distP > h){
00214         return false;
00215     }
00216     Coord vecP;
00217     
00218     for(unsigned i=0 ; i<3 ; ++i)
00219         vecP[i]=p[i]-c[i];
00220     
00221     if ( (acos(vecP*height/(h*distP))*180/3.14) > coneAngle.getValue() ){
00222         
00223         return false;
00224     }
00225     return true;
00226 }
00227 
00228 } // namespace forcefield
00229 
00230 } // namespace component
00231 
00232 } // namespace sofa
00233 
00234 #endif

Generated on Sun Nov 23 02:53:21 2008 for Sofa by  doxygen 1.5.7.1