proximity.cpp

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 #include "proximity.h"
00026 #include <sofa/helper/LCPSolver.inl>
00027 
00028 namespace sofa
00029 {
00030 
00031 namespace component
00032 {
00033 
00034 namespace collision
00035 {
00036 
00037 using namespace sofa::helper;
00038 
00039 //------------------------
00040 // DISTANCETRITRI
00041 /*
00042  aP = alphaP, bP = betaP are the barycentric coordinates of point P on triangle P
00043  aQ = alphaQ, bQ = betaQ are the barycentric coordinates of point Q on triangle Q
00044 
00045  the computation of the distance between P and Q can be done with:
00046 
00047 QP^2 = [aP bP aQ bQ] * [P1P2*P1P2 P1P2*P1P3 -P1P2*Q1Q2 -P1P2*Q1Q3 * [aP bP aQ bQ]^T 
00048                                    P1P3*P1P3 -P1P3*Q1Q2 -P1P3*Q1Q3
00049                         sym                  Q1Q2*Q1Q2  Q1Q2*Q1Q3
00050                                                         Q1Q3*Q1Q3]
00051   + [Q1P1*P1P2 Q1P1*P1P3 -Q1P1*P1Q2 -Q1P1*P1Q3] *[aP bP aQ bQ]^T + (Q1P1)^2
00052 
00053   P and Q are on triangles, so we have the constraints:
00054 aP>=0, bP>=0, aQ>=0, bQ>=0
00055 aP+bP<=1, aQ+bQ<=1 <=> -aP-bP>=-1 , -aQ-bQ>=-1
00056 
00057 To perform min(QP^2) we use LCP formalism
00058 
00059 */
00060 //------------------------
00061 
00062 DistanceTriTri::
00063 DistanceTriTri()
00064 {
00065 }
00066 
00067 DistanceTriTri::
00068 ~DistanceTriTri()
00069 {
00070 }
00071 
00072 
00073 
00074 void DistanceTriTri::
00075 NewComputation(Triangle *triP, Triangle *triQ, Vector3 &Presult, Vector3 &Qresult)
00076 {
00077     Vector3 P1, P2, P3, Q1, Q2, Q3;
00078     P1 = triP->p1();
00079     P2 = triP->p2();
00080     P3 = triP->p3();
00081     Q1 = triQ->p1();
00082     Q2 = triQ->p2();
00083     Q3 = triQ->p3();
00084 
00085     double alphaP, betaP, alphaQ, betaQ;
00086     int i;
00087     Vector3 P1P2, P1P3, Q1Q2, Q1Q3, P1Q1, PQ;
00088     LCPSolver<6>::Matrix  A; 
00089     double          b[6], result[12];
00090     LCPSolver<6>          lcp;
00091 
00092     // clear result
00093     for (i=0; i<12; i++){
00094         result[i] = 0.0;
00095     }
00096             
00097 
00098     P1P2=P2 - P1;
00099     P1P3=P3 - P1;
00100     Q1Q2=Q2 - Q1;
00101     Q1Q3=Q3 - Q1;
00102     P1Q1=Q1 - P1;
00103 
00104     A[0][4] = 1.0; A[4][0] = -1.0;
00105     A[1][4] = 1.0; A[4][1] = -1.0;
00106     A[2][4] = 0.0; A[4][2] = 0.0;
00107     A[3][4] = 0.0; A[4][3] = 0.0;
00108 
00109     A[0][5] = 0.0; A[5][0] = 0.0;
00110     A[1][5] = 0.0; A[5][1] = 0.0;
00111     A[2][5] = 1.0; A[5][2] = -1.0;
00112     A[3][5] = 1.0; A[5][3] = -1.0;
00113     
00114     A[4][4] = 0.0; A[5][5] = 0.0;
00115     A[4][5] = 0.0; A[5][4] = 0.0;
00116 
00117     A[0][0] = dot(P1P2,P1P2);   A[0][1] = dot(P1P3,P1P2);   A[0][2] =-dot(Q1Q2,P1P2);  A[0][3] =-dot(Q1Q3,P1P2);
00118     A[1][0] = dot(P1P2,P1P3);   A[1][1] = dot(P1P3,P1P3);   A[1][2] =-dot(Q1Q2,P1P3);  A[1][3] =-dot(Q1Q3,P1P3);
00119     A[2][0] = -dot(P1P2,Q1Q2);  A[2][1] = -dot(P1P3,Q1Q2);  A[2][2] = dot(Q1Q2,Q1Q2);  A[2][3] = dot(Q1Q3,Q1Q2);
00120     A[3][0] = -dot(P1P2,Q1Q3);  A[3][1] = -dot(P1P3,Q1Q3);  A[3][2] = dot(Q1Q2,Q1Q3);  A[3][3] = dot(Q1Q3,Q1Q3);
00121 
00122     b[0]=-dot(P1Q1,P1P2);  b[1]=-dot(P1Q1,P1P3);  b[2]= dot(P1Q1,Q1Q2); b[3]= dot(P1Q1,Q1Q3);
00123     b[4]=1.0;  b[5]=1.0;
00124 
00125     if(lcp.solve(b, A, result)==1)
00126     {
00127         alphaP=result[6];
00128         betaP=result[7];
00129         alphaQ=result[8];
00130         betaQ=result[9];
00131         Presult = P1 + P1P2*alphaP + P1P3*betaP;
00132         Qresult = Q1 + Q1Q2*alphaQ + Q1Q3*betaQ;
00133     }
00134     else
00135     {
00136         printf(" no result from LCP !\n");
00137         alphaP=0.0;
00138         betaP=0.0; 
00139         alphaQ=0.0;
00140         betaQ=0.0;
00141         Presult = P1;
00142         Qresult = Q1;
00143     }
00144     
00145 
00146 }
00147 
00148 
00149 //------------------------
00150 // DISTANCESEGTRI
00151 //------------------------
00152 
00153 DistanceSegTri::
00154 DistanceSegTri()
00155 {
00156 }
00157 
00158 DistanceSegTri::
00159 ~DistanceSegTri()
00160 {
00161 }
00162 
00163 void DistanceSegTri::
00164 NewComputation(Triangle *tri, const Vector3 &Q1, const Vector3 &Q2, Vector3 &Presult, Vector3 &Qresult)
00165 {
00166     double alpha, beta, gamma;
00167     int i;
00168     Vector3 P1, P2, P3;
00169     P1 = tri->p1();
00170     P2 = tri->p2();
00171     P3 = tri->p3();
00172     //Point Presult, Qresult;
00173 
00174     Vector3 P1P2, P1P3, Q1Q2, P1Q1, PQ;
00175     LCPSolver<5>::Matrix  A; 
00176     double          b[5], result[10];
00177     LCPSolver<5>          lcp;
00178 
00179     for (i=0; i<10; i++){
00180         result[i] = 0.0;
00181     }
00182 
00183     Q1Q2 = Q2 - Q1;
00184     P1P2 = P2 - P1;
00185     P1P3 = P3 - P1;
00186     P1Q1 = Q1 - P1;
00187 
00188 
00189     // initialize A
00190     A[0][3] = 1.0; A[0][4] = 0.0;
00191     A[1][3] = 1.0; A[1][4] = 0.0;
00192     A[2][3] = 0.0; A[2][4] = 1.0;
00193     A[3][0] = -1.0; A[3][1] = -1.0; A[3][2] = 0.0;  A[3][3] = 0.0; A[3][4] = 0.0;
00194     A[4][0] = 0.0; A[4][1] = 0.0;   A[4][2] = -1.0; A[4][3] = 0.0; A[4][4] = 0.0;
00195 
00196     A[0][0] = dot(P1P2,P1P2);   A[0][1] = dot(P1P3,P1P2);   A[0][2] = -dot(Q1Q2,P1P2);  
00197     A[1][0] = dot(P1P2,P1P3);   A[1][1] = dot(P1P3,P1P3);   A[1][2] = -dot(Q1Q2,P1P3);  
00198     A[2][0] = -dot(P1P2,Q1Q2);  A[2][1] = -dot(P1P3,Q1Q2);  A[2][2] = dot(Q1Q2,Q1Q2);  
00199 
00200     // initialize b
00201     b[3]=1.0;  b[4]=1.0;
00202     b[0]=-dot(P1Q1,P1P2);  b[1]=-dot(P1Q1,P1P3);  b[2]=dot(P1Q1,Q1Q2);
00203 
00204     if(lcp.solve(b, A, result))
00205     {
00206         alpha=result[5];
00207         beta=result[6];
00208         gamma=result[7];
00209 
00210         Presult = P1 + P1P2*alpha + P1P3*beta;
00211         Qresult = Q1 + Q1Q2*gamma;
00212     }
00213     else
00214     {
00215         printf(" no result from LCP !\n");
00216         alpha=0;
00217         beta=0; 
00218         gamma=0;
00219         Presult = P1;
00220         Qresult = Q1;
00221     }
00222 
00223 }
00224 
00225 //------------------------------------------------------------------------------------------------------ //
00226 // ---------------------------------------- DISTANCEPOINTTRI ------------------------------------------- //
00227 //------------------------------------------------------------------------------------------------------ //
00228 
00229 
00230 DistancePointTri::
00231 DistancePointTri()
00232 {
00233 }
00234 
00235 DistancePointTri::
00236 ~DistancePointTri()
00237 {
00238 }
00239 
00240 void DistancePointTri::
00241 NewComputation(Triangle *tri, const Vector3 &Q, Vector3 &Presult)
00242 {
00243     double alpha, beta;
00244     int i;
00245 
00246     Vector3 P1, P2, P3;
00247 
00248     Vector3 P1P2, P1P3, P1Q;
00249     LCPSolver<3>::Matrix  A; 
00250     double          b[3], result[6];
00251     LCPSolver<3>    lcp;
00252 
00253     P1 = tri->p1();
00254     P2 = tri->p2();
00255     P3 = tri->p3();
00256 
00257 
00258     for (i=0; i<6; i++){
00259         result[i] = 0.0;
00260     }
00261 
00262     P1P2 = P2 - P1;
00263     P1P3 = P3 - P1;
00264     P1Q = Q - P1;
00265 
00266     // initialize A
00267     A[0][2] = 1.0; 
00268     A[1][2] = 1.0; 
00269     A[2][0] = -1.0; A[2][1] = -1.0; A[2][2] = 0.0;  
00270     A[0][0] = dot(P1P2,P1P2);   A[0][1] = dot(P1P3,P1P2);   
00271     A[1][0] = dot(P1P2,P1P3);   A[1][1] = dot(P1P3,P1P3);   
00272 
00273     // initialize b
00274     b[2]=1.0;  
00275     b[0]=-dot(P1Q,P1P2);  b[1]=-dot(P1Q,P1P3); 
00276 
00277     if(lcp.solve(b, A, result))
00278     {
00279         alpha=result[3];
00280         beta=result[4];
00281 
00282         Presult = P1 + P1P2*alpha + P1P3*beta;
00283     }
00284     else
00285     {
00286         printf(" no result from LCP !\n");
00287         alpha=0;
00288         beta=0; 
00289         Presult = P1;
00290     }
00291 }
00292 
00293 
00294 } // namespace collision
00295 
00296 } // namespace component
00297 
00298 } // namespace sofa

Generated on Sun Nov 23 02:34:36 2008 for Sofa by  doxygen 1.5.7.1