ParabolicConstraint.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_CONSTRAINT_PARABOLICCONSTRAINT_INL
00026 #define SOFA_COMPONENT_CONSTRAINT_PARABOLICCONSTRAINT_INL
00027 
00028 #include <sofa/component/constraint/ParabolicConstraint.h>
00029 #include <sofa/helper/gl/template.h>
00030 
00031 namespace sofa
00032 {
00033 
00034 namespace component
00035 {
00036 
00037 namespace constraint
00038 {
00039 
00040 using namespace sofa::defaulttype;
00041 using namespace sofa::helper;
00042 
00043 template <class DataTypes>
00044 ParabolicConstraint<DataTypes>::ParabolicConstraint()
00045 :core::componentmodel::behavior::Constraint<DataTypes>(NULL)
00046 , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
00047 , m_P1(initData(&m_P1,"P1","first point of the parabol") )
00048 , m_P2(initData(&m_P2,"P2","second point of the parabol") )
00049 , m_P3(initData(&m_P3,"P3","third point of the parabol") )
00050 , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") )
00051 , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") )
00052 {
00053 }
00054 
00055 
00056 template <class DataTypes>
00057 ParabolicConstraint<DataTypes>::ParabolicConstraint(core::componentmodel::behavior::MechanicalState<DataTypes>* mstate)
00058 : core::componentmodel::behavior::Constraint<DataTypes>(mstate)
00059 , m_indices( initData(&m_indices,"indices","Indices of the constrained points") )
00060 , m_P1(initData(&m_P1,"P1","first point of the parabol") )
00061 , m_P2(initData(&m_P2,"P2","second point of the parabol") )
00062 , m_P3(initData(&m_P3,"P3","third point of the parabol") )
00063 , m_tBegin(initData(&m_tBegin,"BeginTime","Begin Time of the motion") )
00064 , m_tEnd(initData(&m_tEnd,"EndTime","End Time of the motion") )
00065 {
00066 }
00067 
00068 template <class DataTypes>
00069 ParabolicConstraint<DataTypes>::~ParabolicConstraint()
00070 {
00071 }
00072 
00073 template <class DataTypes>
00074 void  ParabolicConstraint<DataTypes>::addConstraint(unsigned index)
00075 {
00076     m_indices.beginEdit()->push_back(index);
00077     m_indices.endEdit();
00078 }
00079 
00080 
00081 template <class DataTypes>
00082 void ParabolicConstraint<DataTypes>::init()
00083 {
00084     this->core::componentmodel::behavior::Constraint<DataTypes>::init();
00085 
00086     Vec3R P1 = m_P1.getValue();
00087     Vec3R P2 = m_P2.getValue();
00088     Vec3R P3 = m_P3.getValue();
00089 
00090     //compute the projection to go in the parabol plan,
00091     //such as P1 is the origin, P1P3 vector is the x axis, and P1P2 is in the xy plan
00092     //by the way the computation of the parabol equation is much easier
00093     if(P1 != P2 && P1 != P3 && P2 != P3){
00094 
00095         Vec3R P1P2 = P2 - P1;
00096         Vec3R P1P3 = P3 - P1;
00097 
00098         Vec3R ax = P1P3;
00099         Vec3R az = cross(P1P3, P1P2);
00100         Vec3R ay = cross(az, ax);
00101         ax.normalize();
00102         ay.normalize();
00103         az.normalize();
00104 
00105         Mat<3,3,Real> Mrot(ax, ay, az);
00106         Mat<3,3,Real> Mrot2;
00107         Mrot2.transpose(Mrot);
00108         m_projection.fromMatrix(Mrot2);
00109         m_projection.normalize();
00110 
00111         m_locP1 = Vec3R();
00112         m_locP2 =  m_projection.inverseRotate(P1P2);
00113         m_locP3 =  m_projection.inverseRotate(P1P3);
00114     }
00115 }
00116 
00117 template <class DataTypes>
00118 void ParabolicConstraint<DataTypes>::reinit()
00119 {
00120     init();
00121 }
00122 
00123 
00124 template <class DataTypes>
00125 void ParabolicConstraint<DataTypes>::projectResponse(VecDeriv& dx)
00126 {
00127     Real t = (Real) getContext()->getTime();
00128     if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue())
00129     {
00130         const SetIndexArray & indices = m_indices.getValue().getArray();
00131         for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00132             dx[*it] = Deriv();
00133     }
00134 }
00135 
00136 template <class DataTypes>
00137 void ParabolicConstraint<DataTypes>::projectVelocity(VecDeriv& dx)
00138 {
00139     Real t = (Real) getContext()->getTime();
00140     Real dt = (Real) getContext()->getDt();
00141 
00142     if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() )
00143     {
00144         Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00145         const SetIndexArray & indices = m_indices.getValue().getArray();
00146 
00147         for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00148         {
00149             //compute velocity by doing v = dx/dt
00150             Real pxP = m_locP3.x()*relativeTime;
00151             Real pyP = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxP *pxP) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxP;
00152             relativeTime = (t+dt - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00153             Real pxN = m_locP3.x()*relativeTime;
00154             Real pyN = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (pxN *pxN) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * pxN;
00155 
00156             Vec3R locVel = Vec3R( (pxN-pxP)/dt, (pyN-pyP)/dt, 0.0);
00157 
00158             Vec3R worldVel = m_projection.rotate(locVel);
00159 
00160             dx[*it] = worldVel;
00161         }
00162     }
00163 }
00164 
00165 template <class DataTypes>
00166 void ParabolicConstraint<DataTypes>::projectPosition(VecCoord& x)
00167 {
00168     Real t = (Real) getContext()->getTime();
00169 
00170     if ( t >= m_tBegin.getValue() && t <= m_tEnd.getValue() )
00171     {
00172         Real relativeTime = (t - m_tBegin.getValue() ) / (m_tEnd.getValue() - m_tBegin.getValue());
00173         const SetIndexArray & indices = m_indices.getValue().getArray();
00174 
00175         for(SetIndexArray::const_iterator it = indices.begin(); it != indices.end(); ++it)
00176         {
00177             //compute position from the equation of the parabol : Y = -y2/(x3*x2-x2²) * X² + (x3*y2)/(x3*x2-x2²) * X
00178             //with P1:(0,0,0), P2:(x2,y2,z2), P3:(x3,y3,z3) , projected in parabol plan
00179             Real px = m_locP3.x()*relativeTime;
00180             Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00181             Vec3R locPos( px , py, 0.0);
00182 
00183             //projection to world coordinates
00184             Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00185 
00186             x[*it] = worldPos;
00187         }
00188     }
00189 }
00190 
00191 
00192 template <class DataTypes>
00193 void ParabolicConstraint<DataTypes>::draw()
00194 {
00195     if (!getContext()->getShowBehaviorModels()) return;
00196 
00197     Real dt = (Real) getContext()->getDt();
00198     Real t = m_tEnd.getValue() - m_tBegin.getValue();
00199     Real nbStep = t/dt;
00200 
00201     glDisable (GL_LIGHTING);
00202     glPointSize(5);
00203     glColor4f (1,0.5,0.5,1);
00204 
00205     glBegin (GL_LINES);
00206     for (unsigned int i=0 ; i< nbStep ; i++){
00207         //draw lines between each step of the parabolic trajectory
00208         //so, the smaller is dt, the finer is the parabol
00209         Real relativeTime = i/nbStep;
00210         Real px = m_locP3.x()*relativeTime;
00211         Real py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00212         Vec3R locPos( px , py, 0.0);
00213         Vec3R worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00214         
00215         gl::glVertexT(worldPos);
00216 
00217         relativeTime = (i+1)/nbStep;
00218         px = m_locP3.x()*relativeTime;
00219         py = (- m_locP2.y() / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * (px *px) + ( (m_locP3.x()*m_locP2.y()) / (m_locP3.x()*m_locP2.x() - m_locP2.x()*m_locP2.x())) * px;
00220         locPos = Vec3R( px , py, 0.0);
00221         worldPos = m_P1.getValue() + m_projection.rotate(locPos);
00222         gl::glVertexT(worldPos);
00223     }
00224     glEnd();
00225 
00226     //draw points for the 3 control points
00227     glBegin(GL_POINTS);
00228     gl::glVertexT(m_P1.getValue());
00229     gl::glVertexT(m_P2.getValue());
00230     gl::glVertexT(m_P3.getValue());
00231     glEnd();
00232 }
00233 
00234 
00235 } // namespace constraint
00236 
00237 } // namespace component
00238 
00239 } // namespace sofa
00240 
00241 #endif

Generated on Sun Nov 23 02:45:13 2008 for Sofa by  doxygen 1.5.7.1