Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
GeometricUtilities.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* Utility functions on geometry. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/Iostream.h"
15#include "arcane/utils/ITraceMng.h"
16
18#include "arcane/core/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/*!
69 * \brief Converts a Cartesian coordinate to an iso-parametric coordinate.
70 *
71 * This operation uses Newton's method to find the solution and may therefore
72 * fail to converge. In this case, it returns \a true.
73 *
74 * \param point Cartesian coordinate position of the point to be calculated.
75 * \param uvw returned, calculated iso-parametric coordinates
76 */
77
79cartesianToIso(Real3 point, Real3& uvw, ITraceMng* tm)
80{
81 const Real wanted_precision = m_precision;
82 const Integer max_iteration = 1000;
83
84 Real u_new, v_new, w_new;
85 Real relative_error = 1.0;
86 Integer nb_iter = 0;
87
88 uvw = Real3(0.5, 0.5, 0.0);
89
90 Real3x3 inverse_jacobian_matrix;
91
92 while (relative_error > wanted_precision && nb_iter < max_iteration) {
93 ++nb_iter;
94
95 computeInverseJacobian(uvw, inverse_jacobian_matrix);
96 Real3 new_pos = evaluatePosition(uvw);
97 u_new = uvw.x + inverse_jacobian_matrix.x.x * (point.x-new_pos.x)
98 + inverse_jacobian_matrix.y.x * (point.y-new_pos.y)
99 + inverse_jacobian_matrix.z.x * (point.z-new_pos.z);
100 v_new = uvw.y + inverse_jacobian_matrix.x.y * (point.x-new_pos.x)
101 + inverse_jacobian_matrix.y.y * (point.y-new_pos.y)
102 + inverse_jacobian_matrix.z.y * (point.z-new_pos.z);
103 //w_new = uvw.z + inverse_jacobian_matrix.x.z * (point.x-new_pos.x)
104 // + inverse_jacobian_matrix.y.z * (point.y-new_pos.y)
105 // + inverse_jacobian_matrix.z.z * (point.z-new_pos.z);
106 w_new = 0.;
107
108 relative_error = (u_new - uvw.x) * (u_new - uvw.x) +
109 (v_new - uvw.y) * (v_new - uvw.y) +
110 (w_new - uvw.z) * (w_new - uvw.z);
111
112 if (tm)
113 tm->info() << "CARTESIAN_TO_ISO I=" << nb_iter << " uvw=" << uvw
114 << " new_pos=" << new_pos
115 << " error=" << relative_error;
116
117 uvw.x = u_new;
118 uvw.y = v_new;
119 uvw.z = w_new;
120 }
121 return (relative_error > wanted_precision);
122}
123
124Real3 GeometricUtilities::QuadMapping::
125normal()
126{
127 Real3 normal = QuadMapping::_normal();
128 Real norm = normal.x * normal.x + normal.y * normal.y + normal.z * normal.z;
129 norm = math::sqrt(norm);
130 normal /= norm;
131 return normal;
132}
133
134static Real NormeLinf(Real3 v1, Real3 v2)
135{
136 Real3 v = v2 - v1;
137 Real norm = math::max(math::abs(v.x), math::abs(v.y));
138 norm = math::max(norm, math::abs(v.z));
139 return norm;
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145Real3 GeometricUtilities::QuadMapping::
146_normal()
147{
148 Real3 n0 = math::vecMul(m_pos[1] - m_pos[0], m_pos[2] - m_pos[0]);
149 Real3 n1 = math::vecMul(m_pos[2] - m_pos[1], m_pos[3] - m_pos[1]);
150 Real3 n2 = math::vecMul(m_pos[3] - m_pos[2], m_pos[0] - m_pos[2]);
151 Real3 n3 = math::vecMul(m_pos[0] - m_pos[3], m_pos[1] - m_pos[3]);
152 Real3 normal = (n0 + n1 + n2 + n3) * 0.25;
153 return normal;
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
159/*!
160 * \brief Converts a Cartesian coordinate to an iso-parametric coordinate.
161 *
162 * This operation uses Newton's method to find the solution and may therefore
163 * fail to converge. In this case, it returns \a true.
164 *
165 * \param point Cartesian coordinate position of the point to be calculated.
166 * \param uvw returned, calculated iso-parametric coordinates
167 */
168
170cartesianToIso2(Real3 point, Real3& uvw, ITraceMng* tm)
171{
172 Real epsi_newton = 1.0e-12;
173 int newton_loop_limit = 100;
174 bool error = false;
175
176 // Starting position for Newton
177 Real u = 0.5;
178 Real v = 0.5;
179 Real w = 0.5;
180
181 Real3 other_pos[4];
182 Real3 normal = _normal();
183 for (int i = 0; i < 4; ++i)
184 other_pos[i] = m_pos[i] + normal;
185
186 Real x0 = m_pos[0].x;
187 Real y0 = m_pos[0].y;
188 Real z0 = m_pos[0].z;
189 Real x1 = m_pos[1].x;
190 Real y1 = m_pos[1].y;
191 Real z1 = m_pos[1].z;
192 Real x2 = m_pos[2].x;
193 Real y2 = m_pos[2].y;
194 Real z2 = m_pos[2].z;
195 Real x3 = m_pos[3].x;
196 Real y3 = m_pos[3].y;
197 Real z3 = m_pos[3].z;
198
199 Real x4 = other_pos[0].x;
200 Real y4 = other_pos[0].y;
201 Real z4 = other_pos[0].z;
202 Real x5 = other_pos[1].x;
203 Real y5 = other_pos[1].y;
204 Real z5 = other_pos[1].z;
205 Real x6 = other_pos[2].x;
206 Real y6 = other_pos[2].y;
207 Real z6 = other_pos[2].z;
208 Real x7 = other_pos[3].x;
209 Real y7 = other_pos[3].y;
210 Real z7 = other_pos[3].z;
211
212 Real x = point.x;
213 Real y = point.y;
214 Real z = point.z;
215
216 Real cx = 0.0;
217 Real cy = 0.0;
218 Real cz = 0.0;
219 Real cxu = 0.0;
220 Real cyu = 0.0;
221 Real czu = 0.0;
222 Real cxv = 0.0;
223 Real cyv = 0.0;
224 Real czv = 0.0;
225 Real cxw = 0.0;
226 Real cyw = 0.0;
227 Real czw = 0.0;
228 Real determinant = 0.0;
229
230 // NEWTON loop
231 Real residue = 1.0e30;
232
233 Real u0;
234 Real v0;
235 Real w0;
236
237 int inewt = 0;
238 for (inewt = 0; inewt < newton_loop_limit && residue > epsi_newton; inewt++) {
239
240 u0 = u;
241 v0 = v;
242 w0 = w;
243
244 cx = + x0*((-1 + w0)*(-1 + u0)*(1 - v0)
245 - w0*(-1 + u0)*(1 - v0)
246 + (1 - w0)*u0*(1 - v0)
247 + (-1 + w0)*(-1 + u0)*v0
248 )
249 + x1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
250 + x2*(w0*(-1 + u0)*v0 + w0*u0*v0)
251 + x3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
252 + x4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
253 + x5*((-1 + w0)*u0*v0 + w0*u0*v0)
254 - x6*2*w0*u0*v0
255 + x7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
256 ;
257
258 cxv = x0*(1 - w0)*(-1 + u0)
259 + x1*(-1 + w0)*(-1 + u0)
260 - x2*w0*(-1 + u0)
261 + x3*w0*(-1 + u0)
262 + x4*(-1 + w0)*u0
263 + x5*(1 - w0)*u0
264 + x6*w0*u0
265 - x7*w0*u0
266 ;
267
268 cxw =
269 x0*(-1 + u0)*(1 - v0)
270 + x1*(-1 + u0)*v0
271 + x2*(1 - u0)*v0
272 + x3*(-1 + u0)*(-1 + v0)
273 + x4*u0*(-1 + v0)
274 - x5*u0*v0
275 + x6*u0*v0
276 + x7*u0*(1 - v0)
277 ;
278
279 cxu =
280 x0*(-1 + w0)*(1 - v0)
281 + x1*(-1 + w0)*v0
282 - x2*w0*v0
283 + x3*w0*(-1 + v0)
284 + x4*(-1 + w0)*(-1 + v0)
285 + x5*(1 - w0)*v0
286 + x6*w0*v0
287 + x7*w0*(1 - v0)
288 ;
289
290 cy =
291 + y0*((-1 + w0)*(-1 + u0)*(1 - v0)
292 - w0*(-1 + u0)*(1 - v0)
293 + (1 - w0)*u0*(1 - v0)
294 + (-1 + w0)*(-1 + u0)*v0
295 )
296 + y1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
297 + y2*(w0*(-1 + u0)*v0 + w0*u0*v0)
298 + y3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
299 + y4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
300 + y5*((-1 + w0)*u0*v0 + w0*u0*v0)
301 - y6*2*w0*u0*v0
302 + y7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
303 ;
304
305 cyv =
306 y0*(1 - w0)*(-1 + u0)
307 + y1*(-1 + w0)*(-1 + u0)
308 - y2*w0*(-1 + u0)
309 + y3*w0*(-1 + u0)
310 + y4*(-1 + w0)*u0
311 + y5*(1 - w0)*u0
312 + y6*w0*u0
313 - y7*w0*u0
314 ;
315
316 cyw =
317 y0*(-1 + u0)*(1 - v0)
318 + y1*(-1 + u0)*v0
319 + y2*(1 - u0)*v0
320 + y3*(-1 + u0)*(-1 + v0)
321 + y4*u0*(-1 + v0)
322 - y5*u0*v0
323 + y6*u0*v0
324 + y7*u0*(1 - v0)
325 ;
326
327 cyu = y0*(-1 + w0)*(1 - v0)
328 + y1*(-1 + w0)*v0
329 - y2*w0*v0
330 + y3*w0*(-1 + v0)
331 + y4*(-1 + w0)*(-1 + v0)
332 + y5*(1 - w0)*v0
333 + y6*w0*v0
334 + y7*w0*(1 - v0)
335 ;
336
337 cz = + z0*((-1 + w0)*(-1 + u0)*(1 - v0)
338 - w0*(-1 + u0)*(1 - v0)
339 + (1 - w0)*u0*(1 - v0)
340 + (-1 + w0)*(-1 + u0)*v0
341 )
342 + z1*(-(w0*(-1 + u0)*v0) + (1 - w0)*u0*v0)
343 + z2*(w0*(-1 + u0)*v0 + w0*u0*v0)
344 + z3*(-(w0*u0*(-1 + v0)) - w0*(-1 + u0)*v0)
345 + z4*(-(w0*u0*(-1 + v0)) + (1 - w0)*u0*v0)
346 + z5*((-1 + w0)*u0*v0 + w0*u0*v0)
347 - z6*2*w0*u0*v0
348 + z7*(-(w0*u0*(1 - v0)) + w0*u0*v0)
349 ;
350
351 czv =
352 z0*(1 - w0)*(-1 + u0)
353 + z1*(-1 + w0)*(-1 + u0)
354 - z2*w0*(-1 + u0)
355 + z3*w0*(-1 + u0)
356 + z4*(-1 + w0)*u0
357 + z5*(1 - w0)*u0
358 + z6*w0*u0
359 - z7*w0*u0
360 ;
361
362 czw =
363 z0*(-1 + u0)*(1 - v0)
364 + z1*(-1 + u0)*v0
365 + z2*(1 - u0)*v0
366 + z3*(-1 + u0)*(-1 + v0)
367 + z4*u0*(-1 + v0)
368 - z5*u0*v0
369 + z6*u0*v0
370 + z7*u0*(1 - v0)
371 ;
372
373 czu =
374 z0*(-1 + w0)*(1 - v0)
375 + z1*(-1 + w0)*v0
376 - z2*w0*v0
377 + z3*w0*(-1 + v0)
378 + z4*(-1 + w0)*(-1 + v0)
379 + z5*(1 - w0)*v0
380 + z6*w0*v0
381 + z7*w0*(1 - v0)
382 ;
383
384 determinant = cxv*cyu*czw -
385 cxu*cyv*czw - cxv*cyw*czu +
386 cxw*cyv*czu + cxu*cyw*czv -
387 cxw*cyu*czv;
388
389 if (tm)
390 tm->info() << "ITERATION DETERMINANT = " << determinant << " " << u
391 << " " << v << " " << w;
392
393 if (math::abs(determinant) > 1e-14) {
394
395 u = (cxv*cyw*cz - cxw*cyv*cz - cxv*cy*czw
396 + cx*cyv*czw + cxw*cy*czv - cx*cyw*czv
397 + (- cyv*czw + cyw*czv) * x
398 + ( cxv*czw - cxw*czv) * y
399 + (- cxv*cyw + cxw*cyv) * z
400 )/determinant ;
401
402 v = (-cxu*cyw*cz + cxw*cyu*cz + cxu*cy*czw
403 - cx*cyu*czw - cxw*cy*czu + cx*cyw*czu
404 + ( cyu*czw - cyw*czu) * x
405 + (- cxu*czw + cxw*czu) * y
406 + ( cxu*cyw - cxw*cyu) * z
407 ) / determinant ;
408
409 w = -(cxv*cyu*cz - cxu*cyv*cz - cxv*cy*czu
410 + cx*cyv*czu + cxu*cy*czv - cx*cyu*czv
411 + (- cyv*czu + cyu*czv) * x
412 + ( cxv*czu - cxu*czv) * y
413 + (- cxv*cyu + cxu*cyv) * z
414 )/determinant ;
415
416 residue = NormeLinf(Real3(u,v,w),Real3(u0,v0,w0));
417 }
418 else {
419 if (tm)
420 tm->info() << "Newton failure: determinant zero";
421 error = true;
422 break;
423 }
424 } //for(int inewt=0; inewt<newton_loop_limit && residue>epsi_newton; inewt++ )
425
426 if (inewt == newton_loop_limit) {
427 if (tm)
428 tm->info() << "Too many iterations in the newton";
429 error = true;
430 }
431 // This routine calculates the barycentric coordinates between 0 and 1 and
432 // we want the value between -1 and 1
433 Real3 iso(u, v, w);
434 iso -= Real3(0.5, 0.5, 0.5);
435 iso *= 2.0;
436 uvw = Real3(iso.y, iso.z, 0.0);
437 return error;
438}
439
440/*---------------------------------------------------------------------------*/
441/*---------------------------------------------------------------------------*/
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
447projection(Real3 v1, Real3 v2, Real3 v3, Real3 point)
448{
449 Real3 kDiff = v1 - point;
450 Real3 edge0 = v2 - v1;
451 Real3 edge1 = v3 - v1;
452 Real fA00 = edge0.squareNormL2();
453 Real fA01 = math::dot(edge0, edge1);
454 Real fA11 = edge1.squareNormL2();
455 Real fB0 = math::dot(kDiff, edge0);
456 Real fB1 = math::dot(kDiff, edge1);
457 Real fC = kDiff.squareNormL2();
458 Real fDet = math::abs(fA00 * fA11 - fA01 * fA01);
459 Real alpha = fA01 * fB1 - fA11 * fB0;
460 Real beta = fA01 * fB0 - fA00 * fB1;
461 Real distance2 = 0.0;
462 int region = -1;
463
464 if (alpha + beta <= fDet) {
465 if (alpha < 0.0) {
466 if (beta < 0.0) { // region 4
467 region = 4;
468 if (fB0 < 0.0) {
469 beta = 0.0;
470 if (-fB0 >= fA00) {
471 alpha = 1.0;
472 distance2 = fA00 + (2.0) * fB0 + fC;
473 }
474 else {
475 alpha = -fB0 / fA00;
476 distance2 = fB0 * alpha + fC;
477 }
478 }
479 else {
480 alpha = 0.0;
481 if (fB1 >= 0.0) {
482 beta = 0.0;
483 distance2 = fC;
484 }
485 else if (-fB1 >= fA11) {
486 beta = 1.0;
487 distance2 = fA11 + (2.0) * fB1 + fC;
488 }
489 else {
490 beta = -fB1 / fA11;
491 distance2 = fB1 * beta + fC;
492 }
493 }
494 }
495 else { // region 3
496 region = 3;
497 alpha = 0.0;
498 if (fB1 >= 0.0) {
499 beta = 0.0;
500 distance2 = fC;
501 }
502 else if (-fB1 >= fA11) {
503 beta = 1.0;
504 distance2 = fA11 + (2.0) * fB1 + fC;
505 }
506 else {
507 beta = -fB1 / fA11;
508 distance2 = fB1 * beta + fC;
509 }
510 }
511 }
512 else if (beta < 0.0) { // region 5
513 region = 5;
514 beta = 0.0;
515 if (fB0 >= 0.0) {
516 alpha = 0.0;
517 distance2 = fC;
518 }
519 else if (-fB0 >= fA00) {
520 alpha = 1.0;
521 distance2 = fA00 + (2.0) * fB0 + fC;
522 }
523 else {
524 alpha = -fB0 / fA00;
525 distance2 = fB0 * alpha + fC;
526 }
527 }
528 else { // region 0
529 region = 0;
530 // minimum at interior point
531 Real fInvDet = (1.0) / fDet;
532 alpha *= fInvDet;
533 beta *= fInvDet;
534 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
535 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
536 }
537 }
538 else {
539 if (alpha < 0.0) { // region 2
540 region = 2;
541 Real fTmp0 = fA01 + fB0;
542 Real fTmp1 = fA11 + fB1;
543 if (fTmp1 > fTmp0) {
544 Real fNumer = fTmp1 - fTmp0;
545 Real fDenom = fA00 - 2.0f * fA01 + fA11;
546 if (fNumer >= fDenom) {
547 alpha = 1.0;
548 beta = 0.0;
549 distance2 = fA00 + (2.0) * fB0 + fC;
550 }
551 else {
552 alpha = fNumer / fDenom;
553 beta = 1.0 - alpha;
554 distance2 = alpha * (fA00 * alpha + fA01 * beta + 2.0f * fB0) +
555 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
556 }
557 }
558 else {
559 alpha = 0.0;
560 if (fTmp1 <= 0.0) {
561 beta = 1.0;
562 distance2 = fA11 + (2.0) * fB1 + fC;
563 }
564 else if (fB1 >= 0.0) {
565 beta = 0.0;
566 distance2 = fC;
567 }
568 else {
569 beta = -fB1 / fA11;
570 distance2 = fB1 * beta + fC;
571 }
572 }
573 }
574 else if (beta < 0.0) { // region 6
575 region = 6;
576 Real fTmp0 = fA01 + fB1;
577 Real fTmp1 = fA00 + fB0;
578 if (fTmp1 > fTmp0) {
579 Real fNumer = fTmp1 - fTmp0;
580 Real fDenom = fA00 - (2.0) * fA01 + fA11;
581 if (fNumer >= fDenom) {
582 beta = 1.0;
583 alpha = 0.0;
584 distance2 = fA11 + (2.0) * fB1 + fC;
585 }
586 else {
587 beta = fNumer / fDenom;
588 alpha = 1.0 - beta;
589 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
590 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
591 }
592 }
593 else {
594 beta = 0.0;
595 if (fTmp1 <= 0.0) {
596 alpha = 1.0;
597 distance2 = fA00 + (2.0) * fB0 + fC;
598 }
599 else if (fB0 >= 0.0) {
600 alpha = 0.0;
601 distance2 = fC;
602 }
603 else {
604 alpha = -fB0 / fA00;
605 distance2 = fB0 * alpha + fC;
606 }
607 }
608 }
609 else { // region 1
610 region = 1;
611 Real fNumer = fA11 + fB1 - fA01 - fB0;
612 if (fNumer <= 0.0) {
613 alpha = 0.0;
614 beta = 1.0;
615 distance2 = fA11 + (2.0) * fB1 + fC;
616 }
617 else {
618 Real fDenom = fA00 - 2.0f * fA01 + fA11;
619 if (fNumer >= fDenom) {
620 alpha = 1.0;
621 beta = 0.0;
622 distance2 = fA00 + (2.0) * fB0 + fC;
623 }
624 else {
625 alpha = fNumer / fDenom;
626 beta = 1.0 - alpha;
627 distance2 = alpha * (fA00 * alpha + fA01 * beta + (2.0) * fB0) +
628 beta * (fA01 * alpha + fA11 * beta + (2.0) * fB1) + fC;
629 }
630 }
631 }
632 }
633
634 if (distance2 < 0.0)
635 distance2 = 0.0;
636
637 Real3 projection = v1 + alpha * edge0 + beta * edge1;
638
639 return ProjectionInfo(distance2, region, alpha, beta, projection);
640}
641
642/*---------------------------------------------------------------------------*/
643/*---------------------------------------------------------------------------*/
644
646projection(Real3 v1, Real3 v2, Real3 point)
647{
648 Real3 edge0 = v2 - v1;
649 Real3 edge1 = point - v1;
650 Real dot_product = math::dot(edge0, edge1);
651 Real norm = edge0.squareNormL2();
652 Real alpha = dot_product / norm;
653 int region = -1;
654 Real distance = 0.;
655 if (alpha < 0.) {
656 region = 1;
657 distance = edge1.squareNormL2();
658 }
659 else if (alpha > 1.) {
660 region = 2;
661 distance = (point - v2).squareNormL2();
662 }
663 else {
664 region = 0;
665 distance = (point - (v1 + alpha * edge0)).squareNormL2();
666 }
667 Real3 projection = v1 + alpha * edge0;
668#if 0
669 cout << "InfosDistance: v1=" << v1 << " v2=" << v2 << " point="
670 << point << " alpha=" << alpha
671 << " distance=" << distance
672 << " region=" << region
673 << " projection=" << projection << '\n';
674#endif
675 return ProjectionInfo(distance, region, alpha, 0., projection);
676}
677
678/*---------------------------------------------------------------------------*/
679/*---------------------------------------------------------------------------*/
680
682isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
683{
684 Real3 kDiff = v1 - point;
685 Real3 edge0 = v2 - v1;
686 Real3 edge1 = v3 - v1;
687 Real fA00 = edge0.squareNormL2();
688 Real fA01 = math::dot(edge0, edge1);
689 Real fA11 = edge1.squareNormL2();
690 Real fB0 = math::dot(kDiff, edge0);
691 Real fB1 = math::dot(kDiff, edge1);
692
693 Real fDet = math::abs(fA00 * fA11 - fA01 * fA01);
694
695 Real alpha = fA01 * fB1 - fA11 * fB0;
696 Real beta = fA01 * fB0 - fA00 * fB1;
697
698 if (alpha + beta <= fDet) {
699 if (alpha < 0.0) {
700 return false;
701 }
702 else if (beta < 0.0) {
703 return false;
704 }
705 else {
706 return true;
707 }
708 }
709 return false;
710}
711
712/*---------------------------------------------------------------------------*/
713/*---------------------------------------------------------------------------*/
714
716isInside(Real3 v1, Real3 v2, Real3 point)
717{
718 Real3 edge0 = v2 - v1;
719 Real3 edge1 = point - v1;
720 Real dot_product = math::dot(edge0, edge1);
721 Real norm = edge0.squareNormL2();
722 //cout << "Infos: v1=" << v1 << " v2=" << v2 << " point="
723 //<< point << " dot=" << dot_product << " norm2=" << norm << '\n';
724 if (dot_product > 0. && dot_product < norm)
725 return true;
726 return false;
727}
728
729/*---------------------------------------------------------------------------*/
730/*---------------------------------------------------------------------------*/
731
732} // End namespace Arcane
733
734/*---------------------------------------------------------------------------*/
735/*---------------------------------------------------------------------------*/
Various mathematical functions.
static ProjectionInfo projection(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Projection of point point onto the triangle defined by v1, v2 and v3.
static bool isInside(Real3 v1, Real3 v2, Real3 v3, Real3 point)
Indicates if the projection of point point is inside the triangle defined by v1, v2 and v3.
bool cartesianToIso(Real3 point, Real3 &uvw, ITraceMng *tm)
Converts a Cartesian coordinate to an iso-parametric coordinate.
Real3 evaluatePosition(Real3 iso) const
Calculates Cartesian coordinates from iso-barycentric coordinates.
bool cartesianToIso2(Real3 point, Real3 &uvw, ITraceMng *tm)
Converts a Cartesian coordinate to an iso-parametric coordinate.
virtual TraceMessage info()=0
Stream for an information message.
Class managing a 3-dimensional real vector.
Definition Real3.h:132
constexpr __host__ __device__ Real squareNormL2() const
Returns the square of the L2 norm of the triplet $ .
Definition Real3.h:455
Class managing a 3x3 real matrix.
Definition Real3x3.h:67
Real3 z
first element of the triplet
Definition Real3x3.h:131
Real3 y
first element of the triplet
Definition Real3x3.h:130
Real3 x
first element of the triplet
Definition Real3x3.h:129
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
Definition MathUtils.h:94
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
Definition MathUtils.h:407
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
Definition MathUtils.h:48
__host__ __device__ double sqrt(double v)
Square root of v.
Definition Math.h:142
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
Real y
second component of the triplet
Definition Real3.h:36
Real z
third component of the triplet
Definition Real3.h:37
Real x
first component of the triplet
Definition Real3.h:35