00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
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
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
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
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
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
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
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
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
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 }
00295
00296 }
00297
00298 }