Biomechanical Joint Model
 Author: Anderson Maciel

overlap.cpp

Go to the documentation of this file.
00001 /*************************************************************************\
00002 
00003   Copyright 1995 The University of North Carolina at Chapel Hill.
00004   All Rights Reserved.
00005 
00006   Permission to use, copy, modify and distribute this software and its
00007   documentation for educational, research and non-profit purposes, without
00008    fee, and without a written agreement is hereby granted, provided that the
00009   above copyright notice and the following three paragraphs appear in all
00010   copies.
00011 
00012   IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL BE
00013   LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
00014   CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE
00015   USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY
00016   OF NORTH CAROLINA HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
00017   DAMAGES.
00018 
00019   THE UNIVERSITY OF NORTH CAROLINA SPECIFICALLY DISCLAIM ANY
00020   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00021   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
00022   PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
00023   NORTH CAROLINA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
00024   UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00025 
00026   The authors may be contacted via:
00027 
00028   US Mail:             S. Gottschalk
00029                        Department of Computer Science
00030                        Sitterson Hall, CB #3175
00031                        University of N. Carolina
00032                        Chapel Hill, NC 27599-3175
00033 
00034   Phone:               (919)962-1749
00035 
00036   EMail:              {gottscha}@cs.unc.edu
00037 
00038 
00039 \**************************************************************************/
00040 
00041 
00042 #include "RAPID_version.H"
00043 
00044 static char rapidtag_data[] = "RAPIDTAG  file: "__FILE__"    date: "__DATE__"    time: "__TIME__;
00045 
00046 // to silence the compiler's complaints about unreferenced identifiers.
00047 static void r1(char *f){  r1(f);  r1(rapidtag_data);  r1(rapid_version);}
00048 
00049 #include "matvec.H"
00050 
00051 inline
00052 double
00053 max(double a, double b, double c)
00054 {
00055   double t = a;
00056   if (b > t) t = b;
00057   if (c > t) t = c;
00058   return t;
00059 }
00060 
00061 inline
00062 double
00063 min(double a, double b, double c)
00064 {
00065   double t = a;
00066   if (b < t) t = b;
00067   if (c < t) t = c;
00068   return t;
00069 }
00070 
00071 
00072 int
00073 project6(double *ax, 
00074          double *p1, double *p2, double *p3, 
00075          double *q1, double *q2, double *q3)
00076 {
00077   double P1 = VdotV(ax, p1);
00078   double P2 = VdotV(ax, p2);
00079   double P3 = VdotV(ax, p3);
00080   double Q1 = VdotV(ax, q1);
00081   double Q2 = VdotV(ax, q2);
00082   double Q3 = VdotV(ax, q3);
00083   
00084   double mx1 = max(P1, P2, P3);
00085   double mn1 = min(P1, P2, P3);
00086   double mx2 = max(Q1, Q2, Q3);
00087   double mn2 = min(Q1, Q2, Q3);
00088 
00089   if (mn1 > mx2) return 0;
00090   if (mn2 > mx1) return 0;
00091   return 1;
00092 }
00093 
00094 
00095 // very robust triangle intersection test
00096 // uses no divisions
00097 // works on coplanar triangles
00098 
00099 int 
00100 tri_contact (double *P1, double *P2, double *P3,
00101                     double *Q1, double *Q2, double *Q3) 
00102 {
00103 
00104   /*
00105      One triangle is (p1,p2,p3).  Other is (q1,q2,q3).
00106      Edges are (e1,e2,e3) and (f1,f2,f3).
00107      Normals are n1 and m1
00108      Outwards are (g1,g2,g3) and (h1,h2,h3).
00109 
00110      We assume that the triangle vertices are in the same coordinate system.
00111 
00112      First thing we do is establish a new c.s. so that p1 is at (0,0,0).
00113 
00114      */
00115 
00116   double p1[3], p2[3], p3[3];
00117   double q1[3], q2[3], q3[3];
00118   double e1[3], e2[3], e3[3];
00119   double f1[3], f2[3], f3[3];
00120   double g1[3], g2[3], g3[3];
00121   double h1[3], h2[3], h3[3];
00122   double n1[3], m1[3];
00123   double z[3];
00124 
00125   double ef11[3], ef12[3], ef13[3];
00126   double ef21[3], ef22[3], ef23[3];
00127   double ef31[3], ef32[3], ef33[3];
00128   
00129   z[0] = 0.0;  z[1] = 0.0;  z[2] = 0.0;
00130   
00131   p1[0] = P1[0] - P1[0];  p1[1] = P1[1] - P1[1];  p1[2] = P1[2] - P1[2];
00132   p2[0] = P2[0] - P1[0];  p2[1] = P2[1] - P1[1];  p2[2] = P2[2] - P1[2];
00133   p3[0] = P3[0] - P1[0];  p3[1] = P3[1] - P1[1];  p3[2] = P3[2] - P1[2];
00134   
00135   q1[0] = Q1[0] - P1[0];  q1[1] = Q1[1] - P1[1];  q1[2] = Q1[2] - P1[2];
00136   q2[0] = Q2[0] - P1[0];  q2[1] = Q2[1] - P1[1];  q2[2] = Q2[2] - P1[2];
00137   q3[0] = Q3[0] - P1[0];  q3[1] = Q3[1] - P1[1];  q3[2] = Q3[2] - P1[2];
00138   
00139   e1[0] = p2[0] - p1[0];  e1[1] = p2[1] - p1[1];  e1[2] = p2[2] - p1[2];
00140   e2[0] = p3[0] - p2[0];  e2[1] = p3[1] - p2[1];  e2[2] = p3[2] - p2[2];
00141   e3[0] = p1[0] - p3[0];  e3[1] = p1[1] - p3[1];  e3[2] = p1[2] - p3[2];
00142 
00143   f1[0] = q2[0] - q1[0];  f1[1] = q2[1] - q1[1];  f1[2] = q2[2] - q1[2];
00144   f2[0] = q3[0] - q2[0];  f2[1] = q3[1] - q2[1];  f2[2] = q3[2] - q2[2];
00145   f3[0] = q1[0] - q3[0];  f3[1] = q1[1] - q3[1];  f3[2] = q1[2] - q3[2];
00146   
00147   VcrossV(n1, e1, e2);
00148   VcrossV(m1, f1, f2);
00149 
00150   VcrossV(g1, e1, n1);
00151   VcrossV(g2, e2, n1);
00152   VcrossV(g3, e3, n1);
00153   VcrossV(h1, f1, m1);
00154   VcrossV(h2, f2, m1);
00155   VcrossV(h3, f3, m1);
00156 
00157   VcrossV(ef11, e1, f1);
00158   VcrossV(ef12, e1, f2);
00159   VcrossV(ef13, e1, f3);
00160   VcrossV(ef21, e2, f1);
00161   VcrossV(ef22, e2, f2);
00162   VcrossV(ef23, e2, f3);
00163   VcrossV(ef31, e3, f1);
00164   VcrossV(ef32, e3, f2);
00165   VcrossV(ef33, e3, f3);
00166   
00167   // now begin the series of tests
00168 
00169   if (!project6(n1, p1, p2, p3, q1, q2, q3)) return 0;
00170   if (!project6(m1, p1, p2, p3, q1, q2, q3)) return 0;
00171   
00172   if (!project6(ef11, p1, p2, p3, q1, q2, q3)) return 0;
00173   if (!project6(ef12, p1, p2, p3, q1, q2, q3)) return 0;
00174   if (!project6(ef13, p1, p2, p3, q1, q2, q3)) return 0;
00175   if (!project6(ef21, p1, p2, p3, q1, q2, q3)) return 0;
00176   if (!project6(ef22, p1, p2, p3, q1, q2, q3)) return 0;
00177   if (!project6(ef23, p1, p2, p3, q1, q2, q3)) return 0;
00178   if (!project6(ef31, p1, p2, p3, q1, q2, q3)) return 0;
00179   if (!project6(ef32, p1, p2, p3, q1, q2, q3)) return 0;
00180   if (!project6(ef33, p1, p2, p3, q1, q2, q3)) return 0;
00181 
00182   if (!project6(g1, p1, p2, p3, q1, q2, q3)) return 0;
00183   if (!project6(g2, p1, p2, p3, q1, q2, q3)) return 0;
00184   if (!project6(g3, p1, p2, p3, q1, q2, q3)) return 0;
00185   if (!project6(h1, p1, p2, p3, q1, q2, q3)) return 0;
00186   if (!project6(h2, p1, p2, p3, q1, q2, q3)) return 0;
00187   if (!project6(h3, p1, p2, p3, q1, q2, q3)) return 0;
00188 
00189   return 1;
00190 }
00191 
00192 
00193 
00194 /*
00195 
00196 int
00197 obb_disjoint(double B[3][3], double T[3], double a[3], double b[3]);
00198 
00199 This is a test between two boxes, box A and box B.  It is assumed that
00200 the coordinate system is aligned and centered on box A.  The 3x3
00201 matrix B specifies box B's orientation with respect to box A.
00202 Specifically, the columns of B are the basis vectors (axis vectors) of
00203 box B.  The center of box B is located at the vector T.  The
00204 dimensions of box B are given in the array b.  The orientation and
00205 placement of box A, in this coordinate system, are the identity matrix
00206 and zero vector, respectively, so they need not be specified.  The
00207 dimensions of box A are given in array a.
00208 
00209 This test operates in two modes, depending on how the library is
00210 compiled.  It indicates whether the two boxes are overlapping, by
00211 returning a boolean.  
00212 
00213 The second version of the routine will return a conservative bounds on
00214 the distance between the polygon sets which the boxes enclose.  It is
00215 used when RAPID is being used to estimate the distance between two
00216 models.
00217 
00218 */
00219 
00220 
00221 int
00222 obb_disjoint(double B[3][3], double T[3], double a[3], double b[3])
00223 {
00224   register double t, s;
00225   register int r;
00226   double Bf[3][3];
00227   const double reps = 1e-6;
00228   
00229   // Bf = fabs(B)
00230   Bf[0][0] = myfabs(B[0][0]);  Bf[0][0] += reps;
00231   Bf[0][1] = myfabs(B[0][1]);  Bf[0][1] += reps;
00232   Bf[0][2] = myfabs(B[0][2]);  Bf[0][2] += reps;
00233   Bf[1][0] = myfabs(B[1][0]);  Bf[1][0] += reps;
00234   Bf[1][1] = myfabs(B[1][1]);  Bf[1][1] += reps;
00235   Bf[1][2] = myfabs(B[1][2]);  Bf[1][2] += reps;
00236   Bf[2][0] = myfabs(B[2][0]);  Bf[2][0] += reps;
00237   Bf[2][1] = myfabs(B[2][1]);  Bf[2][1] += reps;
00238   Bf[2][2] = myfabs(B[2][2]);  Bf[2][2] += reps;
00239 
00240   
00241 #if TRACE1
00242   printf("Box test: Bf[3][3], B[3][3], T[3], a[3], b[3]\n");
00243   Mprintg(Bf);
00244   Mprintg(B);
00245   Vprintg(T);
00246   Vprintg(a);
00247   Vprintg(b);
00248 #endif
00249   
00250   // if any of these tests are one-sided, then the polyhedra are disjoint
00251   r = 1;
00252 
00253   // A1 x A2 = A0
00254   t = myfabs(T[0]);
00255   
00256   r &= (t <= 
00257           (a[0] + b[0] * Bf[0][0] + b[1] * Bf[0][1] + b[2] * Bf[0][2]));
00258   if (!r) return 1;
00259   
00260   // B1 x B2 = B0
00261   s = T[0]*B[0][0] + T[1]*B[1][0] + T[2]*B[2][0];
00262   t = myfabs(s);
00263 
00264   r &= ( t <=
00265           (b[0] + a[0] * Bf[0][0] + a[1] * Bf[1][0] + a[2] * Bf[2][0]));
00266   if (!r) return 2;
00267     
00268   // A2 x A0 = A1
00269   t = myfabs(T[1]);
00270   
00271   r &= ( t <= 
00272           (a[1] + b[0] * Bf[1][0] + b[1] * Bf[1][1] + b[2] * Bf[1][2]));
00273   if (!r) return 3;
00274 
00275   // A0 x A1 = A2
00276   t = myfabs(T[2]);
00277 
00278   r &= ( t <= 
00279           (a[2] + b[0] * Bf[2][0] + b[1] * Bf[2][1] + b[2] * Bf[2][2]));
00280   if (!r) return 4;
00281 
00282   // B2 x B0 = B1
00283   s = T[0]*B[0][1] + T[1]*B[1][1] + T[2]*B[2][1];
00284   t = myfabs(s);
00285 
00286   r &= ( t <=
00287           (b[1] + a[0] * Bf[0][1] + a[1] * Bf[1][1] + a[2] * Bf[2][1]));
00288   if (!r) return 5;
00289 
00290   // B0 x B1 = B2
00291   s = T[0]*B[0][2] + T[1]*B[1][2] + T[2]*B[2][2];
00292   t = myfabs(s);
00293 
00294   r &= ( t <=
00295           (b[2] + a[0] * Bf[0][2] + a[1] * Bf[1][2] + a[2] * Bf[2][2]));
00296   if (!r) return 6;
00297 
00298   // A0 x B0
00299   s = T[2] * B[1][0] - T[1] * B[2][0];
00300   t = myfabs(s);
00301   
00302   r &= ( t <= 
00303         (a[1] * Bf[2][0] + a[2] * Bf[1][0] +
00304          b[1] * Bf[0][2] + b[2] * Bf[0][1]));
00305   if (!r) return 7;
00306   
00307   // A0 x B1
00308   s = T[2] * B[1][1] - T[1] * B[2][1];
00309   t = myfabs(s);
00310 
00311   r &= ( t <=
00312         (a[1] * Bf[2][1] + a[2] * Bf[1][1] +
00313          b[0] * Bf[0][2] + b[2] * Bf[0][0]));
00314   if (!r) return 8;
00315 
00316   // A0 x B2
00317   s = T[2] * B[1][2] - T[1] * B[2][2];
00318   t = myfabs(s);
00319 
00320   r &= ( t <=
00321           (a[1] * Bf[2][2] + a[2] * Bf[1][2] +
00322            b[0] * Bf[0][1] + b[1] * Bf[0][0]));
00323   if (!r) return 9;
00324 
00325   // A1 x B0
00326   s = T[0] * B[2][0] - T[2] * B[0][0];
00327   t = myfabs(s);
00328 
00329   r &= ( t <=
00330           (a[0] * Bf[2][0] + a[2] * Bf[0][0] +
00331            b[1] * Bf[1][2] + b[2] * Bf[1][1]));
00332   if (!r) return 10;
00333 
00334   // A1 x B1
00335   s = T[0] * B[2][1] - T[2] * B[0][1];
00336   t = myfabs(s);
00337 
00338   r &= ( t <=
00339           (a[0] * Bf[2][1] + a[2] * Bf[0][1] +
00340            b[0] * Bf[1][2] + b[2] * Bf[1][0]));
00341   if (!r) return 11;
00342 
00343   // A1 x B2
00344   s = T[0] * B[2][2] - T[2] * B[0][2];
00345   t = myfabs(s);
00346 
00347   r &= (t <=
00348           (a[0] * Bf[2][2] + a[2] * Bf[0][2] +
00349            b[0] * Bf[1][1] + b[1] * Bf[1][0]));
00350   if (!r) return 12;
00351 
00352   // A2 x B0
00353   s = T[1] * B[0][0] - T[0] * B[1][0];
00354   t = myfabs(s);
00355 
00356   r &= (t <=
00357           (a[0] * Bf[1][0] + a[1] * Bf[0][0] +
00358            b[1] * Bf[2][2] + b[2] * Bf[2][1]));
00359   if (!r) return 13;
00360 
00361   // A2 x B1
00362   s = T[1] * B[0][1] - T[0] * B[1][1];
00363   t = myfabs(s);
00364 
00365   r &= ( t <=
00366           (a[0] * Bf[1][1] + a[1] * Bf[0][1] +
00367            b[0] * Bf[2][2] + b[2] * Bf[2][0]));
00368   if (!r) return 14;
00369 
00370   // A2 x B2
00371   s = T[1] * B[0][2] - T[0] * B[1][2];
00372   t = myfabs(s);
00373 
00374   r &= ( t <=
00375           (a[0] * Bf[1][2] + a[1] * Bf[0][2] +
00376            b[0] * Bf[2][1] + b[1] * Bf[2][0]));
00377   if (!r) return 15;
00378 
00379   return 0;  // should equal 0
00380 }

Generated on Thu Dec 1 10:13:39 2005 for COME - Biomechanical Joint Model by  doxygen 1.4.5