Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
GeometricUtilities.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* GeometricUtilities.cc (C) 2000-2021 */
9/* */
10/* Fonctions utilitaires sur la géométrie. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/ITraceMng.h"
16
17#include "arcane/MathUtils.h"
18#include "arcane/GeometricUtilities.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29Real GeometricUtilities::QuadMapping::
30computeInverseJacobian(Real3 uvw,Real3x3& matrix)
31{
32 Real3x3 jacobian = evaluateGradient(uvw);
33
34 Real d3 = jacobian.x.x * jacobian.y.y - jacobian.x.y * jacobian.y.x;
35 Real d2 = jacobian.x.z * jacobian.y.x - jacobian.x.y * jacobian.y.z;
36 Real d1 = jacobian.x.y * jacobian.y.z - jacobian.x.z * jacobian.y.y;
37
38 Real det = math::sqrt(d1*d1 + d2*d2 + d3*d3);
39 if (math::isNearlyZero(det))
40 return 0.;
41
42 Real inv_det = 1 / det;
43
44 jacobian.z.x = d1 * inv_det;
45 jacobian.z.y = d2 * inv_det;
46 jacobian.z.z = d3 * inv_det;
47
48 matrix.x.x = (jacobian.y.y * jacobian.z.z - jacobian.y.z * jacobian.z.y);
49 matrix.y.x = -(jacobian.y.x * jacobian.z.z - jacobian.y.z * jacobian.z.x);
50 matrix.z.x = (jacobian.y.x * jacobian.z.y - jacobian.y.y * jacobian.z.x);
51
52 matrix.x.y = -(jacobian.x.y * jacobian.z.z - jacobian.x.z * jacobian.z.y);
53 matrix.y.y = (jacobian.x.x * jacobian.z.z - jacobian.x.z * jacobian.z.x);
54 matrix.z.y = -(jacobian.x.x * jacobian.z.y - jacobian.x.y * jacobian.z.x);
55
56 matrix.x.z = (jacobian.x.y * jacobian.y.z - jacobian.x.z * jacobian.y.y);
57 matrix.y.z = -(jacobian.x.x * jacobian.y.z - jacobian.x.z * jacobian.y.x);
58 matrix.z.z = (jacobian.x.x * jacobian.y.y - jacobian.x.y * jacobian.y.x);
59
60 matrix *= inv_det;
61
62 return det;
63}
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67/*!
68 * \brief Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
69 *
70 * Cette opération utilise un newton pour trouver la solution et peut donc
71 * ne pas converger. Dans ce cas, elle retourne \a true.
72 *
73 * \param point position en coordonnée cartésienne du point à calculer.
74 * \param uvw en retour, coordonnées iso-paramétriques calculées
75 */
76
78cartesianToIso(Real3 point,Real3& uvw,ITraceMng* tm)
79{
80 const Real wanted_precision = m_precision;
81 const Integer max_iteration = 1000;
82
83 Real u_new, v_new, w_new;
84 Real relative_error = 1.0 ;
85 Integer nb_iter = 0;
86
87 uvw = Real3(0.5,0.5,0.0);
88
89 Real3x3 inverse_jacobian_matrix;
90
91 while (relative_error>wanted_precision && nb_iter<max_iteration){
92 ++nb_iter;
93
94 computeInverseJacobian(uvw,inverse_jacobian_matrix);
95 Real3 new_pos = evaluatePosition(uvw);
96 u_new = uvw.x + inverse_jacobian_matrix.x.x * (point.x-new_pos.x)
97 + inverse_jacobian_matrix.y.x * (point.y-new_pos.y)
98 + inverse_jacobian_matrix.z.x * (point.z-new_pos.z);
99 v_new = uvw.y + inverse_jacobian_matrix.x.y * (point.x-new_pos.x)
100 + inverse_jacobian_matrix.y.y * (point.y-new_pos.y)
101 + inverse_jacobian_matrix.z.y * (point.z-new_pos.z);
102 //w_new = uvw.z + inverse_jacobian_matrix.x.z * (point.x-new_pos.x)
103 // + inverse_jacobian_matrix.y.z * (point.y-new_pos.y)
104 // + inverse_jacobian_matrix.z.z * (point.z-new_pos.z);
105 w_new = 0.;
106
107 relative_error = (u_new - uvw.x) * (u_new - uvw.x) +
108 (v_new - uvw.y) * (v_new - uvw.y) +
109 (w_new - uvw.z) * (w_new - uvw.z) ;
110
111 if (tm)
112 tm->info() << "CARTESIAN_TO_ISO I=" << nb_iter << " uvw=" << uvw
113 << " new_pos=" << new_pos
114 << " error=" << relative_error;
115
116 uvw.x = u_new;
117 uvw.y = v_new;
118 uvw.z = w_new;
119 }
120 return (relative_error>wanted_precision);
121}
122
123Real3 GeometricUtilities::QuadMapping::
124normal()
125{
126 Real3 normal= QuadMapping::_normal();
127 Real norm = normal.x*normal.x + normal.y*normal.y + normal.z*normal.z;
128 norm = math::sqrt(norm);
129 normal /=norm;
130 return normal;
131}
132
133static Real NormeLinf(Real3 v1,Real3 v2)
134{
135 Real3 v = v2 - v1;
136 Real norm = math::max(math::abs(v.x),math::abs(v.y));
137 norm = math::max(norm,math::abs(v.z));
138 return norm;
139}
140
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
144Real3 GeometricUtilities::QuadMapping::
145_normal()
146{
147 Real3 n0 = math::vecMul(m_pos[1] - m_pos[0],m_pos[2] - m_pos[0]);
148 Real3 n1 = math::vecMul(m_pos[2] - m_pos[1],m_pos[3] - m_pos[1]);
149 Real3 n2 = math::vecMul(m_pos[3] - m_pos[2],m_pos[0] - m_pos[2]);
150 Real3 n3 = math::vecMul(m_pos[0] - m_pos[3],m_pos[1] - m_pos[3]);
151 Real3 normal = (n0+n1+n2+n3) * 0.25;
152 return normal;
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157/*!
158 * \brief Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
159 *
160 * Cette opération utilise un newton pour trouver la solution et peut donc
161 * ne pas converger. Dans ce cas, elle retourne \a true.
162 *
163 * \param point position en coordonnée cartésienne du point à calculer.
164 * \param uvw en retour, coordonnées iso-paramétriques calculées
165 */
166
168cartesianToIso2(Real3 point,Real3& uvw,ITraceMng* tm)
169{
170 Real epsi_newton = 1.0e-12;
171 int newton_loop_limit = 100;
172 bool error = false;
173
174 // Position de départ pour le Newton
175 Real u = 0.5;
176 Real v = 0.5;
177 Real w = 0.5;
178
179 Real3 other_pos[4];
180 Real3 normal = _normal();
181 for( int i=0; i<4; ++i )
182 other_pos[i] = m_pos[i] + normal;
183
184 Real x0 = m_pos[0].x;
185 Real y0 = m_pos[0].y;
186 Real z0 = m_pos[0].z;
187 Real x1 = m_pos[1].x;
188 Real y1 = m_pos[1].y;
189 Real z1 = m_pos[1].z;
190 Real x2 = m_pos[2].x;
191 Real y2 = m_pos[2].y;
192 Real z2 = m_pos[2].z;
193 Real x3 = m_pos[3].x;
194 Real y3 = m_pos[3].y;
195 Real z3 = m_pos[3].z;
196
197 Real x4 = other_pos[0].x;
198 Real y4 = other_pos[0].y;
199 Real z4 = other_pos[0].z;
200 Real x5 = other_pos[1].x;
201 Real y5 = other_pos[1].y;
202 Real z5 = other_pos[1].z;
203 Real x6 = other_pos[2].x;
204 Real y6 = other_pos[2].y;
205 Real z6 = other_pos[2].z;
206 Real x7 = other_pos[3].x;
207 Real y7 = other_pos[3].y;
208 Real z7 = other_pos[3].z;
209
210 Real x = point.x;
211 Real y = point.y;
212 Real z = point.z;
213
214 Real cx = 0.0;
215 Real cy = 0.0;
216 Real cz = 0.0;
217 Real cxu = 0.0;
218 Real cyu = 0.0;
219 Real czu = 0.0;
220 Real cxv = 0.0;
221 Real cyv = 0.0;
222 Real czv = 0.0;
223 Real cxw = 0.0;
224 Real cyw = 0.0;
225 Real czw = 0.0;
226 Real determinant = 0.0;
227
228 // Boucle du NEWTON
229 Real residue = 1.0e30;
230
231 Real u0;
232 Real v0;
233 Real w0;
234
235 int inewt=0;
236 for(inewt=0; inewt<newton_loop_limit && residue>epsi_newton; inewt++ ) {
237
238 u0 = u;
239 v0 = v;
240 w0 = w;
241
242 cx = + x0*((-1 + w0)*(-1 + u0)*(1 - v0)
243 - w0*(-1 + u0)*(1 - v0)
244 + (1 - w0)*u0*(1 - v0)
245 + (-1 + w0)*(-1 + u0)*v0
246 )
247 + x1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
248 + x2*(w0*(-1 + u0)*v0 + w0*u0*v0)
249 + x3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
250 + x4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
251 + x5*((-1 + w0)*u0*v0 + w0*u0*v0)
252 - x6*2*w0*u0*v0
253 + x7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
254 ;
255
256 cxv = x0*(1 - w0)*(-1 + u0)
257 + x1*(-1 + w0)*(-1 + u0)
258 - x2*w0*(-1 + u0)
259 + x3*w0*(-1 + u0)
260 + x4*(-1 + w0)*u0
261 + x5*(1 - w0)*u0
262 + x6*w0*u0
263 - x7*w0*u0
264 ;
265
266 cxw =
267 x0*(-1 + u0)*(1 - v0)
268 + x1*(-1 + u0)*v0
269 + x2*(1 - u0)*v0
270 + x3*(-1 + u0)*(-1 + v0)
271 + x4*u0*(-1 + v0)
272 - x5*u0*v0
273 + x6*u0*v0
274 + x7*u0*(1 - v0)
275 ;
276
277 cxu =
278 x0*(-1 + w0)*(1 - v0)
279 + x1*(-1 + w0)*v0
280 - x2*w0*v0
281 + x3*w0*(-1 + v0)
282 + x4*(-1 + w0)*(-1 + v0)
283 + x5*(1 - w0)*v0
284 + x6*w0*v0
285 + x7*w0*(1 - v0)
286 ;
287
288 cy =
289 + y0*((-1 + w0)*(-1 + u0)*(1 - v0)
290 - w0*(-1 + u0)*(1 - v0)
291 + (1 - w0)*u0*(1 - v0)
292 + (-1 + w0)*(-1 + u0)*v0
293 )
294 + y1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
295 + y2*(w0*(-1 + u0)*v0 + w0*u0*v0)
296 + y3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
297 + y4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
298 + y5*((-1 + w0)*u0*v0 + w0*u0*v0)
299 - y6*2*w0*u0*v0
300 + y7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
301 ;
302
303 cyv =
304 y0*(1 - w0)*(-1 + u0)
305 + y1*(-1 + w0)*(-1 + u0)
306 - y2*w0*(-1 + u0)
307 + y3*w0*(-1 + u0)
308 + y4*(-1 + w0)*u0
309 + y5*(1 - w0)*u0
310 + y6*w0*u0
311 - y7*w0*u0
312 ;
313
314 cyw =
315 y0*(-1 + u0)*(1 - v0)
316 + y1*(-1 + u0)*v0
317 + y2*(1 - u0)*v0
318 + y3*(-1 + u0)*(-1 + v0)
319 + y4*u0*(-1 + v0)
320 - y5*u0*v0
321 + y6*u0*v0
322 + y7*u0*(1 - v0)
323 ;
324
325 cyu = y0*(-1 + w0)*(1 - v0)
326 + y1*(-1 + w0)*v0
327 - y2*w0*v0
328 + y3*w0*(-1 + v0)
329 + y4*(-1 + w0)*(-1 + v0)
330 + y5*(1 - w0)*v0
331 + y6*w0*v0
332 + y7*w0*(1 - v0)
333 ;
334
335 cz = + z0*((-1 + w0)*(-1 + u0)*(1 - v0)
336 - w0*(-1 + u0)*(1 - v0)
337 + (1 - w0)*u0*(1 - v0)
338 + (-1 + w0)*(-1 + u0)*v0
339 )
340 + z1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
341 + z2*(w0*(-1 + u0)*v0 + w0*u0*v0)
342 + z3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
343 + z4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
344 + z5*((-1 + w0)*u0*v0 + w0*u0*v0)
345 - z6*2*w0*u0*v0
346 + z7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
347 ;
348
349 czv =
350 z0*(1 - w0)*(-1 + u0)
351 + z1*(-1 + w0)*(-1 + u0)
352 - z2*w0*(-1 + u0)
353 + z3*w0*(-1 + u0)
354 + z4*(-1 + w0)*u0
355 + z5*(1 - w0)*u0
356 + z6*w0*u0
357 - z7*w0*u0
358 ;
359
360 czw =
361 z0*(-1 + u0)*(1 - v0)
362 + z1*(-1 + u0)*v0
363 + z2*(1 - u0)*v0
364 + z3*(-1 + u0)*(-1 + v0)
365 + z4*u0*(-1 + v0)
366 - z5*u0*v0
367 + z6*u0*v0
368 + z7*u0*(1 - v0)
369 ;
370
371 czu =
372 z0*(-1 + w0)*(1 - v0)
373 + z1*(-1 + w0)*v0
374 - z2*w0*v0
375 + z3*w0*(-1 + v0)
376 + z4*(-1 + w0)*(-1 + v0)
377 + z5*(1 - w0)*v0
378 + z6*w0*v0
379 + z7*w0*(1 - v0)
380 ;
381
382 determinant = cxv*cyu*czw -
383 cxu*cyv*czw - cxv*cyw*czu +
384 cxw*cyv*czu + cxu*cyw*czv -
385 cxw*cyu*czv;
386
387 if (tm)
388 tm->info() << "ITERATION DETERMINANT = " << determinant << " " << u
389 << " " << v << " " << w;
390
391 if(math::abs(determinant)>1e-14){
392
393 u = (cxv*cyw*cz - cxw*cyv*cz - cxv*cy*czw
394 + cx*cyv*czw + cxw*cy*czv - cx*cyw*czv
395 + (- cyv*czw + cyw*czv) * x
396 + ( cxv*czw - cxw*czv) * y
397 + (- cxv*cyw + cxw*cyv) * z
398 )/determinant ;
399
400 v = (-cxu*cyw*cz + cxw*cyu*cz + cxu*cy*czw
401 - cx*cyu*czw - cxw*cy*czu + cx*cyw*czu
402 + ( cyu*czw - cyw*czu) * x
403 + (- cxu*czw + cxw*czu) * y
404 + ( cxu*cyw - cxw*cyu) * z
405 ) / determinant ;
406
407 w = -(cxv*cyu*cz - cxu*cyv*cz - cxv*cy*czu
408 + cx*cyv*czu + cxu*cy*czv - cx*cyu*czv
409 + (- cyv*czu + cyu*czv) * x
410 + ( cxv*czu - cxu*czv) * y
411 + (- cxv*cyu + cxu*cyv) * z
412 )/determinant ;
413
414 residue = NormeLinf(Real3(u,v,w),Real3(u0,v0,w0));
415 }
416 else {
417 if (tm)
418 tm->info() << "echec du Newton : déterminant nul";
419 error = true;
420 break;
421 }
422 } //for(int inewt=0; inewt<newton_loop_limit && residue>epsi_newton; inewt++ )
423
424 if (inewt == newton_loop_limit) {
425 if (tm)
426 tm->info() << "Too many iterations in the newton";
427 error = true;
428 }
429 // Cette routine calcule les coordonnées barycentriques entre 0 et 1 et
430 // on veut la valeur entre -1 et 1
431 Real3 iso(u,v,w);
432 iso -= Real3(0.5,0.5,0.5);
433 iso *= 2.0;
434 uvw = Real3(iso.y,iso.z,0.0);
435 return error;
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441/*---------------------------------------------------------------------------*/
442/*---------------------------------------------------------------------------*/
443
445projection(Real3 v1,Real3 v2,Real3 v3,Real3 point)
446{
447 Real3 kDiff = v1 - point;
448 Real3 edge0 = v2 - v1;
449 Real3 edge1 = v3 - v1;
450 Real fA00 = edge0.squareNormL2();
451 Real fA01 = math::dot(edge0,edge1);
452 Real fA11 = edge1.squareNormL2();
453 Real fB0 = math::dot(kDiff,edge0);
454 Real fB1 = math::dot(kDiff,edge1);
455 Real fC = kDiff.squareNormL2();
456 Real fDet = math::abs(fA00*fA11-fA01*fA01);
457 Real alpha = fA01*fB1-fA11*fB0;
458 Real beta = fA01*fB0-fA00*fB1;
459 Real distance2 = 0.0;
460 int region = -1;
461
462 if ( alpha + beta <= fDet ){
463 if ( alpha < 0.0 ){
464 if ( beta < 0.0 ){ // region 4
465 region = 4;
466 if ( fB0 < 0.0 ){
467 beta = 0.0;
468 if ( -fB0 >= fA00 ){
469 alpha = 1.0;
470 distance2 = fA00+(2.0)*fB0+fC;
471 }
472 else{
473 alpha = -fB0/fA00;
474 distance2 = fB0*alpha+fC;
475 }
476 }
477 else{
478 alpha = 0.0;
479 if ( fB1 >= 0.0 ){
480 beta = 0.0;
481 distance2 = fC;
482 }
483 else if ( -fB1 >= fA11 ){
484 beta = 1.0;
485 distance2 = fA11+(2.0)*fB1+fC;
486 }
487 else{
488 beta = -fB1/fA11;
489 distance2 = fB1*beta+fC;
490 }
491 }
492 }
493 else{ // region 3
494 region = 3;
495 alpha = 0.0;
496 if ( fB1 >= 0.0 ){
497 beta = 0.0;
498 distance2 = fC;
499 }
500 else if ( -fB1 >= fA11 ){
501 beta = 1.0;
502 distance2 = fA11+(2.0)*fB1+fC;
503 }
504 else{
505 beta = -fB1/fA11;
506 distance2 = fB1*beta+fC;
507 }
508 }
509 }
510 else if ( beta < 0.0 ){ // region 5
511 region = 5;
512 beta = 0.0;
513 if ( fB0 >= 0.0 ){
514 alpha = 0.0;
515 distance2 = fC;
516 }
517 else if ( -fB0 >= fA00 ){
518 alpha = 1.0;
519 distance2 = fA00+(2.0)*fB0+fC;
520 }
521 else{
522 alpha = -fB0/fA00;
523 distance2 = fB0*alpha+fC;
524 }
525 }
526 else{ // region 0
527 region = 0;
528 // minimum at interior point
529 Real fInvDet = (1.0)/fDet;
530 alpha *= fInvDet;
531 beta *= fInvDet;
532 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
533 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
534 }
535 }
536 else{
537 if ( alpha < 0.0 ){ // region 2
538 region = 2;
539 Real fTmp0 = fA01 + fB0;
540 Real fTmp1 = fA11 + fB1;
541 if ( fTmp1 > fTmp0 ){
542 Real fNumer = fTmp1 - fTmp0;
543 Real fDenom = fA00-2.0f*fA01+fA11;
544 if ( fNumer >= fDenom ){
545 alpha = 1.0;
546 beta = 0.0;
547 distance2 = fA00+(2.0)*fB0+fC;
548 }
549 else{
550 alpha = fNumer/fDenom;
551 beta = 1.0 - alpha;
552 distance2 = alpha*(fA00*alpha+fA01*beta+2.0f*fB0) +
553 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
554 }
555 }
556 else{
557 alpha = 0.0;
558 if (fTmp1 <= 0.0){
559 beta = 1.0;
560 distance2 = fA11+(2.0)*fB1+fC;
561 }
562 else if (fB1 >= 0.0){
563 beta = 0.0;
564 distance2 = fC;
565 }
566 else{
567 beta = -fB1/fA11;
568 distance2 = fB1*beta+fC;
569 }
570 }
571 }
572 else if (beta<0.0){ // region 6
573 region = 6;
574 Real fTmp0 = fA01 + fB1;
575 Real fTmp1 = fA00 + fB0;
576 if ( fTmp1 > fTmp0 ){
577 Real fNumer = fTmp1 - fTmp0;
578 Real fDenom = fA00-(2.0)*fA01+fA11;
579 if (fNumer>=fDenom){
580 beta = 1.0;
581 alpha = 0.0;
582 distance2 = fA11+(2.0)*fB1+fC;
583 }
584 else{
585 beta = fNumer/fDenom;
586 alpha = 1.0 - beta;
587 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
588 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
589 }
590 }
591 else{
592 beta = 0.0;
593 if (fTmp1 <= 0.0){
594 alpha = 1.0;
595 distance2 = fA00+(2.0)*fB0+fC;
596 }
597 else if (fB0>=0.0){
598 alpha = 0.0;
599 distance2 = fC;
600 }
601 else{
602 alpha = -fB0/fA00;
603 distance2 = fB0*alpha+fC;
604 }
605 }
606 }
607 else{ // region 1
608 region = 1;
609 Real fNumer = fA11 + fB1 - fA01 - fB0;
610 if (fNumer<=0.0){
611 alpha = 0.0;
612 beta = 1.0;
613 distance2 = fA11+(2.0)*fB1+fC;
614 }
615 else{
616 Real fDenom = fA00-2.0f*fA01+fA11;
617 if ( fNumer >= fDenom ){
618 alpha = 1.0;
619 beta = 0.0;
620 distance2 = fA00+(2.0)*fB0+fC;
621 }
622 else{
623 alpha = fNumer / fDenom;
624 beta = 1.0 - alpha;
625 distance2 = alpha*(fA00*alpha+fA01*beta+(2.0)*fB0) +
626 beta*(fA01*alpha+fA11*beta+(2.0)*fB1)+fC;
627 }
628 }
629 }
630 }
631
632 if (distance2<0.0)
633 distance2 = 0.0;
634
635 Real3 projection = v1 + alpha*edge0 + beta*edge1;
636
637 return ProjectionInfo(distance2,region,alpha,beta,projection);
638}
639
640
641/*---------------------------------------------------------------------------*/
642/*---------------------------------------------------------------------------*/
643
645projection(Real3 v1,Real3 v2,Real3 point)
646{
647 Real3 edge0 = v2 - v1;
648 Real3 edge1 = point - v1;
649 Real dot_product = math::dot(edge0,edge1);
650 Real norm = edge0.squareNormL2();
651 Real alpha = dot_product / norm;
652 int region = -1;
653 Real distance = 0.;
654 if (alpha<0.){
655 region = 1;
656 distance = edge1.squareNormL2();
657 }
658 else if (alpha>1.){
659 region = 2;
660 distance = (point-v2).squareNormL2();
661 }
662 else{
663 region = 0;
664 distance = (point - (v1 + alpha*edge0)).squareNormL2();
665 }
666 Real3 projection = v1 + alpha*edge0;
667#if 0
668 cout << "InfosDistance: v1=" << v1 << " v2=" << v2 << " point="
669 << point << " alpha=" << alpha
670 << " distance=" << distance
671 << " region=" << region
672 << " projection=" << projection << '\n';
673#endif
674 return ProjectionInfo(distance,region,alpha,0.,projection);
675}
676
677/*---------------------------------------------------------------------------*/
678/*---------------------------------------------------------------------------*/
679
681isInside(Real3 v1,Real3 v2,Real3 v3,Real3 point)
682{
683 Real3 kDiff = v1 - point;
684 Real3 edge0 = v2 - v1;
685 Real3 edge1 = v3 - v1;
686 Real fA00 = edge0.squareNormL2();
687 Real fA01 = math::dot(edge0,edge1);
688 Real fA11 = edge1.squareNormL2();
689 Real fB0 = math::dot(kDiff,edge0);
690 Real fB1 = math::dot(kDiff,edge1);
691
692 Real fDet = math::abs(fA00*fA11-fA01*fA01);
693
694 Real alpha = fA01*fB1-fA11*fB0;
695 Real beta = fA01*fB0-fA00*fB1;
696
697 if ( alpha + beta <= fDet ){
698 if ( alpha < 0.0 ){
699 return false;
700 }
701 else if ( beta < 0.0 ){
702 return false;
703 }
704 else{
705 return true;
706 }
707 }
708 return false;
709}
710
711/*---------------------------------------------------------------------------*/
712/*---------------------------------------------------------------------------*/
713
715isInside(Real3 v1,Real3 v2,Real3 point)
716{
717 Real3 edge0 = v2 - v1;
718 Real3 edge1 = point - v1;
719 Real dot_product = math::dot(edge0,edge1);
720 Real norm = edge0.squareNormL2();
721 //cout << "Infos: v1=" << v1 << " v2=" << v2 << " point="
722 //<< point << " dot=" << dot_product << " norm2=" << norm << '\n';
723 if (dot_product>0. && dot_product<norm)
724 return true;
725 return false;
726}
727
728/*---------------------------------------------------------------------------*/
729/*---------------------------------------------------------------------------*/
730
731} // End namespace Arcane
732
733/*---------------------------------------------------------------------------*/
734/*---------------------------------------------------------------------------*/
static ProjectionInfo projection(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Projection du point point au triangle défini par v1, v2 et v3.
static bool isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Indique si un la projection du point point est à l'intérieur du triangle défini par v1,...
bool cartesianToIso(Real3 point, Real3 &uvw, ITraceMng *tm)
Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
bool cartesianToIso2(Real3 point, Real3 &uvw, ITraceMng *tm)
Convertie une coordonnée cartérienne en coordonnée iso-paramétrique.
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
constexpr __host__ __device__ Real squareNormL2() const
Retourne la norme L2 au carré du triplet .
Definition Real3.h:230
Classe gérant une matrice de réel de dimension 3x3.
Definition Real3x3.h:66
Real3 z
premier élément du triplet
Definition Real3x3.h:119
Real3 y
premier élément du triplet
Definition Real3x3.h:118
Real3 x
premier élément du triplet
Definition Real3x3.h:117
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
__host__ __device__ Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
Definition MathUtils.h:96
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
Definition MathUtils.h:52
__host__ __device__ double sqrt(double v)
Racine carrée de v.
Definition Math.h:135
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.
Real y
deuxième composante du triplet
Definition Real3.h:36
Real z
troisième composante du triplet
Definition Real3.h:37
Real x
première composante du triplet
Definition Real3.h:35