Loading...
Searching...
No Matches
CG_elem.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25# include <cmath>
26# include <memory>
27# include <string>
28# include <iostream>
29
30# include <assert.h>
31
32# include "bitpit_operators.hpp"
33
34# include "CG.hpp"
35# include "CG_private.hpp"
36
37
38namespace bitpit{
39
40namespace CGElem{
41
42
64void _projectPointsTriangle( int nPoints, array3D const *points, array3D const &Q0, array3D const &Q1, array3D const &Q2, array3D *proj, double *lambda )
65{
66 assert( validTriangle(Q0,Q1,Q2) );
67
68 array3D v0 = Q1 - Q0;
69 array3D v1 = Q2 - Q0;
70
71 array3D n = crossProduct(v0, v1);
72 double n2 = dotProduct(n, n);
73
74 for( int i=0; i<nPoints; ++i){
75 array3D v2 = points[i] - Q0;
76
77 double *pointLambda = lambda + 3 * i;
78 pointLambda[2] = dotProduct(crossProduct(v0, v2), n) / n2;
79 pointLambda[1] = dotProduct(crossProduct(v2, v1), n) / n2;
80 pointLambda[0] = 1. - pointLambda[1] - pointLambda[2];
81
82 array3D *pointProjections = proj + i;
83 *pointProjections = restrictPointTriangle( Q0, Q1, Q2, pointLambda);
84 }
85}
86
104bool _intersectBoxTriangle(array3D const &A0, array3D const &A1, array3D const &V0, array3D const &V1, array3D const &V2, bool interiorTriangleVertices, bool triangleEdgeBoxHullIntersections, bool triangleBoxEdgeIntersections, std::vector<array3D> *intrPtr, std::vector<int> *flagPtr, int dim, const double distanceTolerance)
105{
106
107 bool intersect(false);
108 bool addFlag( flagPtr!=nullptr);
109 bool computeIntersection(interiorTriangleVertices||triangleBoxEdgeIntersections||triangleEdgeBoxHullIntersections);
110
111 assert( ! (computeIntersection && (intrPtr==nullptr) ) );
112
113 if(computeIntersection){
114 intrPtr->clear();
115 }
116
117 if(addFlag){
118 flagPtr->clear();
119 }
120
121 //check if Triangle Boundig Box and Box overlap -> necessary condition
122 array3D B0, B1;
123 computeAABBTriangle( V0, V1, V2, B0, B1);
124
125 if( !intersectBoxBox( A0, A1, B0, B1, dim, distanceTolerance) ) {
126 return false;
127 }
128
129 //check if triangle vertices are within the box
130 for( int i=0; i<3; ++i){
131 vertexOfTriangle(i, V0, V1, V2, B0);
132 if( intersectPointBox(B0, A0, A1, dim, distanceTolerance) ){
133 intersect = true;
134 if(!interiorTriangleVertices) break;
135
136 intrPtr->push_back(B0);
137 if(addFlag) flagPtr->push_back(0);
138 }
139 }
140
141 //check if triangle edges and box faces intersect
142 if( !intersect || triangleEdgeBoxHullIntersections) {
143
144 for( int edge=0; edge<3; ++edge){
145
146 edgeOfTriangle(edge, V0, V1, V2, B0, B1);
147
148 if(dim==2){
149 array3D p;
150 array3D faceVertex0, faceVertex1;
151
152 for( int face=0; face<4; ++face){
153 edgeOfBox( face, A0, A1, faceVertex0, faceVertex1);
154
155 if( intersectSegmentSegment(B0, B1, faceVertex0, faceVertex1, p, distanceTolerance) ){
156 intersect=true;
157 if(!triangleEdgeBoxHullIntersections) break;
158
159 intrPtr->push_back(p);
160 if(addFlag) flagPtr->push_back(1);
161 }
162
163 }
164
165 } else if(dim==3){
166 array3D p;
167 std::array<array3D, 4> V;
168
169 for( int face=0; face<6; ++face){
170 faceOfBox( face, A0, A1, V[0], V[1], V[2], V[3] );
171
172 if( intersectSegmentPolygon( B0, B1, V.size(), V.data(), p, distanceTolerance ) ) {
173 intersect=true;
174 if(!triangleEdgeBoxHullIntersections) break;
175
176 intrPtr->push_back(p);
177 if(addFlag) flagPtr->push_back(1);
178 }
179 }
180 }
181 }
182 }
183
184 //check if triangle and box edges (dim=3) or box vertices (dim=2) intersect
185 if( !intersect || triangleBoxEdgeIntersections ) {
186
187 array3D p;
188
189 if(dim==2){
190 for( int i=0; i<4; ++i){
191 vertexOfBox( i, A0, A1, B0);
192 if( intersectPointTriangle(B0,V0,V1,V2,distanceTolerance)) {
193 intersect = true;
194 if(!triangleBoxEdgeIntersections) break;
195
196 intrPtr->push_back(B0);
197 if(addFlag) flagPtr->push_back(2);
198 }
199 }
200
201 } else if(dim==3){
202 for( int i=0; i<12; ++i){
203 edgeOfBox( i, A0, A1, B0, B1);
204 if( intersectSegmentTriangle(B0,B1,V0,V1,V2,p,distanceTolerance)) {
205 intersect = true;
206 if(!triangleBoxEdgeIntersections) break;
207
208 intrPtr->push_back(p);
209 if(addFlag) flagPtr->push_back(2);
210 }
211 }
212 }
213 }
214
215 return intersect;
216}
217
233bool _intersectSegmentBox(array3D const &V0, array3D const &V1, array3D const &A0, array3D const &A1, bool interiorSegmentVertice, bool segmentBoxHullIntersection, std::vector<array3D> *intrPtr, std::vector<int> *flagPtr, int dim, const double distanceTolerance)
234{
235
236 bool intersect(false);
237
238 bool addFlag(flagPtr!=nullptr);
239 bool computeIntersection(interiorSegmentVertice||segmentBoxHullIntersection);
240
241 assert( ! (computeIntersection && (intrPtr==nullptr) ) );
242
243 if(computeIntersection){
244 intrPtr->clear();
245 }
246
247 if(addFlag){
248 flagPtr->clear();
249 }
250
251 array3D p, B0, B1;
252
253 //check if segment boundig box and Box overlap
254 computeAABBSegment( V0, V1, B0, B1);
255 if( !intersectBoxBox( A0, A1, B0, B1, dim, distanceTolerance) ) {
256 return false;
257 }
258
259 //check segment points
260 for( int i=0; i<2; ++i){
261 vertexOfSegment(i, V0, V1, B0);
262
263 if( intersectPointBox(B0,A0,A1,dim,distanceTolerance) ){
264 intersect = true;
265 if(!interiorSegmentVertice) break;
266
267 intrPtr->push_back(B0);
268 if(addFlag) flagPtr->push_back(0);
269 }
270 }
271
272 //check if segment intersects outer hull of box
273 if( !intersect || segmentBoxHullIntersection){
274 if( dim == 2){ //check if box edge and segment intersect
275
276 for( int i=0; i<4; ++i){
277 edgeOfBox( i, A0, A1, B0, B1);
278
279 if( intersectSegmentSegment(B0,B1,V0,V1,p,distanceTolerance)) {
280 intersect = true;
281 if(!segmentBoxHullIntersection) break;
282
283 intrPtr->push_back(p);
284 if(addFlag) flagPtr->push_back(1);
285 }
286 }
287
288
289 } else if( dim==3 ) { //3D check if box face and segment intersect
290
291 std::array<array3D, 4> E;
292
293 for( int i=0; i<6; ++i){
294 faceOfBox( i, A0, A1, E[0], E[1], E[2], E[3]);
295
296 if( intersectSegmentPolygon(V0,V1,E.size(),E.data(),p,distanceTolerance) ) {
297 intersect = true;
298 if(!segmentBoxHullIntersection) break;
299
300 intrPtr->push_back(p);
301 if(addFlag) flagPtr->push_back(1);
302 }
303 }
304 }
305 }
306
307 return intersect;
308
309}
310
324bool _intersectPlaneBox(array3D const &P, array3D const &N, array3D const &A0, array3D const &A1, std::vector<array3D> *intrPtr, int dim, const double distanceTolerance)
325{
326
327 bool intersect(false);
328 bool computeIntersection(intrPtr);
329
330 if(computeIntersection){
331 intrPtr->clear();
332 } else if( intersectPointBox(P,A0,A1,dim,distanceTolerance)) {
333 return true;
334 }
335
336 // check if plane intersects the edges of the box
337 // and store eventually intersection points
338 int edgeCount = (dim==2) ? 4 : 12;
339 array3D E0, E1, V;
340
341 for(int i=0; i<edgeCount; ++i){
342 edgeOfBox(i, A0, A1, E0, E1);
343
344 if( intersectSegmentPlane( E0, E1, P, N, V, distanceTolerance) ){
345 intersect = true;
346
347 if(intrPtr){
348 intrPtr->push_back(V);
349 } else {
350 break;
351 }
352 }
353 }
354
355
356 // sort intersection points in couterclock-wise sense
357 if( dim==3 && intrPtr && intersect){
358
359 const array3D origin = intrPtr->at(0);
360
361 std::sort(intrPtr->begin(), intrPtr->end(), [&](const array3D &lhs, const array3D &rhs) -> bool {
362 array3D v = crossProduct(lhs-origin,rhs-origin);
363 return dotProduct(v, N) < 0;
364 } );
365 }
366
367 return intersect;
368}
369
386bool _intersectBoxPolygon(array3D const &A0, array3D const &A1, std::size_t nVS, array3D const *VS, bool innerPolygonPoints, bool polygonEdgeBoxHullIntersection, bool polygonBoxEdgeIntersections, std::vector<array3D> *intrPtr, std::vector<int> *flagPtr, int dim, const double distanceTolerance)
387{
388
389 bool intersect(false);
390 bool addFlag(flagPtr!=nullptr);
391 bool computeIntersection(innerPolygonPoints || polygonEdgeBoxHullIntersection || polygonBoxEdgeIntersections);
392
393 assert( ! (computeIntersection && (intrPtr==nullptr) ) );
394
395 if(computeIntersection){
396 intrPtr->clear();
397 }
398
399 if(addFlag){
400 flagPtr->clear();
401 }
402
403 array3D V0, V1, V2;
404
405 //check if simplex boundig box and box overlap -> necessary condition
406 computeAABBPolygon( nVS, VS, V0, V1);
407 if( !intersectBoxBox( A0, A1, V0, V1, dim, distanceTolerance) ) {
408 return false;
409 }
410
411 std::vector<array3D> partialIntr;
412 std::vector<int> partialFlag;
413
414 // check if triangle vertices lie within box
415 // or if triangles intersect edges of box
416 computeIntersection = innerPolygonPoints || polygonBoxEdgeIntersections;
417 int trianglesCount = polygonSubtriangleCount(nVS, VS);
418 for (int triangle=0; triangle<trianglesCount; ++triangle) {
419 subtriangleOfPolygon(triangle, nVS, VS, V0, V1, V2);
420
421 if( _intersectBoxTriangle( A0, A1, V0, V1, V2, innerPolygonPoints, false, polygonBoxEdgeIntersections, &partialIntr, &partialFlag, dim, distanceTolerance ) ){
422
423 intersect = true;
424 if(!computeIntersection) break;
425
426 int intrCount = partialIntr.size();
427 for( int i=0; i<intrCount; ++i){
428 // Get the intersection point
429 //
430 // Polygon triangulation adds a dummy vertex at the centroid of the polygon (V0).
431 // This vertex should not be taken into account for intersection identification.
432 array3D &candidateCoord = partialIntr[i];
433 if (utils::DoubleFloatingEqual()(norm2(V0 - candidateCoord), 0., distanceTolerance )) {
434 continue;
435 }
436
437 int candidateFlag = partialFlag[i];
438
439 //prune duplicate points
440 auto PItr = intrPtr->begin();
441 bool iterate = (PItr!=intrPtr->end());
442 while(iterate){
443
444 iterate = !utils::DoubleFloatingEqual()( norm2( *PItr -candidateCoord ), 0., distanceTolerance );
445
446 if(iterate){
447 ++PItr;
448 }
449 iterate &= PItr!=intrPtr->end();
450 }
451
452 if(PItr!=intrPtr->end()){
453 continue;
454 }
455
456 intrPtr->push_back(candidateCoord);
457 if(addFlag){
458 flagPtr->push_back(candidateFlag);
459 }
460 }
461 }
462 }
463
464 // check if edges of polygon intersect box face
465 computeIntersection = polygonEdgeBoxHullIntersection;
466 int edgesCount = polygonEdgesCount(nVS, VS);
467 if(!intersect || polygonEdgeBoxHullIntersection){
468 for (int edge=0; edge<edgesCount; ++edge) {
469 edgeOfPolygon(edge, nVS, VS, V0, V1);
470
471 if( _intersectSegmentBox( V0, V1, A0, A1, false, polygonEdgeBoxHullIntersection, &partialIntr, &partialFlag, dim, distanceTolerance) ){
472
473 intersect = true;
474 if(!computeIntersection) break;
475
476 int intrCount = partialIntr.size();
477 for( int i=0; i<intrCount; ++i){
478
479 array3D &candidateCoord = partialIntr[i];
480 int candidateFlag = partialFlag[i];
481
482 //prune duplicate points
483 auto PItr = intrPtr->begin();
484 bool iterate = (PItr!=intrPtr->end());
485 while(iterate){
486
487 iterate = !utils::DoubleFloatingEqual()( norm2( *PItr -candidateCoord ), 0., distanceTolerance );
488
489 if(iterate){
490 ++PItr;
491 }
492 iterate &= PItr!=intrPtr->end();
493 }
494
495 if(PItr!=intrPtr->end()){
496 continue;
497 }
498
499 intrPtr->push_back(candidateCoord);
500 if(addFlag){
501 flagPtr->push_back(candidateFlag);
502 }
503 }
504 }
505 }
506 }
507
508 return intersect;
509}
510
517bool validSegment(const array3D &P0, const array3D &P1 )
518{
519 return !utils::DoubleFloatingEqual()( norm2(P1-P0), 0.);
520}
521
528bool validLine(const array3D &P, const array3D &n )
529{
530 BITPIT_UNUSED(P);
531 return utils::DoubleFloatingEqual()( norm2(n), 1.);
532}
533
540bool validPlane(const array3D &P, const array3D &n )
541{
542 BITPIT_UNUSED(P);
543 return utils::DoubleFloatingEqual()( norm2(n), 1.);
544}
545
553bool validTriangle(const array3D &P0, const array3D &P1, const array3D &P2 )
554{
555
556 array3D v0 = P1 -P0;
557 if( utils::DoubleFloatingEqual()( norm2(v0), 0.) ){
558 return false;
559 }
560
561 array3D v1 = P2 -P1;
562 if( utils::DoubleFloatingEqual()( norm2(v1), 0.) ){
563 return false;
564 }
565
566 array3D v2 = P0 -P2;
567 if( utils::DoubleFloatingEqual()( norm2(v2), 0.) ){
568 return false;
569 }
570
571 array3D n = crossProduct( v0, -1.*v2);
572 if( utils::DoubleFloatingEqual()( norm2(n), 0. ) ){
573 return false;
574 }
575
576 return true;
577}
578
585bool validBarycentric(double const *lambdaPtr, int n )
586{
587
588 double sum(-1.);
589 double maxValue(0.);
590
591 for(int i=0; i<n; ++i){
592
593 double value = lambdaPtr[i];
594 if( std::abs(value) > std::abs(maxValue) ){
595 sum -= maxValue;
596 maxValue = -value;
597
598 } else {
599 sum += value;
600
601 }
602
603 }
604
605 double tolerance = std::max(1., std::abs(maxValue)) * std::numeric_limits<double>::epsilon();
606 return utils::DoubleFloatingEqual()(sum, maxValue, tolerance);
607}
608
618int convertBarycentricToFlagSegment( std::array<double,2> const &lambda, double tolerance)
619{
620
621 return convertBarycentricToFlagSegment( lambda.data(), tolerance);
622}
623
633int convertBarycentricToFlagSegment( const double *lambda, double tolerance)
634{
635
636 assert( validBarycentric(&lambda[0],2) );
637
638 if ( lambda[0] > 1. || utils::DoubleFloatingEqual()( lambda[0], 1., tolerance ) ) {
639 return 1;
640
641 } else if ( lambda[1] > 1. || utils::DoubleFloatingEqual()( lambda[1], 1., tolerance ) ) {
642 return 2;
643
644 }
645
646 return 0;
647}
648
658int convertBarycentricToFlagTriangle( array3D const &lambda, double tolerance)
659{
660 return convertBarycentricToFlagPolygon( 3, lambda.data(), tolerance);
661}
662
672int convertBarycentricToFlagTriangle( const double *lambda, double tolerance)
673{
674 return convertBarycentricToFlagPolygon( 3, lambda, tolerance);
675}
676
686int convertBarycentricToFlagPolygon( std::vector<double> const &lambda, double tolerance)
687{
688 return convertBarycentricToFlagPolygon( lambda.size(), lambda.data(), tolerance);
689}
690
701int convertBarycentricToFlagPolygon( std::size_t nLambda, double const *lambda, double tolerance)
702{
703
704 assert( validBarycentric(&lambda[0],nLambda) );
705
706 int count = 0;
707 std::size_t lastPositive = std::numeric_limits<std::size_t>::max();
708 for( std::size_t i=0; i<nLambda; ++i){
709 if ( lambda[i] < 0. || utils::DoubleFloatingEqual()( lambda[i], 0., tolerance ) ) {
710 continue;
711 }
712
713 ++count;
714 if (count > 2) {
715 return 0;
716 }
717
718 if (lastPositive != 0 || i == 1) {
719 lastPositive = i;
720 }
721 }
722
723 if( count == 1){
724 count = lastPositive + 1;
725
726 } else if (count==2) {
727 if (lastPositive != 0) {
728 count = - static_cast<int>(lastPositive);
729 } else {
730 count = - static_cast<int>(nLambda);
731 }
732
733 }
734
735 return count;
736}
737
750void computeGeneralizedBarycentric( array3D const &p, std::vector<array3D> const &vertex, std::vector<double> &lambda)
751{
752 computeGeneralizedBarycentric( p, vertex.size(), vertex.data(), lambda);
753}
754
768void computeGeneralizedBarycentric( array3D const &p, std::size_t nVertices, array3D const *vertex, std::vector<double> &lambda)
769{
770 lambda.resize(nVertices);
771
772 computeGeneralizedBarycentric( p, nVertices, vertex, lambda.data());
773}
774
788void computeGeneralizedBarycentric( array3D const &p, std::size_t nVertices, array3D const *vertex, double *lambda)
789{
790 const int MAX_ELEM_VERTICES = 8;
791 BITPIT_CREATE_WORKSPACE(area, double, nVertices, MAX_ELEM_VERTICES);
792
793 for( std::size_t i=0; i<nVertices; ++i){
794 int next = (i +1) %nVertices;
795 area[i] = areaTriangle( vertex[i], vertex[next], p);
796 }
797
798 double sumWeight(0);
799
800 for( std::size_t i=0; i<nVertices; ++i){
801 std::size_t prev = (i +nVertices -1) %nVertices;
802 std::size_t next = (i +1) %nVertices;
803 lambda[i] = areaTriangle(vertex[prev], vertex[i], vertex[next]);
804
805 for( std::size_t j=0; j<nVertices; ++j){
806 if( j==prev || j==i){
807 continue;
808 }
809
810 lambda[i] *= area[j];
811 }
812
813 sumWeight += lambda[i];
814 }
815
816 for( std::size_t i=0; i<nVertices; ++i){
817 lambda[i] /= sumWeight;
818 }
819}
820
828array3D reconstructPointFromBarycentricSegment(array3D const &Q0, array3D const &Q1, std::array<double,2> const &lambda)
829{
830 assert( validBarycentric(&lambda[0],2) );
831
832 return lambda[0]*Q0 +lambda[1]*Q1;
833}
834
842array3D reconstructPointFromBarycentricSegment(array3D const &Q0, array3D const &Q1, double const *lambda)
843{
844 assert( validBarycentric(&lambda[0],2) );
845
846 return lambda[0]*Q0 +lambda[1]*Q1;
847}
848
857array3D reconstructPointFromBarycentricTriangle(array3D const &Q0, array3D const &Q1, array3D const &Q2, array3D const &lambda)
858{
859 assert( validBarycentric(&lambda[0],3) );
860
861 return lambda[0]*Q0 +lambda[1]*Q1 +lambda[2]*Q2;
862}
863
872array3D reconstructPointFromBarycentricTriangle(array3D const &Q0, array3D const &Q1, array3D const &Q2, double const *lambda)
873{
874 assert( validBarycentric(&lambda[0],3) );
875
876 return lambda[0]*Q0 +lambda[1]*Q1 +lambda[2]*Q2;
877}
878
892array3D rotatePoint(const array3D &P, const array3D &n0, const array3D &n1, double angle)
893{
894 // Check if the axis is valid
895 double axisNorm = norm2(n1 - n0);
896 if (utils::DoubleFloatingEqual()(axisNorm, 0.)) {
897 return P;
898 }
899
900 // Transform point to a coordinates system centered in n0
901 array3D Q = P - n0;
902
903 // Rotate the point
904 std::array<double, 3> axis = (n1 - n0) / axisNorm;
905 double axis_dot = dotProduct(axis, Q);
906 std::array<double, 3> axis_cross = crossProduct(axis, Q);
907
908 double angle_cos = std::cos(angle);
909 double angle_sin = std::sin(angle);
910
911 Q[0] = Q[0] * angle_cos + axis[0] * axis_dot * (1. - angle_cos) + axis_cross[0] * angle_sin;
912 Q[1] = Q[1] * angle_cos + axis[1] * axis_dot * (1. - angle_cos) + axis_cross[1] * angle_sin;
913 Q[2] = Q[2] * angle_cos + axis[2] * axis_dot * (1. - angle_cos) + axis_cross[2] * angle_sin;
914
915 // Transform point back to the original coordinate system
916 Q = Q + n0;
917
918 return Q;
919}
920
927array3D reconstructPointFromBarycentricPolygon( std::vector<array3D> const &V, std::vector<double> const &lambda)
928{
929 return reconstructPointFromBarycentricPolygon( V.size(), V.data(), lambda);
930}
931
939array3D reconstructPointFromBarycentricPolygon( std::size_t nV, array3D const *V, std::vector<double> const &lambda)
940{
941 return reconstructPointFromBarycentricPolygon(nV, V, lambda.data());
942}
943
951array3D reconstructPointFromBarycentricPolygon( std::size_t nV, array3D const *V, double const *lambda)
952{
953 assert( validBarycentric(lambda, nV) );
954
955 array3D xP = {{0.,0.,0.}};
956 for(std::size_t i=0; i<nV; ++i){
957 xP += lambda[i]*V[i];
958 }
959
960 return xP;
961}
962
970array3D projectPointLine( array3D const &P, array3D const &Q, array3D const &n )
971{
972 assert( validLine(Q,n) );
973 return Q + dotProduct(P - Q, n) * n;
974}
975
983array3D projectPointPlane( array3D const &P, array3D const &Q, array3D const &n )
984{
985 assert( validPlane(Q,n) );
986 return P - dotProduct(P - Q, n) * n;
987}
988
996array3D projectPointSegment( array3D const &P, array3D const &Q0, array3D const &Q1)
997{
998
999 std::array<double,2> lambda;
1000 return projectPointSegment( P, Q0, Q1, &lambda[0] );
1001}
1002
1011array3D projectPointSegment( array3D const &P, array3D const &Q0, array3D const &Q1, std::array<double,2> &lambda )
1012{
1013 return projectPointSegment( P, Q0, Q1, &lambda[0]);
1014}
1015
1024array3D projectPointSegment( array3D const &P, array3D const &Q0, array3D const &Q1, double *lambda )
1025{
1026
1027 assert( validSegment(Q0,Q1) );
1028
1029 array3D n = Q1 -Q0;
1030 double t = -dotProduct(n,Q0-P) / dotProduct(n,n);
1031
1032 // Restrict projection onto the segment
1033 t = std::max( std::min( t, 1.), 0. );
1034
1035 lambda[0] = 1. - t;
1036 lambda[1] = t;
1037
1038 return reconstructPointFromBarycentricSegment( Q0, Q1, lambda);
1039}
1040
1049array3D projectPointTriangle( array3D const &P, array3D const &Q0, array3D const &Q1, array3D const &Q2)
1050{
1051 array3D xP;
1052 array3D lambda;
1053 _projectPointsTriangle( 1, &P, Q0, Q1, Q2, &xP, lambda.data() );
1054 return xP;
1055}
1056
1066array3D projectPointTriangle( array3D const &P, array3D const &Q0, array3D const &Q1, array3D const &Q2, array3D &lambda)
1067{
1068 return projectPointTriangle( P, Q0, Q1, Q2, lambda.data() );
1069}
1070
1080array3D projectPointTriangle( array3D const &P, array3D const &Q0, array3D const &Q1, array3D const &Q2, double *lambda)
1081{
1082 array3D xP;
1083 _projectPointsTriangle( 1, &P, Q0, Q1, Q2, &xP, lambda );
1084
1085 return xP;
1086}
1087
1096array3D restrictPointTriangle( array3D const &Q0, array3D const &Q1, array3D const &Q2, array3D &lambda)
1097{
1098 return restrictPointTriangle( Q0, Q1, Q2, &lambda[0] );
1099}
1100
1109array3D restrictPointTriangle( array3D const &Q0, array3D const &Q1, array3D const &Q2, double *lambda)
1110{
1111
1112 assert( validBarycentric(&lambda[0], 3) );
1113
1114 int count = 0;
1115 std::array<int,2> negatives = {{ 0, 0 }};
1116
1117 for( int i=0; i<3; ++i){
1118 if( lambda[i] < 0){
1119 negatives[count] = i;
1120 ++count;
1121 }
1122 }
1123
1124 if( count == 0){
1125 return reconstructPointFromBarycentricTriangle( Q0, Q1, Q2, lambda );
1126 }
1127
1128 std::array<const array3D*,3> r = {{&Q0, &Q1, &Q2}};
1129 if( count == 1){
1130 std::array<double,2> lambdaLocal;
1131 int vertex0 = (negatives[0] +1) %3;
1132 int vertex1 = (vertex0 +1) %3;
1133 array3D P = reconstructPointFromBarycentricTriangle( Q0, Q1, Q2, lambda );
1134 array3D xP = projectPointSegment(P, *r[vertex0], *r[vertex1], lambdaLocal);
1135 lambda[negatives[0]] = 0.;
1136 lambda[vertex0] = lambdaLocal[0];
1137 lambda[vertex1] = lambdaLocal[1];
1138 return xP;
1139
1140 } else {
1141 int vertex0 = 3 -negatives[0] -negatives[1];
1142 int vertex1 = (vertex0 +1) %3;
1143 int vertex2 = (vertex1 +1) %3;
1144
1145 array3D s01 = *r[vertex1] - *r[vertex0];
1146 array3D s02 = *r[vertex2] - *r[vertex0];
1147
1148 if(dotProduct(s01,s02) >= 0 ){
1149 lambda[0] = 0.;
1150 lambda[1] = 0.;
1151 lambda[2] = 0.;
1152 lambda[vertex0] = 1.;
1153 return *r[vertex0];
1154
1155 } else {
1156 std::array<double,2> lambdaLocal01, lambdaLocal02;
1157 array3D P = reconstructPointFromBarycentricTriangle( Q0, Q1, Q2, lambda );
1158
1159 array3D xP01 = projectPointSegment(P, *r[vertex0], *r[vertex1], lambdaLocal01);
1160 array3D xP02 = projectPointSegment(P, *r[vertex0], *r[vertex2], lambdaLocal02);
1161
1162 if( norm2(P-xP01) <= norm2(P-xP02) ){
1163 lambda[vertex0] = lambdaLocal01[0];
1164 lambda[vertex1] = lambdaLocal01[1];
1165 lambda[vertex2] = 0.;
1166 return xP01;
1167
1168 } else {
1169 lambda[vertex0] = lambdaLocal02[0];
1170 lambda[vertex1] = 0;
1171 lambda[vertex2] = lambdaLocal02[1];
1172 return xP02;
1173 }
1174
1175 }
1176
1177 }
1178
1179 BITPIT_UNREACHABLE("CANNOT REACH");
1180
1181}
1182
1193std::vector<array3D> projectCloudTriangle( std::vector<array3D> const &cloud, array3D const &Q0, array3D const &Q1, array3D const &Q2, std::vector<array3D> &lambda )
1194{
1195
1196 int cloudCount(cloud.size());
1197
1198 std::vector<array3D> xP(cloudCount);
1199
1200 lambda.resize(cloudCount);
1201
1202 _projectPointsTriangle( cloudCount, cloud.data(), Q0, Q1, Q2, xP.data(), &lambda[0][0]);
1203
1204 return xP;
1205
1206}
1207
1214array3D projectPointPolygon( array3D const &P, std::vector<array3D> const &V)
1215{
1216 return projectPointPolygon( P, V.size(), V.data());
1217}
1218
1226array3D projectPointPolygon( array3D const &P, std::size_t nV, array3D const *V)
1227{
1228 std::vector<double> lambda(nV);
1229 return projectPointPolygon( P, nV, V, lambda);
1230}
1231
1239array3D projectPointPolygon( array3D const &P, std::vector<array3D> const &V, std::vector<double> &lambda)
1240{
1241 return projectPointPolygon( P, V.size(), V.data(), lambda);
1242}
1243
1252array3D projectPointPolygon( array3D const &P, std::size_t nV, array3D const *V, std::vector<double> &lambda)
1253{
1254 lambda.resize(nV);
1255
1256 return projectPointPolygon(P, nV, V, lambda.data());
1257}
1258
1267array3D projectPointPolygon( array3D const &P, std::size_t nV, array3D const *V, double *lambda)
1268{
1269 array3D xP;
1270
1271 double distance, minDistance(std::numeric_limits<double>::max());
1272 int minTriangle = -1;
1273 array3D V0, V1, V2;
1274 array3D localLambda, minLambda;
1275
1276 // Compute the distance from each triangle in the simplex
1277 int triangleCount = polygonSubtriangleCount(nV, V);
1278
1279 for (int triangle=0; triangle < triangleCount; ++triangle) {
1280
1281 subtriangleOfPolygon( triangle, nV, V, V0, V1, V2);
1282
1283 distance = distancePointTriangle(P, V0, V1, V2, localLambda);
1284
1285 if (distance <= minDistance) {
1286
1287 minDistance = distance;
1288
1289 minLambda = localLambda;
1290 minTriangle = triangle;
1291 }
1292
1293 } //next triangle
1294
1295 assert(minTriangle >= 0);
1296 subtriangleOfPolygon( minTriangle, nV, V, V0, V1, V2);
1297 xP = reconstructPointFromBarycentricTriangle( V0, V1, V2, minLambda);
1298
1299 computeGeneralizedBarycentric( xP, nV, V, lambda);
1300
1301 return xP;
1302
1303}
1304
1313array3D projectPointCone( array3D const &point, array3D const &apex, array3D const &axis, double alpha)
1314{
1315
1316
1317 if( alpha <= BITPIT_PI_2 ) { //accute cone angle
1318
1319 array3D versor = point-apex;
1320 versor /= norm2(versor);
1321
1322 double cosPointAxis = dotProduct(versor,axis);
1323 double cosCriticalAngle = cos(alpha+BITPIT_PI_2);
1324
1325 if( cosPointAxis <= cosCriticalAngle ){ //point projects on cone apex
1326 return apex;
1327
1328 } else { // point projects on cone surface
1329
1330 array3D planeNormal = crossProduct(axis,versor);
1331 planeNormal /= norm2(planeNormal);
1332
1333 array3D direction = rotateVector(axis,planeNormal,alpha);
1334
1335 return projectPointLine(point,apex,direction);
1336
1337 }
1338
1339 } else { // abtuse cone angle -> project on complement
1340 return projectPointCone( point, apex, -1.*axis, BITPIT_PI-alpha);
1341
1342 }
1343
1344}
1345
1354double distancePointLine( array3D const &P, array3D const &Q, array3D const &n, array3D &xP)
1355{
1356 xP = projectPointLine(P,Q,n);
1357 return norm2( P-xP);
1358}
1359
1368double distancePointPlane( array3D const &P, array3D const &Q, array3D const &n, array3D &xP)
1369{
1370 xP = projectPointPlane(P,Q,n);
1371 return norm2(P-xP);
1372}
1373
1381double distancePointSegment( array3D const &P, array3D const &Q0, array3D const &Q1)
1382{
1383 array3D xP = projectPointSegment( P, Q0, Q1);
1384 return norm2(P-xP);
1385}
1386
1395double distancePointSegment( array3D const &P, array3D const &Q0, array3D const &Q1, std::array<double,2> &lambda)
1396{
1397 array3D xP = projectPointSegment( P, Q0, Q1, lambda);
1398 return norm2(P-xP);
1399}
1400
1409double distancePointTriangle( array3D const &P, array3D const &Q0, array3D const &Q1, array3D const &Q2)
1410{
1411 array3D xP = projectPointTriangle(P, Q0, Q1, Q2);
1412 return norm2(P-xP);
1413}
1414
1424double distancePointTriangle( array3D const &P, array3D const &Q0, array3D const &Q1, array3D const &Q2, array3D &lambda)
1425{
1426 array3D xP = projectPointTriangle(P, Q0, Q1, Q2, lambda);
1427 return norm2(P-xP);
1428}
1429
1438double distancePointCone( array3D const &point, array3D const &apex, array3D const &axis, double alpha)
1439{
1440 array3D xP = projectPointCone( point, apex, axis, alpha);
1441 return norm2(point-xP);
1442}
1443
1452std::vector<double> distanceCloudTriangle( std::vector<array3D> const &cloud, array3D const &Q0, array3D const &Q1, array3D const &Q2)
1453{
1454 std::vector<array3D> lambda(cloud.size());
1455 return distanceCloudTriangle( cloud, Q0, Q1, Q2, lambda);
1456}
1457
1467std::vector<double> distanceCloudTriangle( std::vector<array3D> const &cloud, array3D const &Q0, array3D const &Q1, array3D const &Q2, std::vector<array3D> &lambda )
1468{
1469 int N(cloud.size());
1470
1471 lambda.resize(N);
1472
1473 std::vector<array3D> xP(N);
1474 _projectPointsTriangle( N, cloud.data(), Q0, Q1, Q2, xP.data(), &lambda[0][0]);
1475
1476 std::vector<double> d(N);
1477 std::vector<double>::iterator distance = d.begin();
1478
1479 std::vector<array3D>::iterator projection = xP.begin();
1480 for( const auto &point : cloud){
1481 *distance = norm2( point - *projection);
1482
1483 ++projection;
1484 ++distance;
1485 }
1486
1487 return d;
1488}
1489
1498double distancePointPolygon( array3D const &P, std::vector<array3D> const &V, array3D &xP, int &flag)
1499{
1500 return distancePointPolygon( P, V.size(), V.data(), xP, flag);
1501}
1502
1512double distancePointPolygon( array3D const &P, std::size_t nV, array3D const *V, array3D &xP, int &flag)
1513{
1514 const int MAX_ELEM_VERTICES = 8;
1515 BITPIT_CREATE_WORKSPACE(lambda, double, nV, MAX_ELEM_VERTICES);
1516
1517 double distance = distancePointPolygon( P, nV, V, lambda);
1518 xP = reconstructPointFromBarycentricPolygon( nV, V, lambda );
1519 flag = convertBarycentricToFlagPolygon( nV, lambda );
1520
1521 return distance;
1522}
1523
1530double distancePointPolygon( array3D const &P, std::vector<array3D> const &V)
1531{
1532 return distancePointPolygon( P, V.size(), V.data());
1533}
1534
1542double distancePointPolygon( array3D const &P, std::size_t nV, array3D const *V)
1543{
1544 std::vector<double> lambda(nV);
1545 return distancePointPolygon( P, nV, V, lambda);
1546}
1547
1555double distancePointPolygon( array3D const &P, std::vector<array3D> const &V,std::vector<double> &lambda)
1556{
1557 return distancePointPolygon(P, V.size(), V.data(), lambda);
1558}
1559
1568double distancePointPolygon( array3D const &P, std::size_t nV, array3D const *V,std::vector<double> &lambda)
1569{
1570 lambda.resize(nV);
1571
1572 return distancePointPolygon(P, nV, V, lambda.data());
1573}
1574
1583double distancePointPolygon( array3D const &P, std::size_t nV, array3D const *V, double *lambda)
1584{
1585 array3D xP = projectPointPolygon( P, nV, V, lambda);
1586 return norm2(P-xP);
1587}
1588
1597std::vector<double> distanceCloudPolygon( std::vector<array3D> const &cloud, std::vector<array3D> const &V, std::vector<array3D> &xP, std::vector<int> &flag)
1598{
1599 return distanceCloudPolygon( cloud, V.size(), V.data(), xP, flag);
1600}
1601
1611std::vector<double> distanceCloudPolygon( std::vector<array3D> const &cloud, std::size_t nV, array3D const *V, std::vector<array3D> &xP, std::vector<int> &flag)
1612{
1613 int cloudCount( cloud.size() );
1614
1615 std::vector<std::vector<double>> lambda( cloudCount, std::vector<double> (nV));
1616 std::vector<double> d = distanceCloudPolygon( cloud, nV, V, lambda);
1617
1618 xP.resize(cloudCount);
1619 std::vector<array3D>::iterator xPItr = xP.begin();
1620
1621 flag.resize(cloudCount);
1622 std::vector<int>::iterator flagItr = flag.begin();
1623
1624 for( const auto &l : lambda){
1625 *flagItr = convertBarycentricToFlagPolygon( l );
1626 *xPItr = reconstructPointFromBarycentricPolygon( nV, V, l );
1627
1628 ++xPItr;
1629 ++flagItr;
1630 }
1631
1632 return d;
1633}
1634
1641std::vector<double> distanceCloudPolygon( std::vector<array3D> const &P, std::vector<array3D> const &V)
1642{
1643 return distanceCloudPolygon( P, V.size(), V.data());
1644}
1645
1653std::vector<double> distanceCloudPolygon( std::vector<array3D> const &P, std::size_t nV, array3D const *V)
1654{
1655 int cloudCount(P.size());
1656
1657 std::vector<double> d(cloudCount,std::numeric_limits<double>::max());
1658
1659 int triangleCount = polygonSubtriangleCount(nV, V);
1660 array3D V0, V1, V2;
1661
1662 for (int triangle=0; triangle < triangleCount; ++triangle) { // foreach triangle
1663 subtriangleOfPolygon( triangle, nV, V, V0, V1, V2);
1664 std::vector<double> dT = distanceCloudTriangle(P, V0, V1, V2);
1665
1666 d = min(d,dT);
1667 }
1668
1669 return d;
1670}
1671
1679std::vector<double> distanceCloudPolygon( std::vector<array3D> const &cloud, std::vector<array3D> const &V, std::vector<std::vector<double>> &lambda)
1680{
1681 return distanceCloudPolygon( cloud, V.size(), V.data(), lambda);
1682}
1683
1692std::vector<double> distanceCloudPolygon( std::vector<array3D> const &cloud, std::size_t nV, array3D const *V, std::vector<std::vector<double>> &lambda)
1693{
1694 int cloudCount(cloud.size()), vertexCount(nV);
1695
1696 std::vector<double> d(cloudCount,std::numeric_limits<double>::max());
1697 lambda.resize(cloudCount, std::vector<double>(vertexCount,0) );
1698
1699 std::vector<double> dTemp(cloudCount);
1700 std::vector<array3D> lambdaTemp(cloudCount);
1701 int triangleCount = polygonSubtriangleCount(nV, V);
1702 array3D V0, V1, V2;
1703
1704 for (int triangle=0; triangle < triangleCount; ++triangle) { // foreach triangle
1705 subtriangleOfPolygon( triangle, nV, V, V0, V1, V2);
1706 dTemp = distanceCloudTriangle(cloud, V0, V1, V2, lambdaTemp);
1707
1708 for(int i=0; i< cloudCount; ++i){
1709 if( dTemp[i] < d[i]){
1710 d[i] = dTemp[i];
1711 std::copy( lambdaTemp[i].begin(), lambdaTemp[i].end(), lambda[i].begin());
1712 }
1713 }
1714 }
1715
1716 return d;
1717}
1718
1727double distanceLineLine( array3D const &P0, array3D const &n0, array3D const &P1, array3D const &n1)
1728{
1729 array3D xP0, xP1;
1730 return distanceLineLine( P0, n0, P1, n1, xP0, xP1);
1731}
1732
1743double distanceLineLine( array3D const &P0, array3D const &n0, array3D const &P1, array3D const &n1, array3D &xP0, array3D &xP1)
1744{
1745 assert( validLine(P0,n0) );
1746 assert( validLine(P1,n1) );
1747
1748 double n01 = dotProduct(n0,n1);
1749 double det = 1. - n01*n01;
1750
1751 // check if lines are parallel
1752 if( std::abs(det) < 1.e-12){
1753 double distance = distancePointLine(P0, P1, n1, xP1);
1754 xP0 = projectPointLine(xP1, P0, n0);
1755 return distance;
1756 }
1757
1758
1759 array3D dP = P1-P0;
1760 double rhs0 = dotProduct(dP,n0);
1761 double rhs1 = -dotProduct(dP,n1);
1762
1763 double det0 = rhs0 +rhs1*n01;
1764 double det1 = rhs1 +rhs0*n01;
1765
1766 double s0 = det0/det;
1767 double s1 = det1/det;
1768
1769 xP0 = P0 +s0*n0;
1770 xP1 = P1 +s1*n1;
1771
1772 return norm2( xP0 - xP1);
1773}
1774
1785bool intersectLineLine( array3D const &P1, array3D const &n1, array3D const &P2, array3D const &n2, array3D &P, double distanceTolerance)
1786{
1787 array3D xP1, xP2;
1788 if( distanceLineLine(P1,n1,P2,n2,xP1,xP2) < distanceTolerance){
1789 P = xP1;
1790 return true;
1791 }
1792
1793 return false;
1794}
1795
1806bool intersectSegmentSegment( array3D const &P1, array3D const &P2, array3D const &Q1, array3D const &Q2, array3D &x, double distanceTolerance)
1807{
1808 assert( validSegment(P1,P2) );
1809 assert( validSegment(Q1,Q2) );
1810
1811 array3D nP = P2 - P1;
1812 nP /= norm2(nP);
1813
1814 array3D nQ = Q2 - Q1;
1815 nQ /= norm2(nQ);
1816
1817 array3D temp;
1818 if( intersectLineLine(P1, nP, Q1, nQ, temp, distanceTolerance) && intersectPointSegment( temp, P1, P2, distanceTolerance) && intersectPointSegment(temp, Q1, Q2, distanceTolerance) ){
1819 x = temp;
1820 return true;
1821 }
1822
1823 return false;
1824}
1825
1837bool intersectLinePlane( array3D const &P1, array3D const &n1, array3D const &P2, array3D const &n2, array3D &P, const double coplanarityTolerance)
1838{
1839
1840 assert( validLine(P1,n1) );
1841 assert( validPlane(P2,n2) );
1842
1843 // ========================================================================== //
1844 // CHECK DEGENERATE CASES //
1845 // ========================================================================== //
1846 double s = dotProduct(n1, n2);
1847 if (std::abs(s) < std::cos(0.5*BITPIT_PI-coplanarityTolerance)) {
1848 return false;
1849 }
1850
1851 // ========================================================================== //
1852 // FIND INTERSECTION POINTS //
1853 // ========================================================================== //
1854 double xi = -dotProduct(P1 - P2, n2) /s;
1855 P = P1 + xi *n1;
1856
1857 return true;
1858}
1859
1870bool intersectSegmentPlane( array3D const &Q1, array3D const &Q2, array3D const &P2, array3D const &n2, array3D &P, const double distanceTolerance)
1871{
1872
1873 assert( validSegment(Q1,Q2) );
1874 assert( validPlane(P2,n2) );
1875
1876 array3D n = Q2 - Q1;
1877 n /= norm2(n);
1878
1879 array3D xP;
1880 if ( intersectLinePlane(Q1, n, P2, n2, xP, distanceTolerance) && intersectPointSegment(xP, Q1, Q2, distanceTolerance) ) {
1881 P = xP;
1882 return true;
1883 }
1884
1885 return false;
1886}
1887
1900bool intersectPlanePlane( array3D const &P1, array3D const &n1, array3D const &P2, array3D const &n2,
1901 array3D &Pl, array3D &nl, const double coplanarityTolerance)
1902{
1903
1904 assert( validPlane(P1,n1) );
1905 assert( validPlane(P2,n2) );
1906
1907 double n12 = dotProduct(n1, n2);
1908 // check degenerate condition
1909 if( std::abs(n12) > std::cos(coplanarityTolerance)) {
1910 return false;
1911 }
1912
1913
1914 double detCB = 1.0-n12*n12;
1915
1916
1917 nl = crossProduct(n1,n2);
1918 nl /= norm2(nl);
1919
1920 // if planes intersect, determine the closest point
1921 // to P1 and P2 as anchor point. The augmented functional
1922 // I = 0.5*[ (Pl-P1)^2 + (Pl-P2)^2] + lambda1[ n1.(Pl-P1) ] +lambda2[ n2.(Pl-P2) ]
1923 // where lambda1 and lambda2 are Lagrange multipliers.
1924 // The optimality conditions I,Pl I,lambda1 I,lambda2 are
1925 // solved using the Schur complment
1926
1927 array3D dP = P2-P1;
1928 std::array<double,2> rhs = {{ dotProduct(n1,dP) , -dotProduct(n2,dP) }};
1929
1930 double det1 = rhs[0] - n12*rhs[1];
1931 double det2 = rhs[1] - n12*rhs[0];
1932 double lambda1 = det1 /detCB;
1933 double lambda2 = det2 /detCB;
1934
1935 Pl = P1 +P2 -lambda1*n1 -lambda2*n2;
1936 Pl *= 0.5;
1937
1938 return true;
1939
1940}
1941
1952bool intersectPlaneBox( array3D const &P1, array3D const &n1, array3D const &A0, array3D const &A1, int dim, const double distanceTolerance)
1953{
1954 assert( validPlane(P1,n1) );
1955 return _intersectPlaneBox( P1, n1, A0, A1, nullptr, dim, distanceTolerance);
1956}
1957
1969bool intersectPlaneBox( array3D const &P1, array3D const &n1, array3D const &A0, array3D const &A1, std::vector<array3D> &intersects, int dim, const double distanceTolerance)
1970{
1971 assert( validPlane(P1,n1) );
1972 return _intersectPlaneBox( P1, n1, A0, A1, &intersects, dim, distanceTolerance);
1973}
1974
1986bool intersectLineTriangle( array3D const &P, array3D const &n, array3D const &A, array3D const &B, array3D const &C, array3D &Q, const double distanceTolerance)
1987{
1988 assert( validLine(P,n) );
1989 assert( validTriangle(A,B,C) );
1990
1991 array3D nT = crossProduct(B - A, C - A);
1992 nT /= norm2(nT);
1993
1994 array3D xP;
1995 if ( intersectLinePlane(P, n, A, nT, xP, distanceTolerance) && intersectPointTriangle(xP, A, B, C, distanceTolerance) ) {
1996 Q = xP;
1997 return true;
1998 }
1999
2000 return false;
2001}
2002
2014bool intersectSegmentTriangle( array3D const &P0, array3D const &P1, array3D const &A, array3D const &B, array3D const &C, array3D &Q, const double distanceTolerance)
2015{
2016 assert( validSegment(P0,P1) );
2017 assert( validTriangle(A,B,C) );
2018
2019 array3D n = P1 - P0;
2020 n /= norm2(n);
2021
2022 array3D xP;
2023 if ( intersectLineTriangle(P0, n, A, B, C, xP, distanceTolerance) && intersectPointSegment(xP, P0, P1, distanceTolerance) ) {
2024 Q = xP;
2025 return true;
2026 }
2027
2028 return false;
2029}
2030
2040bool intersectLinePolygon( array3D const &P, array3D const &n, std::vector<array3D > const &V, array3D &Q, const double distanceTolerance)
2041{
2042 return intersectLinePolygon( P, n, V.size(), V.data(), Q, distanceTolerance);
2043}
2044
2055bool intersectLinePolygon( array3D const &P, array3D const &n, std::size_t nV, array3D const *V, array3D &Q, const double distanceTolerance)
2056{
2057 assert( validLine(P,n) );
2058
2059 int nTriangles = polygonSubtriangleCount(nV, V);
2060 array3D V0, V1, V2;
2061
2062 for( int i=0; i< nTriangles; ++i){
2063 subtriangleOfPolygon(i, nV, V, V0, V1, V2);
2064
2065 if( intersectLineTriangle(P, n, V0, V1, V2, Q, distanceTolerance) ) {
2066 return true;
2067 }
2068 }
2069
2070 return false;
2071}
2072
2082bool intersectSegmentPolygon( array3D const &P0, array3D const &P1, std::vector<array3D > const &V, array3D &Q, const double distanceTolerance)
2083{
2084 return intersectSegmentPolygon( P0, P1, V.size(), V.data(), Q, distanceTolerance);
2085}
2086
2097bool intersectSegmentPolygon( array3D const &P0, array3D const &P1, std::size_t nV, array3D const *V, array3D &Q, const double distanceTolerance)
2098{
2099 assert( validSegment(P0,P1) );
2100
2101 int nTriangles = polygonSubtriangleCount(nV, V);
2102 array3D V0, V1, V2;
2103
2104 for( int i=0; i< nTriangles; ++i){
2105 subtriangleOfPolygon(i, nV, V, V0, V1, V2);
2106
2107 if( intersectSegmentTriangle(P0, P1, V0, V1, V2, Q, distanceTolerance) ) {
2108 return true;
2109 }
2110 }
2111
2112 return false;
2113}
2114
2125bool intersectBoxBox(array3D const &A1, array3D const &A2, array3D const &B1, array3D const &B2, int dim, const double distanceTolerance)
2126{
2127 for( int d=0; d<dim; ++d){
2128 if( B1[d] > A2[d] + distanceTolerance || B2[d] < A1[d] - distanceTolerance ){
2129 return false;
2130 }
2131 }
2132
2133 return true;
2134}
2135
2148bool intersectBoxBox(array3D const &A1, array3D const &A2, array3D const &B1, array3D const &B2, array3D &I1, array3D &I2, int dim, const double distanceTolerance )
2149{
2150 for( int d=0; d<dim; ++d){
2151
2152 if( B1[d] > A2[d] + distanceTolerance || B2[d] < A1[d] - distanceTolerance ){
2153 return false;
2154 }
2155
2156 else{
2157 I1[d] = std::max( A1[d], B1[d] );
2158 I2[d] = std::min( A2[d], B2[d] );
2159 }
2160
2161 }
2162
2163 return true;
2164}
2165
2177bool intersectBoxTriangle(array3D const &A0, array3D const &A1, array3D const &V0, array3D const &V1, array3D const &V2, int dim, const double distanceTolerance)
2178{
2179 return _intersectBoxTriangle( A0, A1, V0, V1, V2, false, false, false, nullptr, nullptr, dim, distanceTolerance);
2180}
2181
2197bool intersectBoxTriangle(array3D const &A0, array3D const &A1, array3D const &V0, array3D const &V1, array3D const &V2, bool interiorTriangleVertices, bool triangleEdgeBoxFaceIntersections, bool triangleBoxEdgeIntersections, std::vector<array3D> &P, int dim, const double distanceTolerance)
2198{
2199 return _intersectBoxTriangle( A0, A1, V0, V1, V2, interiorTriangleVertices, triangleEdgeBoxFaceIntersections, triangleBoxEdgeIntersections, &P, nullptr, dim, distanceTolerance);
2200}
2201
2218bool intersectBoxTriangle(array3D const &A0, array3D const &A1, array3D const &V0, array3D const &V1, array3D const &V2, bool interiorTriangleVertices, bool triangleEdgeBoxHullIntersections, bool triangleBoxEdgeIntersections, std::vector<array3D> &P, std::vector<int> &flag, int dim, const double distanceTolerance)
2219{
2220 return _intersectBoxTriangle( A0, A1, V0, V1, V2, interiorTriangleVertices, triangleEdgeBoxHullIntersections, triangleBoxEdgeIntersections, &P, &flag, dim, distanceTolerance);
2221}
2222
2233bool intersectSegmentBox( array3D const &V0, array3D const &V1, array3D const &A0, array3D const &A1, int dim, const double distanceTolerance)
2234{
2235 return _intersectSegmentBox( V0, V1, A0, A1, false, false, nullptr, nullptr, dim, distanceTolerance);
2236}
2237
2251bool intersectSegmentBox( array3D const &V0, array3D const &V1, array3D const &A0, array3D const &A1, bool interiorSegmentVertice, bool segmentBoxHullIntersection, std::vector<array3D> &P, int dim, const double distanceTolerance)
2252{
2253 return _intersectSegmentBox( V0, V1, A0, A1, interiorSegmentVertice, segmentBoxHullIntersection, &P, nullptr, dim, distanceTolerance);
2254}
2255
2270bool intersectSegmentBox( array3D const &V0, array3D const &V1, array3D const &A0, array3D const &A1, bool interiorSegmentVertice, bool segmentBoxHullIntersection, std::vector<array3D> &P, std::vector<int> &flag, int dim, const double distanceTolerance)
2271{
2272 return _intersectSegmentBox( V0, V1, A0, A1, interiorSegmentVertice, segmentBoxHullIntersection, &P, &flag, dim, distanceTolerance);
2273}
2274
2284bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::vector<array3D> const &VS, int dim, const double distanceTolerance )
2285{
2286 return intersectBoxPolygon( A0, A1, VS.size(), VS.data(), dim, distanceTolerance );
2287}
2298bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::size_t nVS, array3D const *VS, int dim, const double distanceTolerance )
2299{
2300 return _intersectBoxPolygon(A0, A1, nVS, VS, false, false, false, nullptr, nullptr, dim, distanceTolerance);
2301}
2302
2316bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::vector<array3D> const &VS, bool innerPolygonPoints, bool polygonEdgeBoxFaceIntersections, bool polygonBoxEdgeIntersections, std::vector<array3D> &P, int dim, const double distanceTolerance)
2317{
2318 return intersectBoxPolygon( A0, A1, VS.size(), VS.data(), innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, P, dim, distanceTolerance);
2319}
2320
2321
2336bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::size_t nVS, array3D const *VS, bool innerPolygonPoints, bool polygonEdgeBoxFaceIntersections, bool polygonBoxEdgeIntersections, std::vector<array3D> &P, int dim, const double distanceTolerance)
2337{
2338 return _intersectBoxPolygon(A0, A1, nVS, VS, innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, &P, nullptr, dim, distanceTolerance);
2339}
2340
2355bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::vector<array3D> const &VS, bool innerPolygonPoints, bool polygonEdgeBoxFaceIntersections, bool polygonBoxEdgeIntersections, std::vector<array3D> &P, std::vector<int> &flag, int dim, const double distanceTolerance)
2356{
2357 return intersectBoxPolygon( A0, A1, VS.size(), VS.data(), innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, P, flag, dim, distanceTolerance);
2358}
2359
2375bool intersectBoxPolygon( array3D const &A0, array3D const &A1, std::size_t nVS, array3D const *VS, bool innerPolygonPoints, bool polygonEdgeBoxFaceIntersections, bool polygonBoxEdgeIntersections, std::vector<array3D> &P, std::vector<int> &flag, int dim, const double distanceTolerance)
2376{
2377 return _intersectBoxPolygon(A0, A1, nVS, VS, innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, &P, &flag, dim, distanceTolerance);
2378}
2379
2390bool intersectBoxCircle( array3D const &A0, array3D const &A1, array3D const &centre, double radius, const double distanceTolerance)
2391{
2392 double minimumDistance = 0.;
2393 for (int i = 0; i < 2; ++i) {
2394 if (centre[i] < A0[i]) {
2395 minimumDistance += (centre[i] - A0[i]) * (centre[i] - A0[i]);
2396 } else if (centre[i] > A1[i]) {
2397 minimumDistance += (centre[i] - A1[i]) * (centre[i] - A1[i]);
2398 }
2399 }
2400
2401 double inflatedRadius = radius + distanceTolerance;
2402
2403 return (minimumDistance <= (inflatedRadius * inflatedRadius));
2404}
2405
2416bool intersectBoxSphere( array3D const &A0, array3D const &A1, array3D const &centre, double radius, const double distanceTolerance)
2417{
2418 double minimumDistance = 0.;
2419 for (int i = 0; i < 3; ++i) {
2420 if (centre[i] < A0[i]) {
2421 minimumDistance += (centre[i] - A0[i]) * (centre[i] - A0[i]);
2422 } else if (centre[i] > A1[i]) {
2423 minimumDistance += (centre[i] - A1[i]) * (centre[i] - A1[i]);
2424 }
2425 }
2426
2427 double inflatedRadius = radius + distanceTolerance;
2428
2429 return (minimumDistance <= (inflatedRadius * inflatedRadius));
2430}
2431
2432//to levelset // -------------------------------------------------------------------------- //
2433//to levelset bool intersectLineSurface(
2434//to levelset array3D const &x1,
2435//to levelset array3D const &n1,
2436//to levelset array3D const &x2,
2437//to levelset array3D const &n2,
2438//to levelset array3D const &xL,
2439//to levelset array3D const &nL,
2440//to levelset array3D &xp,
2441//to levelset array3D &np
2442//to levelset ) {
2443//to levelset
2444//to levelset // ========================================================================== //
2445//to levelset // //
2446//to levelset // Reconstruct Surface given by two points and their normals and computes //
2447//to levelset // intersection of reconstruction with a line given by point and versor ' //
2448//to levelset // ========================================================================== //
2449//to levelset // INPUT //
2450//to levelset // ========================================================================== //
2451//to levelset // ========================================================================== //
2452//to levelset // OUTPUT //
2453//to levelset // ========================================================================== //
2454//to levelset // - none //
2455//to levelset // ========================================================================== //
2456//to levelset
2457//to levelset // ========================================================================== //
2458//to levelset // VARIABLES DECLARATION //
2459//to levelset // ========================================================================== //
2460//to levelset
2461//to levelset double w1(0), w2(0), w(0);
2462//to levelset array3D c1, c2;
2463//to levelset bool s1, s2;
2464//to levelset
2465//to levelset s1 = intersectLinePlane( xL, nL, x1, n1, c1);
2466//to levelset s2 = intersectLinePlane( xL, nL, x2, n2, c2);
2467//to levelset
2468//to levelset if( s1 && s2) {
2469//to levelset w1 = norm2( c2-x2);
2470//to levelset w2 = norm2( c1-x1);
2471//to levelset w = w1+w2;
2472//to levelset
2473//to levelset w1 = w1 /w;
2474//to levelset w2 = w2 /w;
2475//to levelset
2476//to levelset xp = w1*c1 +w2*c2;
2477//to levelset np = w1*n1 +w2*n2;
2478//to levelset
2479//to levelset np = np /norm2(np);
2480//to levelset
2481//to levelset return (true);
2482//to levelset }
2483//to levelset
2484//to levelset else if( s1 ){
2485//to levelset xp = c1;
2486//to levelset np = n1;
2487//to levelset
2488//to levelset return(true);
2489//to levelset }
2490//to levelset
2491//to levelset else if( s2 ){
2492//to levelset xp = c2;
2493//to levelset np = n2;
2494//to levelset
2495//to levelset return(true);
2496//to levelset }
2497//to levelset
2498//to levelset return (false);
2499//to levelset
2500//to levelset }
2501
2510bool intersectPointLine( array3D const &P, array3D const &Q, array3D const &n, const double distanceTolerance)
2511{
2512 assert( validLine(Q,n) );
2513
2514 array3D xP;
2515 if(distancePointLine(P, Q, n, xP) > distanceTolerance){
2516 return false;
2517 }
2518
2519 return true;
2520}
2521
2530bool intersectPointSegment( array3D const &P, array3D const &P1, array3D const &P2, const double distanceTolerance)
2531{
2532 assert( validSegment(P1,P2) );
2533
2534 array3D xP = projectPointSegment( P, P1, P2 );
2535 array3D offset = xP - P;
2536
2537 return (dotProduct(offset, offset) <= distanceTolerance * distanceTolerance);
2538}
2539
2549bool intersectPointTriangle( array3D const &P, array3D const &A, array3D const &B, array3D const &C, const double distanceTolerance)
2550{
2551
2552 if(distancePointTriangle(P, A, B, C) > distanceTolerance){
2553 return false;
2554 }
2555
2556 return true;
2557}
2558
2568bool intersectPointBox( array3D const &P, array3D const &B1, array3D const &B2, int dim, const double distanceTolerance)
2569{
2570
2571 for( int d=0; d<dim; ++d){
2572 if( P[d]< (B1[d] - distanceTolerance) || P[d] > (B2[d] + distanceTolerance)){
2573 return false;
2574 }
2575 }
2576
2577 return true;
2578}
2579
2587void computeAABBSegment(array3D const &A, array3D const &B, array3D &P0, array3D &P1)
2588{
2589
2590 P0 = A;
2591 P1 = A;
2592
2593 for(int i=0; i<3; ++i){
2594 P0[i] = std::min( P0[i], B[i] );
2595 P1[i] = std::max( P1[i], B[i] );
2596 }
2597
2598 return;
2599}
2600
2609void computeAABBTriangle(array3D const &A, array3D const &B, array3D const &C, array3D &P0, array3D &P1)
2610{
2611 P0 = A;
2612 P1 = A;
2613
2614 for(int i=0; i<3; ++i){
2615 P0[i] = std::min( P0[i], B[i] );
2616 P0[i] = std::min( P0[i], C[i] );
2617
2618 P1[i] = std::max( P1[i], B[i] );
2619 P1[i] = std::max( P1[i], C[i] );
2620 }
2621
2622 return;
2623}
2624
2631void computeAABBPolygon(std::vector<array3D> const &VS, array3D &P0, array3D &P1)
2632{
2633 computeAABBPolygon(VS.size(), VS.data(), P0, P1);
2634}
2635
2643void computeAABBPolygon(std::size_t nVS, array3D const *VS, array3D &P0, array3D &P1)
2644{
2645 P0 = VS[0];
2646 P1 = VS[0];
2647
2648 for( std::size_t j=1; j<nVS; ++j){
2649 for( int i=0; i<3; ++i){
2650 P0[i] = std::min( P0[i], VS[j][i] );
2651 P1[i] = std::max( P1[i], VS[j][i] );
2652 }
2653 }
2654
2655 return;
2656}
2657
2667void unionAABB( array3D const &A0, array3D const &A1, array3D const &B0, array3D const &B1, array3D &C0, array3D &C1)
2668{
2669 for( int i=0; i<3; ++i){
2670 C0[i] = std::min( A0[i], B0[i]);
2671 C1[i] = std::max( A1[i], B1[i]);
2672 }
2673
2674 return;
2675}
2676
2684void unionAABB(std::vector<array3D> const &A0, std::vector<array3D> const &A1, array3D &C0, array3D &C1)
2685{
2686
2687 int n( std::min(A0.size(), A1.size() ) );
2688
2689 if( n > 0 ){
2690 C0 = A0[0];
2691 C1 = A1[0];
2692
2693 for( int i=1; i<n; ++i){
2694 unionAABB( A0[i], A1[i], C0, C1, C0, C1);
2695 }
2696 }
2697
2698 return;
2699}
2700
2710void intersectionAABB(array3D const &A0, array3D const &A1, array3D const &B0, array3D const &B1, array3D &C0, array3D &C1)
2711{
2712 intersectBoxBox( A0, A1, B0, B1, C0, C1 );
2713 return;
2714}
2715
2725void subtractionAABB(array3D const &A0, array3D const &A1, array3D const &B0, array3D const &B1, array3D &C0, array3D &C1)
2726{
2727 // X direction
2728 if( B0[1]<=A0[1] && B0[2]<=A0[2] && B1[1]>=A1[1] && B1[2]>=A1[2] ){
2729 C0[0] = ( B0[0]<=A0[0] && B1[0]>=A0[0] ) ? B1[0] : A0[0];
2730 C1[0] = ( B0[0]<=A1[0] && B1[0]>=A1[0] ) ? B0[0] : A1[0];
2731 }
2732
2733 // Y direction
2734 if( B0[0]<=A0[0] && B0[2]<=A0[2] && B1[0]>=A1[0] && B1[2]>=A1[2] ){
2735 C0[1] = ( B0[1]<=A0[1] && B1[1]>=A0[1] ) ? B1[1] : A0[2];
2736 C1[1] = ( B0[1]<=A1[1] && B1[1]>=A1[1] ) ? B0[1] : A1[2];
2737 }
2738
2739 // Z direction
2740 if( B0[0]<=A0[0] && B0[1]<=A0[1] && B1[0]>=A1[0] && B1[1]>=A1[1] ){
2741 C0[2] = ( B0[2]<=A0[2] && B1[2]>=A0[2] ) ? B1[2] : A0[2];
2742 C1[2] = ( B0[2]<=A1[2] && B1[2]>=A1[2] ) ? B0[2] : A1[2];
2743 }
2744
2745 return;
2746}
2747
2755void vertexOfSegment(int i, array3D const &V0, array3D const &V1, array3D &P)
2756{
2757 switch(i){
2758
2759 case 0:
2760 P = V0;
2761 break;
2762
2763 case 1:
2764 P = V1;
2765 break;
2766
2767 default:
2768 assert(false);
2769 break;
2770 }
2771
2772 return;
2773}
2774
2783void vertexOfTriangle(int i, array3D const &V0, array3D const &V1, array3D const &V2, array3D &P)
2784{
2785 switch(i){
2786
2787 case 0:
2788 P = V0;
2789 break;
2790
2791 case 1:
2792 P = V1;
2793 break;
2794
2795 case 2:
2796 P = V2;
2797 break;
2798
2799 default:
2800 assert(false);
2801 break;
2802 }
2803
2804 return;
2805}
2806
2816void edgeOfTriangle(int i, array3D const &V0, array3D const &V1, array3D const &V2, array3D &P0, array3D &P1)
2817{
2818 switch(i){
2819
2820 case 0:
2821 P0 = V0;
2822 P1 = V1;
2823 break;
2824
2825 case 1:
2826 P0 = V1;
2827 P1 = V2;
2828 break;
2829
2830 case 2:
2831 P0 = V2;
2832 P1 = V0;
2833 break;
2834
2835 default:
2836 assert(false);
2837 break;
2838 }
2839
2840 return;
2841}
2842
2853void faceOfBox(int i, array3D const &A0, array3D const &A1, array3D &P0, array3D &P1, array3D &P2, array3D &P3)
2854{
2855
2856 assert(i<6);
2857
2858 int v0 = boxFaceVertexConnectivity[i][0];
2859 int v1 = boxFaceVertexConnectivity[i][1];
2860 int v2 = boxFaceVertexConnectivity[i][2];
2861 int v3 = boxFaceVertexConnectivity[i][3];
2862
2863 vertexOfBox(v0, A0, A1, P0 );
2864 vertexOfBox(v1, A0, A1, P1 );
2865 vertexOfBox(v2, A0, A1, P2 );
2866 vertexOfBox(v3, A0, A1, P3 );
2867
2868 return;
2869}
2870
2879void edgeOfBox(int i, array3D const &A0, array3D const &A1, array3D &P0, array3D &P1)
2880{
2881 assert(i<12);
2882
2883 int v0 = boxEdgeVertexConnectivity[i][0];
2884 int v1 = boxEdgeVertexConnectivity[i][1];
2885
2886 vertexOfBox(v0, A0, A1, P0 );
2887 vertexOfBox(v1, A0, A1, P1 );
2888
2889 return;
2890}
2891
2899void vertexOfBox(int i, array3D const &A0, array3D const &A1, array3D &P)
2900{
2901
2902 switch(i){
2903
2904 case 0:
2905 P[0] = A0[0];
2906 P[1] = A0[1];
2907 P[2] = A0[2];
2908 break;
2909
2910 case 1:
2911 P[0] = A1[0];
2912 P[1] = A0[1];
2913 P[2] = A0[2];
2914 break;
2915
2916 case 2:
2917 P[0] = A0[0];
2918 P[1] = A1[1];
2919 P[2] = A0[2];
2920 break;
2921
2922 case 3:
2923 P[0] = A1[0];
2924 P[1] = A1[1];
2925 P[2] = A0[2];
2926 break;
2927
2928 case 4:
2929 P[0] = A0[0];
2930 P[1] = A0[1];
2931 P[2] = A1[2];
2932 break;
2933
2934 case 5:
2935 P[0] = A1[0];
2936 P[1] = A0[1];
2937 P[2] = A1[2];
2938 break;
2939
2940 case 6:
2941 P[0] = A0[0];
2942 P[1] = A1[1];
2943 P[2] = A1[2];
2944 break;
2945
2946 case 7:
2947 P[0] = A1[0];
2948 P[1] = A1[1];
2949 P[2] = A1[2];
2950 break;
2951
2952 default:
2953 assert(false);
2954 break;
2955
2956 }
2957
2958 return;
2959}
2960
2968array3D rotateVector( array3D const &vector, array3D const &axis, double theta)
2969{
2970
2971 array3D rotated;
2972 double cosTheta = cos(theta);
2973
2974 rotated = cosTheta * vector;
2975 rotated += sin(theta) * crossProduct(axis,vector);
2976 rotated += (1.0 - cosTheta) * dotProduct(axis,vector) * axis;
2977
2978 return rotated;
2979}
2980
2987double areaTriangle( array3D const &a, array3D const &b, array3D const &c)
2988{
2989 return 0.5 *norm2(crossProduct(b-a,c-a));
2990}
2991
2996int polygonEdgesCount( std::vector<array3D> const &V)
2997{
2998 return polygonEdgesCount( V.size(), V.data());
2999}
3000
3007int polygonEdgesCount( std::size_t nV, array3D const *V)
3008{
3009 BITPIT_UNUSED(V);
3010
3011 return nV;
3012}
3013
3022int polygonSubtriangleCount( std::vector<array3D> const &V)
3023{
3024 return polygonSubtriangleCount( V.size(), V.data());
3025}
3026
3037int polygonSubtriangleCount( std::size_t nV, array3D const *V)
3038{
3039 BITPIT_UNUSED(V);
3040
3041 return nV;
3042}
3043
3051void edgeOfPolygon( int edge, std::vector<array3D> const &V, array3D &V0, array3D &V1)
3052{
3053 edgeOfPolygon( edge, V.size(), V.data(), V0, V1);
3054}
3055
3064void edgeOfPolygon( int edge, std::size_t nV, array3D const *V, array3D &V0, array3D &V1)
3065{
3066 assert(edge<polygonEdgesCount(nV, V));
3067
3068 V0 = V[edge];
3069 V1 = V[(edge+1) % nV];
3070 return;
3071}
3072
3087void subtriangleOfPolygon( int triangle, std::vector<array3D> const &V, array3D &V0, array3D &V1, array3D &V2)
3088{
3089 subtriangleOfPolygon( triangle, V.size(), V.data(), V0, V1, V2);
3090}
3091
3107void subtriangleOfPolygon( int triangle, std::size_t nV, array3D const *V, array3D &V0, array3D &V1, array3D &V2)
3108{
3109 assert(triangle<polygonSubtriangleCount(nV, V));
3110
3111 V0 = {0., 0., 0.};
3112 for (std::size_t i = 0; i < nV; i++) {
3113 for (int d = 0; d < 3; d++) {
3114 V0[d] += V[i][d];
3115 }
3116 }
3117 for (int d = 0; d < 3; d++) {
3118 V0[d] /= nV;
3119 }
3120 V1 = V[triangle%nV];
3121 V2 = V[(triangle+1)%nV];
3122 return;
3123}
3124
3129}
3130
3131}
void edgeOfPolygon(int, std::vector< array3D > const &, array3D &, array3D &)
Definition CG_elem.cpp:3051
std::vector< double > distanceCloudTriangle(std::vector< array3D > const &, array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1452
double distancePointLine(array3D const &, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:1354
double distancePointCone(array3D const &, array3D const &, array3D const &, double)
Definition CG_elem.cpp:1438
array3D projectPointLine(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:970
void edgeOfTriangle(int, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2816
const std::array< std::array< int, 2 >, 12 > boxEdgeVertexConnectivity
Definition CG.hpp:53
bool intersectPlaneBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:1952
void unionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2667
bool intersectPointTriangle(array3D const &, array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2549
bool intersectBoxBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2125
array3D projectPointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1049
array3D rotateVector(array3D const &, array3D const &, double)
Definition CG_elem.cpp:2968
array3D projectPointSegment(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:996
double distancePointPlane(array3D const &, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:1368
bool intersectBoxTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2177
int convertBarycentricToFlagSegment(std::array< double, 2 > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:618
void computeAABBTriangle(array3D const &, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2609
bool validBarycentric(double const *, int)
Definition CG_elem.cpp:585
void intersectionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2710
double distanceLineLine(array3D const &, array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1727
array3D reconstructPointFromBarycentricTriangle(array3D const &, array3D const &, array3D const &, std::array< double, 3 > const &)
Definition CG_elem.cpp:857
array3D reconstructPointFromBarycentricSegment(array3D const &, array3D const &, std::array< double, 2 > const &)
Definition CG_elem.cpp:828
const std::array< std::array< int, 4 >, 6 > boxFaceVertexConnectivity
Definition CG.hpp:73
std::vector< double > distanceCloudPolygon(std::vector< array3D > const &, std::vector< array3D > const &, std::vector< array3D > &, std::vector< int > &)
Definition CG_elem.cpp:1597
void vertexOfSegment(int, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:2755
void vertexOfTriangle(int, array3D const &, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:2783
int convertBarycentricToFlagPolygon(std::vector< double > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:686
bool intersectSegmentPlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:1870
bool intersectLineTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:1986
bool intersectSegmentSegment(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:1806
double distancePointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1409
bool intersectPointLine(array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2510
int polygonEdgesCount(std::vector< array3D > const &)
Definition CG_elem.cpp:2996
int polygonSubtriangleCount(std::vector< array3D > const &)
Definition CG_elem.cpp:3022
bool intersectBoxSphere(array3D const &A0, array3D const &A1, array3D const &centre, double radius, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2416
int convertBarycentricToFlagTriangle(std::array< double, 3 > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:658
double areaTriangle(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:2987
array3D projectPointPlane(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:983
void subtriangleOfPolygon(int, std::vector< array3D > const &, array3D &, array3D &, array3D &)
Definition CG_elem.cpp:3087
bool intersectSegmentBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2233
bool intersectPlanePlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &, const double coplanarityTolerance=DEFAULT_COPLANARITY_TOLERANCE)
Definition CG_elem.cpp:1900
void computeGeneralizedBarycentric(array3D const &, std::vector< array3D > const &, std::vector< double > &)
Definition CG_elem.cpp:750
double distancePointSegment(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:1381
bool intersectLinePlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double coplanarityTolerance=DEFAULT_COPLANARITY_TOLERANCE)
Definition CG_elem.cpp:1837
bool validPlane(array3D const &, array3D const &)
Definition CG_elem.cpp:540
array3D rotatePoint(const array3D &P, const array3D &n0, const array3D &n1, double angle)
Definition CG_elem.cpp:892
double distancePointPolygon(array3D const &, std::vector< array3D > const &, array3D &, int &)
Definition CG_elem.cpp:1498
bool validLine(array3D const &, array3D const &)
Definition CG_elem.cpp:528
void computeAABBPolygon(std::vector< array3D > const &, array3D &, array3D &)
Definition CG_elem.cpp:2631
bool validTriangle(array3D const &, array3D const &, array3D const &)
Definition CG_elem.cpp:553
array3D reconstructPointFromBarycentricPolygon(std::vector< array3D > const &, std::vector< double > const &)
Definition CG_elem.cpp:927
bool intersectSegmentTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2014
array3D restrictPointTriangle(array3D const &, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:1096
bool intersectBoxPolygon(array3D const &, array3D const &, std::vector< array3D > const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2284
void faceOfBox(int, array3D const &, array3D const &, array3D &, array3D &, array3D &, array3D &)
Definition CG_elem.cpp:2853
std::vector< array3D > projectCloudTriangle(std::vector< array3D > const &, array3D const &, array3D const &, array3D const &, std::vector< array3D > &)
Definition CG_elem.cpp:1193
array3D projectPointCone(array3D const &, array3D const &, array3D const &, double)
Definition CG_elem.cpp:1313
void vertexOfBox(int, array3D const &, array3D const &, array3D &)
Definition CG_elem.cpp:2899
void edgeOfBox(int, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2879
void subtractionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2725
array3D projectPointPolygon(array3D const &, std::vector< array3D > const &)
Definition CG_elem.cpp:1214
bool validSegment(array3D const &, array3D const &)
Definition CG_elem.cpp:517
void computeAABBSegment(array3D const &, array3D const &, array3D &, array3D &)
Definition CG_elem.cpp:2587
bool intersectPointBox(array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2568
bool intersectPointSegment(array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2530
bool intersectLineLine(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:1785
bool intersectBoxCircle(array3D const &A0, array3D const &A1, array3D const &centre, double radius, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2390
bool intersectLinePolygon(array3D const &, array3D const &, std::vector< array3D > const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2040
bool intersectSegmentPolygon(array3D const &, array3D const &, std::vector< array3D > const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
Definition CG_elem.cpp:2082
void sum(const std::array< T, d > &x, T1 &s)
std::array< T, 3 > crossProduct(const std::array< T, 3 > &x, const std::array< T, 3 > &y)
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
double norm2(const std::array< T, d > &x)
std::array< T, d > min(const std::array< T, d > &x, const std::array< T, d > &y)
#define BITPIT_UNREACHABLE(str)
Definition compiler.hpp:53
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
#define BITPIT_CREATE_WORKSPACE(workspace, item_type, size, stack_size)
--- layout: doxygen_footer ---