MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
ot_algorithme_geometrique.cpp
Aller à la documentation de ce fichier.
1 //####//------------------------------------------------------------
2 //####//------------------------------------------------------------
3 //####// MAGiC
4 //####// Jean Christophe Cuilliere et Vincent FRANCOIS
5 //####// Departement de Genie Mecanique - UQTR
6 //####//------------------------------------------------------------
7 //####// MAGIC est un projet de recherche de l equipe ERICCA
8 //####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres
9 //####// http://www.uqtr.ca/ericca
10 //####// http://www.uqtr.ca/
11 //####//------------------------------------------------------------
12 //####//------------------------------------------------------------
13 //####//
14 //####// ot_algorithme_geometrique.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:53:59 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 
23 #include <math.h>
24 
25 #pragma hdrstop
26 
27 
29 #pragma package(smart_init)
30 
32 (double *norm, double *root, double *pnt)
33 {
34  double res[3];
35  return Closest_Point_to_Plane_3d(norm,root,pnt,res);
36 }
37 
38 double OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Plane_3d(double *norm, double *root, double *pnt, double *res)
39 {
40  double pr[3], sn,sd,sb;
41 
42  // pr = pnt - root
43  VEC3_MINUS_VEC3(pnt,root,pr);
44  // sn = -(norm * pr)
45  sn = - VEC3_DOT_VEC3(norm,pr);
46  // sd = norm*norm
47  sd = VEC3_NORM2(norm);
48  // sb = sn/sd
49  sb = sn/sd;
50  // res = pnt + sb * norm
51  VEC3_MULTIPLY_SCALAR(norm,sb,res);
52  VEC3_PLUS_VEC3(res,pnt,res);
53  // return dist(res, pnt)
54  return VEC3_DISTANCE_VEC3(res,pnt);
55 }
56 
57 void
58 OT_ALGORITHME_GEOMETRIQUE::Dist3D_Segment_Segment( double *S11, double *S12, double *S21, double *S22, double *dist, double *P1, double *P2)
59 {
60  static const double SMALL_NUM = 1E-12;
61  int i;
62  double u[3], v[3], w[3];
63  double a,b,c,d,e;
64  double D;
65  double sc, sN, sD;
66  double tc, tN, tD;
67  double dP[3];
68 
69  for (i=0;i<3;i++)
70  {
71  u[i]=S12[i]-S11[i];
72  v[i]=S22[i]-S21[i];
73  w[i]=S11[i]-S21[i];
74  }
75  a=VEC3_DOT_VEC3(u,u);// always >= 0
76  b=VEC3_DOT_VEC3(u,v);
77  c=VEC3_DOT_VEC3(v,v);// always >= 0
78  d=VEC3_DOT_VEC3(u,w);
79  e=VEC3_DOT_VEC3(w,v);
80  D = a*c - b*b; // always >= 0
81  sD = D; // sc = sN / sD, default sD = D >= 0
82  tD = D; // tc = tN / tD, default tD = D >= 0
83 
84  // compute the line parameters of the two closest points
85  if (D < SMALL_NUM) { // the lines are almost parallel
86  sN = 0.0; // force using point P0 on segment S1
87  sD = 1.0; // to prevent possible division by 0.0 later
88  tN = e;
89  tD = c;
90  }
91  else { // get the closest points on the infinite lines
92  sN = (b*e - c*d);
93  tN = (a*e - b*d);
94  if (sN < 0.0) { // sc < 0 => the s=0 edge is visible
95  sN = 0.0;
96  tN = e;
97  tD = c;
98  }
99  else if (sN > sD) { // sc > 1 => the s=1 edge is visible
100  sN = sD;
101  tN = e + b;
102  tD = c;
103  }
104  }
105 
106  if (tN < 0.0) { // tc < 0 => the t=0 edge is visible
107  tN = 0.0;
108  // recompute sc for this edge
109  if (-d < 0.0)
110  sN = 0.0;
111  else if (-d > a)
112  sN = sD;
113  else {
114  sN = -d;
115  sD = a;
116  }
117  }
118  else if (tN > tD) { // tc > 1 => the t=1 edge is visible
119  tN = tD;
120  // recompute sc for this edge
121  if ((-d + b) < 0.0)
122  sN = 0;
123  else if ((-d + b) > a)
124  sN = sD;
125  else {
126  sN = (-d + b);
127  sD = a;
128  }
129  }
130  // finally do the division to get sc and tc
131  sc = (fabs(sN) < SMALL_NUM ? 0.0 : sN / sD);
132  tc = (fabs(tN) < SMALL_NUM ? 0.0 : tN / tD);
133 
134  // get the difference of the two closest points
135  for (i=0;i<3;i++)
136  {
137  P1[i] = S11[i] + sc * u[i];
138  P2[i] = S21[i] + tc * v[i];
139  dP[i] = w[i] + (sc * u[i]) - (tc * v[i]); // = S1(sc) - S2(tc)
140  }
141 
142  *dist = VEC3_NORM(dP); // return the closest distance
143 }
144 
145 int OT_ALGORITHME_GEOMETRIQUE::Intr3D_Plane_Plane(double __N1[3],double __P1[3],double __N2[3],double __P2[3],double __D[3])
146 {
147  VEC3_CROSS_VEC3(__N1,__N2,__D);
148 
149  if (VEC3_NORM2(__D) == 0)
150  return 0;
151 
152  VEC3_NORMALIZE(__D);
153  return 1;
154 }
156 (double *norm, double *root, double *pnt)
157 {
158  double D = -(norm[0]*root[0]+norm[1]*root[1]+norm[2]*root[2]);
159 
160  return (norm[0]*pnt[0]+norm[1]*pnt[1]+norm[2]*pnt[2]+D)/sqrt(fabs(norm[0]*norm[0]+norm[1]*norm[1]+norm[2]*norm[2]));
161 }
162 
163 int OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Line_3d (double __lineOrigin[3], double __lineDirection[3], double __p[3], double __r[3])
164 {
165  double ab[3];
166  VEC3_ASSIGN_VEC3(__lineDirection,ab);
167  double ac[3];
168  VEC3_MINUS_VEC3(__p,__lineOrigin,ac);
169  double c1 = VEC3_DOT_VEC3(ac,ab);
170  double c2 = VEC3_NORM2 (ab);
171  double t = c1/c2;
172  VEC3_MULTIPLY_SCALAR(ab,t,__r);
173  VEC3_PLUS_VEC3(__r,__lineOrigin,__r);
174  return 0;
175 }
176 
177 int OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d (double a[3], double b[3], double c[3], double d[3])
178 {
179  double ab[3];
180  VEC3_MINUS_VEC3(b,a,ab);
181 
182  double ac[3];
183  VEC3_MINUS_VEC3(c,a,ac);
184 
185  double c1 = VEC3_DOT_VEC3(ac,ab);
186 
187  if (c1 <= 0)
188  {
189  VEC3_ASSIGN_VEC3(a,d);
190  return 1;
191  }
192 
193  double c2 = VEC3_NORM2 (ab);
194  if (c2 <= c1)
195  {
196  VEC3_ASSIGN_VEC3(b,d);
197  return 2;
198  }
199 
200  double t = c1/c2;
201  {
202  VEC3_MULTIPLY_SCALAR(ab,t,d);
203  VEC3_PLUS_VEC3(d,a,d);
204  return 0;
205  }
206 }
207 int OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d (double a[3], double b[3], double c[3], double d[3], double *t)
208 {
209  double ab[3];
210  VEC3_MINUS_VEC3(b,a,ab);
211 
212  double ac[3];
213  VEC3_MINUS_VEC3(c,a,ac);
214 
215  double c1 = VEC3_DOT_VEC3(ac,ab);
216  double c2 = VEC3_NORM2 (ab);
217  if (c2 == 0) // degenerated segment
218  {
219  *t=1E300;
220  return -1;
221  }
222 
223  if (c1 <= 0)
224  {
225  VEC3_ASSIGN_VEC3(a,d);
226  *t=0;
227  return 1;
228  }
229 
230  *t = c1/c2;
231  if (c2 <= c1)
232  {
233  VEC3_ASSIGN_VEC3(b,d);
234  return 2;
235  }
236 
237  {
238  VEC3_MULTIPLY_SCALAR(ab,*t,d);
239  VEC3_PLUS_VEC3(d,a,d);
240  return 0;
241  }
242 }
243 
244 
245 
246 int OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_2d( double * SP0, double * SP1, double * P, double * t, double result[2])
247 {
248  double v[2];
249  for (int i = 0; i < 2; i++)
250  v[i] = SP1[i] - SP0[i];
251 
252  double w[2];
253  for (int i = 0; i < 2; i++)
254  w[i] = P[i] - SP0[i];
255 
256  double c1 = v[0]*w[0]+v[1]*w[1];
257  double c2 = v[0]*v[0]+v[1]*v[1];
258 
259  if (c2 < 1E-6*fabs(c1) || c2 == 0.0f )
260  {
261  *t=1E6;
262  return -1;
263  }
264  else
265  *t = c1 / c2;
266 
267  if ( c1 <= 0 )
268  {
269  for (int i = 0; i < 2; i++)
270  result[i] = SP0[i];
271  return 1;
272  }
273 
274  if ( c2 <= c1 )
275  {
276  for (int i = 0; i < 2; i++)
277  result[i] = SP1[i];
278  return 2;
279  }
280 
281  for (int i = 0; i < 2; i++)
282  result[i] = SP0[i] + t[0] * v[i];
283 
284  return 0;
285 }
286 
287 
288 double OT_ALGORITHME_GEOMETRIQUE::Dist2D_Point_Segment (double a[2], double b[2], double c[2])
289  {
290  double closestPoint[2], tmpt;
291 
292  Closest_Point_to_Segment_2d(a,b,c,&tmpt, closestPoint);
293 
294  return VEC2_DISTANCE_VEC2(closestPoint, c);
295 }
296 
297 
299 (double a[3], double b[3], double c[3])
300 {
301  double closestPoint[3];
302 
303  Closest_Point_to_Segment_3d(a,b,c,closestPoint);
304 
305  return VEC3_DISTANCE_VEC3(closestPoint, c);
306 }
307 
309 (double *norm, double *root, double *pnt, double *proj_pnt)
310 {
311  double d = Dist3D_Point_Plan
312 (norm, root, pnt);
313 
314  for (int i=0; i<3; i++)
315  proj_pnt[i] = pnt[i] - d*norm[i];
316 }
317 
318 
319 int
321 (double P0[3], double P1[3], double O[3], double V[3], double *p_coef, double EPSILON)
322 {
323  int i=0; // variable de boucle
324  double u[3]; // u: vecteur P1 - P0
325  double w[3]; // P0 - 0 (vecteur = premier pt segt - point appartenant au plan)
326  double coef = 0; // coefficient d'intersection du edge
327  double D = .0;
328  double N = .0;
329 
330  for (i = 0; i < 3; i++) u[i] = P1[i] - P0[i];
331  for (i = 0; i < 3; i++) w[i] = P0[i] - O[i];
332 
333  D = V[0]*u[0]+V[1]*u[1]+V[2]*u[2]; // prod scalaire normale plan * u
334  N = -(V[0]*w[0]+V[1]*w[1]+V[2]*w[2]);
335  // prod scalaire normale plan * w : positif
336  // si il est // plan) dans le direction normale au plan
337 
338  if (fabs(D) < EPSILON) { // edge is parallel to plane
339  if (fabs(N) < EPSILON) // edge lies in plane
340  return 2;
341  else
342  return 0; // no intersection
343  }
344 
345  // they are not parallel
346  // compute intersect param
347  coef = N / D;
348  if ( coef+EPSILON < 0.0 || coef-EPSILON > 1.0)
349  {
350  *p_coef = coef;
351  return 0; // no intersection
352  }
353 
354  /*
355  for (i = 0; i < 3; i++)
356  I[i] = P0[i] + coef * u[i]; // compute edge-plane intersect point
357  */
358 
359  // met la valeur de coef dans la variable de sortie
360  *p_coef = coef;
361 
362  return 1;
363 }
364 
365 int
367 (double P0[3], double P1[3], double O[3], double V[3], double *p_coef, double *distance, double EPSILON)
368 {
369  double dist_P0 = Dist3D_Point_Plan
370 (V, O, P0);
371  if ( fabs(dist_P0) < EPSILON )
372  dist_P0 = 0;
373 
374  double dist_P1 = Dist3D_Point_Plan
375 (V, O, P1);
376  if ( fabs(dist_P1) < EPSILON )
377  dist_P1 = 0;
378 
379  double prodDist = dist_P0 * dist_P1;
380  if ( prodDist < 0 )
381  {
382  // The segment passes through the plane.
383  double direction[3];
384  VEC3_MINUS_VEC3(P1,P0,direction);
385 
386  *p_coef = -dist_P0/(VEC3_DOT_VEC3(direction, V));
387  *distance = 0;
388 
389  return 1;
390  }
391 
392  if ( prodDist > 0 )
393  {
394  // The segment is on one side of the plane.
395  double direction[3];
396  VEC3_MINUS_VEC3(P1,P0,direction);
397 
398  double dirDotNormal = VEC3_DOT_VEC3(direction, V);
399  if (dirDotNormal > EPSILON)
400  *p_coef = -dist_P0/dirDotNormal;
401  else
402  *p_coef = 1;
403  *distance = (fabs(dist_P0) < fabs(dist_P1)) ? fabs(dist_P0) : fabs(dist_P1) ;
404 
405  return 0;
406  }
407 
408  if ( dist_P0 != 0.0 || dist_P0 != 0.0 )
409  {
410  // A segment end point touches the plane.
411 
412  if (dist_P0 == 0)
413  *p_coef = 0;
414  if (dist_P1 == 0)
415  *p_coef = 1;
416 
417  *distance = 0;
418  return 1;
419  }
420 
421  if ( dist_P0 == 0.0 && dist_P0 == 0.0 )
422  {
423  // The segment is coincident with the plane.
424  *distance = 0;
425  *p_coef = .5;
426  return 2;
427  }
428 
429  return 0;
430 }
431 
432 double
433 OT_ALGORITHME_GEOMETRIQUE::pbase_Plane( double P[3], double planeNormal[3], double planeRootPoint[3], double B[3])
434 {
435  // sn = -dot( PL.n, (P - PL.V0));
436  double sn=0;
437  for (int i=0;i<3;i++)
438  sn += - (planeNormal[i] - (P[i] - planeRootPoint[i]));
439 
440  // sd = dot(PL.n, PL.n);
441  double sd=0;
442  for (int i=0;i<3;i++)
443  sd += (planeNormal[i]*planeNormal[i]);
444 
445  // sb = sn / sd;
446  double sb = sn / sd;
447 
448  // *B = P + sb * PL.n;
449  for (int i=0;i<3;i++)
450  B[i] = P[i] + sb * planeNormal[i];
451 
452  // return d(P, *B);
453  return sqrt(pow(P[0]-B[0],2)+pow(P[1]-B[1],2)+pow(P[2]-B[2],2));
454 }
455 
456 double
458 (double __v0[3], double __v1[3], double __v2[3])
459 {
460  double s01[3], s12[3];
461  VEC3_MINUS_VEC3(__v1, __v0, s01);
462  VEC3_MINUS_VEC3(__v2, __v1, s12);
463 
464  double s01Dots12 = VEC3_DOT_VEC3(s01, s12);
465  double norm_s01 = VEC3_NORM(s01);
466  double norm_s12 = VEC3_NORM(s12);
467 
468  if (norm_s01*norm_s12 < 1E-28)
469  return 0;
470 
471  double proj = s01Dots12/(norm_s01*norm_s12);
472  if (proj > 1.0)
473  proj = 1.0;
474  if (proj < -1.0)
475  proj = -1.0;
476 
477  double angle = acos (proj);
478 
479  return angle;
480 }
489 (double p[3],double theta, double r[3], double q[3])
490 {
491  double costheta,sintheta;
492 
493  VEC3_NORMALIZE(r);
494  costheta = cos(theta);
495  sintheta = sin(theta);
496 
497  q[0] = q[1] = q[2] = 0;
498 
499  q[0] += (costheta + (1 - costheta) * r[0] * r[0]) * p[0];
500  q[0] += ((1 - costheta) * r[0] * r[1] - r[2] * sintheta) * p[1];
501  q[0] += ((1 - costheta) * r[0] * r[2] + r[1] * sintheta) * p[2];
502 
503  q[1] += ((1 - costheta) * r[0] * r[1] + r[2] * sintheta) * p[0];
504  q[1] += (costheta + (1 - costheta) * r[1] * r[1]) * p[1];
505  q[1] += ((1 - costheta) * r[1] * r[2] - r[0] * sintheta) * p[2];
506 
507  q[2] += ((1 - costheta) * r[0] * r[2] - r[1] * sintheta) * p[0];
508  q[2] += ((1 - costheta) * r[1] * r[2] + r[0] * sintheta) * p[1];
509  q[2] += (costheta + (1 - costheta) * r[2] * r[2]) * p[2];
510 }
511 
512 #define SMALL_NUM 0.00000001 // anything that avoids division overflow
513 int OT_ALGORITHME_GEOMETRIQUE::intersect2D_SegSeg( double S1P0[2], double S1P1[2], double S2P0[2], double S2P1[2], double __intrPoint[2], double __intrEndPointSeg[2])
514 {
515  double u[2],v[2],w[2];
516  // Vector u = S1.P1 - S1.P0;
517  VEC2_MINUS_VEC2(S1P1,S1P0,u);
518  // Vector v = S2.P1 - S2.P0;
519  VEC2_MINUS_VEC2(S2P1,S2P0,v);
520  //Vector w = S1.P0 - S2.P0;
521  VEC2_MINUS_VEC2(S1P0,S2P0,w);
522 
523  double D = PERP_PROD2(u,v);
524 
525  // test if they are parallel (includes either being a point)
526  if (fabs(D) < SMALL_NUM) { // S1 and S2 are parallel
527  if (PERP_PROD2(u,w) != 0 || PERP_PROD2(v,w) != 0) {
528  return 0; // they are NOT collinear
529  }
530  // they are collinear or degenerate
531  // check if they are degenerate points
532  double du = VEC2_DOT_VEC2(u,u);
533  double dv = VEC2_DOT_VEC2(v,v);
534  if (du==0 && dv==0) { // both segments are points
535  if (VEC2_DISTANCE2_VEC2(S1P0,S2P0) > 0) // they are distinct points
536  return 0;
537  VEC2_ASSIGN_VEC2(S1P0, __intrPoint); // they are the same point
538  return 1;
539  }
540  if (du==0) { // S1 is a single point
541  if (Dist2D_Point_Segment(S2P0,S2P1,S1P0) > 0) // but is not in S2
542  return 0;
543  VEC2_ASSIGN_VEC2(S1P0, __intrPoint);
544  return 1;
545  }
546  if (dv==0) { // S2 a single point
547  if (Dist2D_Point_Segment(S1P0,S1P1,S2P0) > 0) // but is not in S1
548  return 0;
549  VEC2_ASSIGN_VEC2(S2P0, __intrPoint);
550  return 1;
551  }
552  // they are collinear segments - get overlap (or not)
553  double t0, t1; // endpoints of S1 in eqn for S2
554  //Vector w2 = S1.P1 - S2.P0;
555  double w2[2];
556  VEC2_MINUS_VEC2(S1P1, S2P0, w2);
557 
558  if (v[0] != 0) {
559  t0 = w[0] / v[0];
560  t1 = w2[0] / v[0];
561  }
562  else {
563  t0 = w[1] / v[1];
564  t1 = w2[1] / v[1];
565  }
566  if (t0 > t1) { // must have t0 smaller than t1
567  double t=t0;
568  t0=t1;
569  t1=t; // swap if not
570  }
571  if (t0 > 1 || t1 < 0) {
572  return 0; // NO overlap
573  }
574  t0 = t0<0? 0 : t0; // clip to min 0
575  t1 = t1>1? 1 : t1; // clip to max 1
576  if (t0 == t1) { // intersect is a point
577  for (int i=0; i<2; i++)
578  __intrPoint[i] = S2P0[i] + t0 * v[i];
579  return 1;
580  }
581 
582  // they overlap in a valid subsegment
583  for (int i=0; i<2; i++)
584  __intrPoint[i] = S2P0[i] + t0 * v[i];
585 
586  for (int i=0; i<2; i++)
587  __intrEndPointSeg[i] = S2P0[i] + t1 * v[i];
588 
589  return 2;
590  }
591 
592  // the segments are skew and may intersect in a point
593  // get the intersect parameter for S1
594  double sI = PERP_PROD2(v,w) / D;
595  if (sI < 0 || sI > 1) // no intersect with S1
596  return 0;
597 
598  // get the intersect parameter for S2
599  double tI = PERP_PROD2(u,w) / D;
600  if (tI < 0 || tI > 1) // no intersect with S2
601  return 0;
602 
603  for (int i=0; i<2; i++) // compute S1 intersect point
604  __intrPoint[i] = S1P0[i] + sI * u[i];
605 
606  return 1;
607 }
608 
609 int OT_ALGORITHME_GEOMETRIQUE::intersect_RayTriangle( double RP0[3], double dir[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT )
610 {
611  double u[3], v[3], n[3]; // triangle vectors
612  double w0[3], w[3]; // ray vectors
613  double r, a, b; // params to calc ray-plane intersect
614 
615  // get triangle edge vectors and plane normal
616  // u = T.V1 - T.V0;
617  VEC3_MINUS_VEC3(TV1,TV0,u);
618  // v = T.V2 - T.V0;
619  VEC3_MINUS_VEC3(TV2,TV0,v);
620  //n = u * v; // cross product
621  VEC3_CROSS_VEC3(u,v,n);
622 
623  if (VEC3_NORM2(n) == 0) // triangle is degenerate
624  return -1; // do not deal with this case
625 
626  // dir = ray direction vector
627  //w0 = R.P0 - T.V0;
628  VEC3_MINUS_VEC3(RP0, TV0, w0);
629  // a = -dot(n,w0);
630  a = -VEC3_DOT_VEC3(n,w0);
631  // b = dot(n,dir);
632  b = VEC3_DOT_VEC3(n,dir);
633  if (fabs(b) < SMALL_NUM) { // ray is parallel to triangle plane
634  if (a == 0) // ray lies in triangle plane
635  return 2;
636  else return 0; // ray disjoint from plane
637  }
638 
639  // get intersect point of ray with triangle plane
640  r = a / b;
641  if (r < 0.0) // ray goes away from triangle
642  return 0; // => no intersect
643  // for a segment, also test if (r > 1.0) => no intersect
644 
645  for (int i=0; i<3; i++)
646  I[i] = RP0[i] + r*dir[i]; // intersect point of ray and plane
647 
648  // is I inside T?
649  double uu, uv, vv, wu, wv, D;
650  uu = VEC3_DOT_VEC3(u,u);
651  uv = VEC3_DOT_VEC3(u,v);
652  vv = VEC3_DOT_VEC3(v,v);
653  for (int i=0; i<3; i++)
654  w[i] = I[i] - TV0[i];
655  wu = VEC3_DOT_VEC3(w,u);
656  wv = VEC3_DOT_VEC3(w,v);
657  D = uv * uv - uu * vv;
658 
659  // get and test parametric coords
660  double s, t;
661  s = (uv * wv - vv * wu) / D;
662  if (s < 0.0 || s > 1.0) // I is outside T
663  return 0;
664  t = (uv * wu - uu * wv) / D;
665  if (t < 0.0 || (s + t) > 1.0) // I is outside T
666  return 0;
667 
668  if (IT)
669  *IT = r;
670 
671  return 1; // I is in T
672 }
673 
674 
675 int OT_ALGORITHME_GEOMETRIQUE::project_PointTriangle( double P0[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT )
676 {
677  double u[3], v[3], n[3]; // triangle vectors
678  double dir[3], RP0[3]; // ray vectors
679  double r, a, b; // params to calc ray-plane intersect
680 
681  // get triangle edge vectors and plane normal
682  // u = T.V1 - T.V0;
683  VEC3_MINUS_VEC3(TV1,TV0,u);
684  // v = T.V2 - T.V0;
685  VEC3_MINUS_VEC3(TV2,TV1,v);
686  //n = u * v; // cross product
687  VEC3_CROSS_VEC3(u,v,n);
688 
689  // signed squared distance between the point and the plane of the triangle
690  double D=Dist3D_Point_Plane(n,TV0,P0);
691 
692  int signD = (D<0)?-1:+1;
693 
694  // D is used for the direction of the intersecting ray
695  for (int i=0; i<3; i++)
696  dir[i] = n[i]*signD;
697  for (int i=0; i<3; i++)
698  RP0[i] = P0[i]-dir[i];
699 
700  int res_intrRT = intersect_RayTriangle(RP0, dir, TV0, TV1, TV2, I, IT);
701 
702  // Signed distance from the point to the triangle
703  *IT = VEC3_DISTANCE_VEC3(I,P0);
704 
705  return res_intrRT;
706 }
707 
708 
709 int OT_ALGORITHME_GEOMETRIQUE::intersect_SegTriangle( double SP0[3], double SP1[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT )
710 {
711  double u[3], v[3], n[3]; // triangle vectors
712  double dir[3], RP0[3]; // ray vectors
713  double r, a, b; // params to calc ray-plane intersect
714 
715  // get triangle edge vectors and plane normal
716  // u = T.V1 - T.V0;
717  VEC3_MINUS_VEC3(TV1,TV0,u);
718  // v = T.V2 - T.V0;
719  VEC3_MINUS_VEC3(TV2,TV0,v);
720  //n = u * v; // cross product
721  VEC3_CROSS_VEC3(u,v,n);
722 
723  // D is used for the direction of the intersecting ray
724  for (int i=0; i<3; i++)
725  dir[i] = SP1[i]-SP0[i];
726 
727  int res_IntrRT = intersect_RayTriangle(SP0, dir, TV0, TV1, TV2, I, &r);
728 
729  switch (res_IntrRT)
730  {
731  case 1: // intersection ray/triangle is a point
732  {
733  if (r > 1+SMALL_NUM) // if the triangle intersect the segment outside range SP0 SP1
734  return 0;
735  break;
736  }
737  case 2: // the ray is coplanar to the triangle
738  {
739  // test is at least 1 extremity of the segment lies into the triangle's domain
740  double ITSP0, ISP0[3], ITSP1, ISP1[3];
741  int resSP0;
742  resSP0 = project_PointTriangle(SP0, TV0, TV1, TV2, ISP0, &ITSP0);
743  project_PointTriangle(SP1, TV0, TV1, TV2, ISP1, &ITSP1);
744 
745  if (resSP0!=0) // 1st extremity of the segment is inside the triangle
746  VEC3_ASSIGN_VEC3(ISP0,I);
747  return 0;
748  }
749  }
750  return res_IntrRT;
751 }
752 
753 
754 double OT_ALGORITHME_GEOMETRIQUE::Area_Triangle(double TV0[3], double TV1[3], double TV2[3])
755 {
756  double S01[3],S12[3];
757  for (int i=0;i<3;i++)
758  S01[i]=TV1[i]-TV0[i];
759  for (int i=0;i<3;i++)
760  S12[i]=TV2[i]-TV1[i];
761  double crossProd[3];
762  VEC3_CROSS_VEC3(S01,S12,crossProd);
763  double area = VEC3_NORM(crossProd);
764  return area;
765 }
OT_ALGORITHME_GEOMETRIQUE::Dist2D_Point_Segment
static double Dist2D_Point_Segment(double a[2], double b[2], double c[2])
Definition: ot_algorithme_geometrique.cpp:288
OT_ALGORITHME_GEOMETRIQUE::VEC2_DISTANCE2_VEC2
static double VEC2_DISTANCE2_VEC2(double a[2], double b[2])
Definition: ot_algorithme_geometrique.h:181
OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_2d
static int Closest_Point_to_Segment_2d(double *SP0, double *SP1, double *P, double *t, double result[2])
Definition: ot_algorithme_geometrique.cpp:246
OT_ALGORITHME_GEOMETRIQUE::VEC3_CROSS_VEC3
static void VEC3_CROSS_VEC3(double a[3], double b[3], double c[3])
Definition: ot_algorithme_geometrique.h:76
a
#define a(i, j)
OT_ALGORITHME_GEOMETRIQUE::intersect_RayTriangle
static int intersect_RayTriangle(double RP0[3], double dir[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT=0)
Definition: ot_algorithme_geometrique.cpp:609
OT_ALGORITHME_GEOMETRIQUE::VEC3_PLUS_VEC3
static void VEC3_PLUS_VEC3(double a[3], double b[3], double c[3])
Definition: ot_algorithme_geometrique.h:86
OT_ALGORITHME_GEOMETRIQUE::project_PointTriangle
static int project_PointTriangle(double P0[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT=0)
Definition: ot_algorithme_geometrique.cpp:675
OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Segment
static double Dist3D_Point_Segment(double a[3], double b[3], double c[3])
Definition: ot_algorithme_geometrique.cpp:299
OT_ALGORITHME_GEOMETRIQUE::Proj3D_Point_Plan
static void Proj3D_Point_Plan(double *norm, double *root, double *pnt, double *proj_pnt)
Definition: ot_algorithme_geometrique.cpp:309
OT_ALGORITHME_GEOMETRIQUE::VEC2_DOT_VEC2
static double VEC2_DOT_VEC2(double a[2], double b[2])
Definition: ot_algorithme_geometrique.h:147
OT_ALGORITHME_GEOMETRIQUE::VEC3_DOT_VEC3
static double VEC3_DOT_VEC3(double a[3], double b[3])
Definition: ot_algorithme_geometrique.h:91
OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Line_3d
static int Closest_Point_to_Line_3d(double __lineOrigin[3], double __lineDirection[3], double __p[3], double _r[3])
Definition: ot_algorithme_geometrique.cpp:163
SMALL_NUM
#define SMALL_NUM
Definition: ot_algorithme_geometrique.cpp:512
OT_ALGORITHME_GEOMETRIQUE::Angle3D_Segment_Segment
static double Angle3D_Segment_Segment(double __v0[3], double __v1[3], double __v2[3])
Definition: ot_algorithme_geometrique.cpp:458
OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Plane
static double Dist3D_Point_Plane(double *norm, double *root, double *pnt)
Definition: ot_algorithme_geometrique.cpp:32
OT_ALGORITHME_GEOMETRIQUE::Area_Triangle
static double Area_Triangle(double TV0[3], double TV1[3], double TV2[3])
Definition: ot_algorithme_geometrique.cpp:754
OT_ALGORITHME_GEOMETRIQUE::VEC3_NORM
static double VEC3_NORM(double a[3])
Definition: ot_algorithme_geometrique.h:94
f
double f(double x, long nb, double *xfonc, double *fonc, double eng, double eni, double lambda, double nor, double *fonc2)
Definition: fct_generateur_calibrage.cpp:96
OT_ALGORITHME_GEOMETRIQUE::VEC3_NORMALIZE
static void VEC3_NORMALIZE(double a[3])
Definition: ot_algorithme_geometrique.h:100
OT_ALGORITHME_GEOMETRIQUE::pbase_Plane
static double pbase_Plane(double P[3], double planeNormal[3], double planeRootPoint[3], double B[3])
Definition: ot_algorithme_geometrique.cpp:433
OT_ALGORITHME_GEOMETRIQUE::VEC2_ASSIGN_VEC2
static void VEC2_ASSIGN_VEC2(double a[2], double b[2])
Definition: ot_algorithme_geometrique.h:161
OT_ALGORITHME_GEOMETRIQUE::Intr3D_Plane_Plane
static int Intr3D_Plane_Plane(double __N1[3], double __P1[3], double __N2[3], double __P2[3], double __D[3])
Definition: ot_algorithme_geometrique.cpp:145
OT_ALGORITHME_GEOMETRIQUE::VEC2_MINUS_VEC2
static void VEC2_MINUS_VEC2(double a[2], double b[2], double c[2])
Definition: ot_algorithme_geometrique.h:139
OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Segment_3d
static int Closest_Point_to_Segment_3d(double a[3], double b[3], double c[3], double d[3])
Definition: ot_algorithme_geometrique.cpp:177
OT_ALGORITHME_GEOMETRIQUE::intersect_SegTriangle
static int intersect_SegTriangle(double SP0[3], double SP1[3], double TV0[3], double TV1[3], double TV2[3], double I[3], double *IT=0)
Definition: ot_algorithme_geometrique.cpp:709
OT_ALGORITHME_GEOMETRIQUE::VEC3_MULTIPLY_SCALAR
static void VEC3_MULTIPLY_SCALAR(double a[3], double b, double c[3])
Definition: ot_algorithme_geometrique.h:117
OT_ALGORITHME_GEOMETRIQUE::Rot3D_Point_Axe_Angle
static void Rot3D_Point_Axe_Angle(double p[3], double theta, double r[3], double q[3])
Definition: ot_algorithme_geometrique.cpp:489
V
void V(MCAA *mcaa)
Definition: CAD4FE_MCAA.cpp:1794
acos
double2 acos(double2 &val)
Definition: ot_doubleprecision.cpp:224
OT_ALGORITHME_GEOMETRIQUE::Dist3D_Segment_Segment
static void Dist3D_Segment_Segment(double *S11, double *S12, double *S21, double *S22, double *dist, double *P1, double *P2)
Definition: ot_algorithme_geometrique.cpp:58
sqrt
double2 sqrt(double2 &val)
Definition: ot_doubleprecision.cpp:345
OT_ALGORITHME_GEOMETRIQUE::Closest_Point_to_Plane_3d
static double Closest_Point_to_Plane_3d(double *norm, double *root, double *pnt, double *res)
Definition: ot_algorithme_geometrique.cpp:38
OT_ALGORITHME_GEOMETRIQUE::VEC2_DISTANCE_VEC2
static double VEC2_DISTANCE_VEC2(double a[2], double b[2])
Definition: ot_algorithme_geometrique.h:178
ot_algorithme_geometrique.h
OT_ALGORITHME_GEOMETRIQUE::Dist3D_Point_Plan
static double Dist3D_Point_Plan(double *norm, double *root, double *pnt)
Definition: ot_algorithme_geometrique.cpp:156
res
#define res(i, j)
OT_ALGORITHME_GEOMETRIQUE::VEC3_NORM2
static double VEC3_NORM2(double a[3])
Definition: ot_algorithme_geometrique.h:97
OT_ALGORITHME_GEOMETRIQUE::Intr3D_Segment_Plan
static int Intr3D_Segment_Plan(double P0[3], double P1[3], double O[3], double V[3], double *p_coef, double EPSILON=1E-8)
Definition: ot_algorithme_geometrique.cpp:321
cos
double2 cos(double2 &val)
Definition: ot_doubleprecision.cpp:206
P
#define P(i, j)
OT_ALGORITHME_GEOMETRIQUE::VEC3_ASSIGN_VEC3
static void VEC3_ASSIGN_VEC3(double a[3], double b[3])
Definition: ot_algorithme_geometrique.h:106
OT_ALGORITHME_GEOMETRIQUE::VEC3_DISTANCE_VEC3
static double VEC3_DISTANCE_VEC3(double a[3], double b[3])
Definition: ot_algorithme_geometrique.h:127
OT_ALGORITHME_GEOMETRIQUE::VEC3_MINUS_VEC3
static void VEC3_MINUS_VEC3(double a[3], double b[3], double c[3])
Definition: ot_algorithme_geometrique.h:81
OT_ALGORITHME_GEOMETRIQUE::intersect2D_SegSeg
static int intersect2D_SegSeg(double S1P0[2], double S1P1[2], double S2P0[2], double S2P1[2], double __intrPoint[2], double __intrEndPointSeg[2])
Definition: ot_algorithme_geometrique.cpp:513
OT_ALGORITHME_GEOMETRIQUE::Dist3D_Segment_Plan
static int Dist3D_Segment_Plan(double P0[3], double P1[3], double O[3], double V[3], double *p_coef, double *distance, double EPSILON)
Definition: ot_algorithme_geometrique.cpp:367
sin
double2 sin(double2 &val)
Definition: ot_doubleprecision.cpp:250
OT_ALGORITHME_GEOMETRIQUE::PERP_PROD2
static double PERP_PROD2(double a[2], double b[2])
Definition: ot_algorithme_geometrique.h:136