32# include "bitpit_operators.hpp"
35# include "CG_private.hpp"
64void _projectPointsTriangle(
int nPoints, array3D
const *points, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2, array3D *proj,
double *lambda )
74 for(
int i=0; i<nPoints; ++i){
75 array3D v2 = points[i] - Q0;
77 double *pointLambda = lambda + 3 * i;
80 pointLambda[0] = 1. - pointLambda[1] - pointLambda[2];
82 array3D *pointProjections = proj + i;
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)
107 bool intersect(
false);
108 bool addFlag( flagPtr!=
nullptr);
109 bool computeIntersection(interiorTriangleVertices||triangleBoxEdgeIntersections||triangleEdgeBoxHullIntersections);
111 assert( ! (computeIntersection && (intrPtr==
nullptr) ) );
113 if(computeIntersection){
130 for(
int i=0; i<3; ++i){
134 if(!interiorTriangleVertices)
break;
136 intrPtr->push_back(B0);
137 if(addFlag) flagPtr->push_back(0);
142 if( !intersect || triangleEdgeBoxHullIntersections) {
144 for(
int edge=0; edge<3; ++edge){
150 array3D faceVertex0, faceVertex1;
152 for(
int face=0; face<4; ++face){
153 edgeOfBox( face, A0, A1, faceVertex0, faceVertex1);
157 if(!triangleEdgeBoxHullIntersections)
break;
159 intrPtr->push_back(p);
160 if(addFlag) flagPtr->push_back(1);
167 std::array<array3D, 4> V;
169 for(
int face=0; face<6; ++face){
170 faceOfBox( face, A0, A1, V[0], V[1], V[2], V[3] );
174 if(!triangleEdgeBoxHullIntersections)
break;
176 intrPtr->push_back(p);
177 if(addFlag) flagPtr->push_back(1);
185 if( !intersect || triangleBoxEdgeIntersections ) {
190 for(
int i=0; i<4; ++i){
194 if(!triangleBoxEdgeIntersections)
break;
196 intrPtr->push_back(B0);
197 if(addFlag) flagPtr->push_back(2);
202 for(
int i=0; i<12; ++i){
206 if(!triangleBoxEdgeIntersections)
break;
208 intrPtr->push_back(p);
209 if(addFlag) flagPtr->push_back(2);
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)
236 bool intersect(
false);
238 bool addFlag(flagPtr!=
nullptr);
239 bool computeIntersection(interiorSegmentVertice||segmentBoxHullIntersection);
241 assert( ! (computeIntersection && (intrPtr==
nullptr) ) );
243 if(computeIntersection){
260 for(
int i=0; i<2; ++i){
265 if(!interiorSegmentVertice)
break;
267 intrPtr->push_back(B0);
268 if(addFlag) flagPtr->push_back(0);
273 if( !intersect || segmentBoxHullIntersection){
276 for(
int i=0; i<4; ++i){
281 if(!segmentBoxHullIntersection)
break;
283 intrPtr->push_back(p);
284 if(addFlag) flagPtr->push_back(1);
289 }
else if( dim==3 ) {
291 std::array<array3D, 4> E;
293 for(
int i=0; i<6; ++i){
294 faceOfBox( i, A0, A1, E[0], E[1], E[2], E[3]);
298 if(!segmentBoxHullIntersection)
break;
300 intrPtr->push_back(p);
301 if(addFlag) flagPtr->push_back(1);
324bool _intersectPlaneBox(array3D
const &P, array3D
const &N, array3D
const &A0, array3D
const &A1, std::vector<array3D> *intrPtr,
int dim,
const double distanceTolerance)
327 bool intersect(
false);
328 bool computeIntersection(intrPtr);
330 if(computeIntersection){
338 int edgeCount = (dim==2) ? 4 : 12;
341 for(
int i=0; i<edgeCount; ++i){
348 intrPtr->push_back(V);
357 if( dim==3 && intrPtr && intersect){
359 const array3D origin = intrPtr->at(0);
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;
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)
389 bool intersect(
false);
390 bool addFlag(flagPtr!=
nullptr);
391 bool computeIntersection(innerPolygonPoints || polygonEdgeBoxHullIntersection || polygonBoxEdgeIntersections);
393 assert( ! (computeIntersection && (intrPtr==
nullptr) ) );
395 if(computeIntersection){
411 std::vector<array3D> partialIntr;
412 std::vector<int> partialFlag;
416 computeIntersection = innerPolygonPoints || polygonBoxEdgeIntersections;
418 for (
int triangle=0; triangle<trianglesCount; ++triangle) {
421 if( _intersectBoxTriangle( A0, A1, V0, V1, V2, innerPolygonPoints,
false, polygonBoxEdgeIntersections, &partialIntr, &partialFlag, dim, distanceTolerance ) ){
424 if(!computeIntersection)
break;
426 int intrCount = partialIntr.size();
427 for(
int i=0; i<intrCount; ++i){
432 array3D &candidateCoord = partialIntr[i];
433 if (utils::DoubleFloatingEqual()(
norm2(V0 - candidateCoord), 0., distanceTolerance )) {
437 int candidateFlag = partialFlag[i];
440 auto PItr = intrPtr->begin();
441 bool iterate = (PItr!=intrPtr->end());
444 iterate = !utils::DoubleFloatingEqual()(
norm2( *PItr -candidateCoord ), 0., distanceTolerance );
449 iterate &= PItr!=intrPtr->end();
452 if(PItr!=intrPtr->end()){
456 intrPtr->push_back(candidateCoord);
458 flagPtr->push_back(candidateFlag);
465 computeIntersection = polygonEdgeBoxHullIntersection;
467 if(!intersect || polygonEdgeBoxHullIntersection){
468 for (
int edge=0; edge<edgesCount; ++edge) {
471 if( _intersectSegmentBox( V0, V1, A0, A1,
false, polygonEdgeBoxHullIntersection, &partialIntr, &partialFlag, dim, distanceTolerance) ){
474 if(!computeIntersection)
break;
476 int intrCount = partialIntr.size();
477 for(
int i=0; i<intrCount; ++i){
479 array3D &candidateCoord = partialIntr[i];
480 int candidateFlag = partialFlag[i];
483 auto PItr = intrPtr->begin();
484 bool iterate = (PItr!=intrPtr->end());
487 iterate = !utils::DoubleFloatingEqual()(
norm2( *PItr -candidateCoord ), 0., distanceTolerance );
492 iterate &= PItr!=intrPtr->end();
495 if(PItr!=intrPtr->end()){
499 intrPtr->push_back(candidateCoord);
501 flagPtr->push_back(candidateFlag);
591 for(
int i=0; i<n; ++i){
593 double value = lambdaPtr[i];
594 if( std::abs(value) > std::abs(maxValue) ){
605 double tolerance = std::max(1., std::abs(maxValue)) * std::numeric_limits<double>::epsilon();
707 std::size_t lastPositive = std::numeric_limits<std::size_t>::max();
708 for( std::size_t i=0; i<nLambda; ++i){
718 if (lastPositive != 0 || i == 1) {
724 count = lastPositive + 1;
726 }
else if (count==2) {
727 if (lastPositive != 0) {
728 count = -
static_cast<int>(lastPositive);
730 count = -
static_cast<int>(nLambda);
770 lambda.resize(nVertices);
790 const int MAX_ELEM_VERTICES = 8;
793 for( std::size_t i=0; i<nVertices; ++i){
794 int next = (i +1) %nVertices;
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]);
805 for( std::size_t j=0; j<nVertices; ++j){
806 if( j==prev || j==i){
810 lambda[i] *= area[j];
813 sumWeight += lambda[i];
816 for( std::size_t i=0; i<nVertices; ++i){
817 lambda[i] /= sumWeight;
832 return lambda[0]*Q0 +lambda[1]*Q1;
846 return lambda[0]*Q0 +lambda[1]*Q1;
861 return lambda[0]*Q0 +lambda[1]*Q1 +lambda[2]*Q2;
876 return lambda[0]*Q0 +lambda[1]*Q1 +lambda[2]*Q2;
892array3D
rotatePoint(
const array3D &P,
const array3D &n0,
const array3D &n1,
double angle)
895 double axisNorm =
norm2(n1 - n0);
904 std::array<double, 3> axis = (n1 - n0) / axisNorm;
906 std::array<double, 3> axis_cross =
crossProduct(axis, Q);
908 double angle_cos = std::cos(angle);
909 double angle_sin = std::sin(angle);
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;
955 array3D xP = {{0.,0.,0.}};
956 for(std::size_t i=0; i<nV; ++i){
957 xP += lambda[i]*V[i];
999 std::array<double,2> lambda;
1011array3D
projectPointSegment( array3D
const &P, array3D
const &Q0, array3D
const &Q1, std::array<double,2> &lambda )
1033 t = std::max( std::min( t, 1.), 0. );
1053 _projectPointsTriangle( 1, &P, Q0, Q1, Q2, &xP, lambda.data() );
1066array3D
projectPointTriangle( array3D
const &P, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2, array3D &lambda)
1080array3D
projectPointTriangle( array3D
const &P, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2,
double *lambda)
1083 _projectPointsTriangle( 1, &P, Q0, Q1, Q2, &xP, lambda );
1115 std::array<int,2> negatives = {{ 0, 0 }};
1117 for(
int i=0; i<3; ++i){
1119 negatives[count] = i;
1128 std::array<const array3D*,3> r = {{&Q0, &Q1, &Q2}};
1130 std::array<double,2> lambdaLocal;
1131 int vertex0 = (negatives[0] +1) %3;
1132 int vertex1 = (vertex0 +1) %3;
1135 lambda[negatives[0]] = 0.;
1136 lambda[vertex0] = lambdaLocal[0];
1137 lambda[vertex1] = lambdaLocal[1];
1141 int vertex0 = 3 -negatives[0] -negatives[1];
1142 int vertex1 = (vertex0 +1) %3;
1143 int vertex2 = (vertex1 +1) %3;
1145 array3D s01 = *r[vertex1] - *r[vertex0];
1146 array3D s02 = *r[vertex2] - *r[vertex0];
1152 lambda[vertex0] = 1.;
1156 std::array<double,2> lambdaLocal01, lambdaLocal02;
1163 lambda[vertex0] = lambdaLocal01[0];
1164 lambda[vertex1] = lambdaLocal01[1];
1165 lambda[vertex2] = 0.;
1169 lambda[vertex0] = lambdaLocal02[0];
1170 lambda[vertex1] = 0;
1171 lambda[vertex2] = lambdaLocal02[1];
1193std::vector<array3D>
projectCloudTriangle( std::vector<array3D>
const &cloud, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2, std::vector<array3D> &lambda )
1196 int cloudCount(cloud.size());
1198 std::vector<array3D> xP(cloudCount);
1200 lambda.resize(cloudCount);
1202 _projectPointsTriangle( cloudCount, cloud.data(), Q0, Q1, Q2, xP.data(), &lambda[0][0]);
1228 std::vector<double> lambda(nV);
1271 double distance, minDistance(std::numeric_limits<double>::max());
1272 int minTriangle = -1;
1274 array3D localLambda, minLambda;
1279 for (
int triangle=0; triangle < triangleCount; ++triangle) {
1285 if (distance <= minDistance) {
1287 minDistance = distance;
1289 minLambda = localLambda;
1290 minTriangle = triangle;
1295 assert(minTriangle >= 0);
1313array3D
projectPointCone( array3D
const &point, array3D
const &apex, array3D
const &axis,
double alpha)
1317 if( alpha <= BITPIT_PI_2 ) {
1319 array3D versor = point-apex;
1320 versor /=
norm2(versor);
1322 double cosPointAxis =
dotProduct(versor,axis);
1323 double cosCriticalAngle = cos(alpha+BITPIT_PI_2);
1325 if( cosPointAxis <= cosCriticalAngle ){
1331 planeNormal /=
norm2(planeNormal);
1333 array3D direction =
rotateVector(axis,planeNormal,alpha);
1357 return norm2( P-xP);
1424double distancePointTriangle( array3D
const &P, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2, array3D &lambda)
1438double distancePointCone( array3D
const &point, array3D
const &apex, array3D
const &axis,
double alpha)
1441 return norm2(point-xP);
1452std::vector<double>
distanceCloudTriangle( std::vector<array3D>
const &cloud, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2)
1454 std::vector<array3D> lambda(cloud.size());
1467std::vector<double>
distanceCloudTriangle( std::vector<array3D>
const &cloud, array3D
const &Q0, array3D
const &Q1, array3D
const &Q2, std::vector<array3D> &lambda )
1469 int N(cloud.size());
1473 std::vector<array3D> xP(N);
1474 _projectPointsTriangle( N, cloud.data(), Q0, Q1, Q2, xP.data(), &lambda[0][0]);
1476 std::vector<double> d(N);
1477 std::vector<double>::iterator distance = d.begin();
1479 std::vector<array3D>::iterator projection = xP.begin();
1480 for(
const auto &point : cloud){
1481 *distance =
norm2( point - *projection);
1514 const int MAX_ELEM_VERTICES = 8;
1544 std::vector<double> lambda(nV);
1597std::vector<double>
distanceCloudPolygon( std::vector<array3D>
const &cloud, std::vector<array3D>
const &V, std::vector<array3D> &xP, std::vector<int> &flag)
1611std::vector<double>
distanceCloudPolygon( std::vector<array3D>
const &cloud, std::size_t nV, array3D
const *V, std::vector<array3D> &xP, std::vector<int> &flag)
1613 int cloudCount( cloud.size() );
1615 std::vector<std::vector<double>> lambda( cloudCount, std::vector<double> (nV));
1618 xP.resize(cloudCount);
1619 std::vector<array3D>::iterator xPItr = xP.begin();
1621 flag.resize(cloudCount);
1622 std::vector<int>::iterator flagItr = flag.begin();
1624 for(
const auto &l : lambda){
1655 int cloudCount(P.size());
1657 std::vector<double> d(cloudCount,std::numeric_limits<double>::max());
1662 for (
int triangle=0; triangle < triangleCount; ++triangle) {
1679std::vector<double>
distanceCloudPolygon( std::vector<array3D>
const &cloud, std::vector<array3D>
const &V, std::vector<std::vector<double>> &lambda)
1692std::vector<double>
distanceCloudPolygon( std::vector<array3D>
const &cloud, std::size_t nV, array3D
const *V, std::vector<std::vector<double>> &lambda)
1694 int cloudCount(cloud.size()), vertexCount(nV);
1696 std::vector<double> d(cloudCount,std::numeric_limits<double>::max());
1697 lambda.resize(cloudCount, std::vector<double>(vertexCount,0) );
1699 std::vector<double> dTemp(cloudCount);
1700 std::vector<array3D> lambdaTemp(cloudCount);
1704 for (
int triangle=0; triangle < triangleCount; ++triangle) {
1708 for(
int i=0; i< cloudCount; ++i){
1709 if( dTemp[i] < d[i]){
1711 std::copy( lambdaTemp[i].begin(), lambdaTemp[i].end(), lambda[i].begin());
1727double distanceLineLine( array3D
const &P0, array3D
const &n0, array3D
const &P1, array3D
const &n1)
1743double distanceLineLine( array3D
const &P0, array3D
const &n0, array3D
const &P1, array3D
const &n1, array3D &xP0, array3D &xP1)
1749 double det = 1. - n01*n01;
1752 if( std::abs(det) < 1.e-12){
1763 double det0 = rhs0 +rhs1*n01;
1764 double det1 = rhs1 +rhs0*n01;
1766 double s0 = det0/det;
1767 double s1 = det1/det;
1772 return norm2( xP0 - xP1);
1785bool intersectLineLine( array3D
const &P1, array3D
const &n1, array3D
const &P2, array3D
const &n2, array3D &P,
double distanceTolerance)
1806bool intersectSegmentSegment( array3D
const &P1, array3D
const &P2, array3D
const &Q1, array3D
const &Q2, array3D &x,
double distanceTolerance)
1811 array3D nP = P2 - P1;
1814 array3D nQ = Q2 - Q1;
1818 if(
intersectLineLine(P1, nP, Q1, nQ, temp, distanceTolerance) &&
intersectPointSegment( temp, P1, P2, distanceTolerance) &&
intersectPointSegment(temp, Q1, Q2, distanceTolerance) ){
1837bool intersectLinePlane( array3D
const &P1, array3D
const &n1, array3D
const &P2, array3D
const &n2, array3D &P,
const double coplanarityTolerance)
1847 if (std::abs(s) < std::cos(0.5*BITPIT_PI-coplanarityTolerance)) {
1870bool intersectSegmentPlane( array3D
const &Q1, array3D
const &Q2, array3D
const &P2, array3D
const &n2, array3D &P,
const double distanceTolerance)
1876 array3D n = Q2 - Q1;
1901 array3D &Pl, array3D &nl,
const double coplanarityTolerance)
1909 if( std::abs(n12) > std::cos(coplanarityTolerance)) {
1914 double detCB = 1.0-n12*n12;
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;
1935 Pl = P1 +P2 -lambda1*n1 -lambda2*n2;
1952bool intersectPlaneBox( array3D
const &P1, array3D
const &n1, array3D
const &A0, array3D
const &A1,
int dim,
const double distanceTolerance)
1955 return _intersectPlaneBox( P1, n1, A0, A1,
nullptr, dim, distanceTolerance);
1969bool intersectPlaneBox( array3D
const &P1, array3D
const &n1, array3D
const &A0, array3D
const &A1, std::vector<array3D> &intersects,
int dim,
const double distanceTolerance)
1972 return _intersectPlaneBox( P1, n1, A0, A1, &intersects, dim, distanceTolerance);
1986bool intersectLineTriangle( array3D
const &P, array3D
const &n, array3D
const &A, array3D
const &B, array3D
const &C, array3D &Q,
const double distanceTolerance)
2014bool intersectSegmentTriangle( array3D
const &P0, array3D
const &P1, array3D
const &A, array3D
const &B, array3D
const &C, array3D &Q,
const double distanceTolerance)
2019 array3D n = P1 - P0;
2040bool intersectLinePolygon( array3D
const &P, array3D
const &n, std::vector<array3D >
const &V, array3D &Q,
const double distanceTolerance)
2055bool intersectLinePolygon( array3D
const &P, array3D
const &n, std::size_t nV, array3D
const *V, array3D &Q,
const double distanceTolerance)
2062 for(
int i=0; i< nTriangles; ++i){
2082bool intersectSegmentPolygon( array3D
const &P0, array3D
const &P1, std::vector<array3D >
const &V, array3D &Q,
const double distanceTolerance)
2097bool intersectSegmentPolygon( array3D
const &P0, array3D
const &P1, std::size_t nV, array3D
const *V, array3D &Q,
const double distanceTolerance)
2104 for(
int i=0; i< nTriangles; ++i){
2125bool intersectBoxBox(array3D
const &A1, array3D
const &A2, array3D
const &B1, array3D
const &B2,
int dim,
const double distanceTolerance)
2127 for(
int d=0; d<dim; ++d){
2128 if( B1[d] > A2[d] + distanceTolerance || B2[d] < A1[d] - distanceTolerance ){
2148bool intersectBoxBox(array3D
const &A1, array3D
const &A2, array3D
const &B1, array3D
const &B2, array3D &I1, array3D &I2,
int dim,
const double distanceTolerance )
2150 for(
int d=0; d<dim; ++d){
2152 if( B1[d] > A2[d] + distanceTolerance || B2[d] < A1[d] - distanceTolerance ){
2157 I1[d] = std::max( A1[d], B1[d] );
2158 I2[d] = std::min( A2[d], B2[d] );
2177bool intersectBoxTriangle(array3D
const &A0, array3D
const &A1, array3D
const &V0, array3D
const &V1, array3D
const &V2,
int dim,
const double distanceTolerance)
2179 return _intersectBoxTriangle( A0, A1, V0, V1, V2,
false,
false,
false,
nullptr,
nullptr, dim, distanceTolerance);
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)
2199 return _intersectBoxTriangle( A0, A1, V0, V1, V2, interiorTriangleVertices, triangleEdgeBoxFaceIntersections, triangleBoxEdgeIntersections, &P,
nullptr, dim, distanceTolerance);
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)
2220 return _intersectBoxTriangle( A0, A1, V0, V1, V2, interiorTriangleVertices, triangleEdgeBoxHullIntersections, triangleBoxEdgeIntersections, &P, &flag, dim, distanceTolerance);
2233bool intersectSegmentBox( array3D
const &V0, array3D
const &V1, array3D
const &A0, array3D
const &A1,
int dim,
const double distanceTolerance)
2235 return _intersectSegmentBox( V0, V1, A0, A1,
false,
false,
nullptr,
nullptr, dim, distanceTolerance);
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)
2253 return _intersectSegmentBox( V0, V1, A0, A1, interiorSegmentVertice, segmentBoxHullIntersection, &P,
nullptr, dim, distanceTolerance);
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)
2272 return _intersectSegmentBox( V0, V1, A0, A1, interiorSegmentVertice, segmentBoxHullIntersection, &P, &flag, dim, distanceTolerance);
2284bool intersectBoxPolygon( array3D
const &A0, array3D
const &A1, std::vector<array3D>
const &VS,
int dim,
const double distanceTolerance )
2298bool intersectBoxPolygon( array3D
const &A0, array3D
const &A1, std::size_t nVS, array3D
const *VS,
int dim,
const double distanceTolerance )
2300 return _intersectBoxPolygon(A0, A1, nVS, VS,
false,
false,
false,
nullptr,
nullptr, dim, distanceTolerance);
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)
2318 return intersectBoxPolygon( A0, A1, VS.size(), VS.data(), innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, P, dim, distanceTolerance);
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)
2338 return _intersectBoxPolygon(A0, A1, nVS, VS, innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, &P,
nullptr, dim, distanceTolerance);
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)
2357 return intersectBoxPolygon( A0, A1, VS.size(), VS.data(), innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, P, flag, dim, distanceTolerance);
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)
2377 return _intersectBoxPolygon(A0, A1, nVS, VS, innerPolygonPoints, polygonEdgeBoxFaceIntersections, polygonBoxEdgeIntersections, &P, &flag, dim, distanceTolerance);
2390bool intersectBoxCircle( array3D
const &A0, array3D
const &A1, array3D
const ¢re,
double radius,
const double distanceTolerance)
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]);
2401 double inflatedRadius = radius + distanceTolerance;
2403 return (minimumDistance <= (inflatedRadius * inflatedRadius));
2416bool intersectBoxSphere( array3D
const &A0, array3D
const &A1, array3D
const ¢re,
double radius,
const double distanceTolerance)
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]);
2427 double inflatedRadius = radius + distanceTolerance;
2429 return (minimumDistance <= (inflatedRadius * inflatedRadius));
2510bool intersectPointLine( array3D
const &P, array3D
const &Q, array3D
const &n,
const double distanceTolerance)
2535 array3D offset = xP - P;
2537 return (
dotProduct(offset, offset) <= distanceTolerance * distanceTolerance);
2549bool intersectPointTriangle( array3D
const &P, array3D
const &A, array3D
const &B, array3D
const &C,
const double distanceTolerance)
2568bool intersectPointBox( array3D
const &P, array3D
const &B1, array3D
const &B2,
int dim,
const double distanceTolerance)
2571 for(
int d=0; d<dim; ++d){
2572 if( P[d]< (B1[d] - distanceTolerance) || P[d] > (B2[d] + distanceTolerance)){
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] );
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] );
2618 P1[i] = std::max( P1[i], B[i] );
2619 P1[i] = std::max( P1[i], C[i] );
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] );
2667void unionAABB( array3D
const &A0, array3D
const &A1, array3D
const &B0, array3D
const &B1, array3D &C0, array3D &C1)
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]);
2684void unionAABB(std::vector<array3D>
const &A0, std::vector<array3D>
const &A1, array3D &C0, array3D &C1)
2687 int n( std::min(A0.size(), A1.size() ) );
2693 for(
int i=1; i<n; ++i){
2694 unionAABB( A0[i], A1[i], C0, C1, C0, C1);
2710void intersectionAABB(array3D
const &A0, array3D
const &A1, array3D
const &B0, array3D
const &B1, array3D &C0, array3D &C1)
2725void subtractionAABB(array3D
const &A0, array3D
const &A1, array3D
const &B0, array3D
const &B1, array3D &C0, array3D &C1)
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];
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];
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];
2783void vertexOfTriangle(
int i, array3D
const &V0, array3D
const &V1, array3D
const &V2, array3D &P)
2816void edgeOfTriangle(
int i, array3D
const &V0, array3D
const &V1, array3D
const &V2, array3D &P0, array3D &P1)
2853void faceOfBox(
int i, array3D
const &A0, array3D
const &A1, array3D &P0, array3D &P1, array3D &P2, array3D &P3)
2879void edgeOfBox(
int i, array3D
const &A0, array3D
const &A1, array3D &P0, array3D &P1)
2899void vertexOfBox(
int i, array3D
const &A0, array3D
const &A1, array3D &P)
2968array3D
rotateVector( array3D
const &vector, array3D
const &axis,
double theta)
2972 double cosTheta = cos(theta);
2974 rotated = cosTheta * vector;
2976 rotated += (1.0 - cosTheta) *
dotProduct(axis,vector) * axis;
3051void edgeOfPolygon(
int edge, std::vector<array3D>
const &V, array3D &V0, array3D &V1)
3064void edgeOfPolygon(
int edge, std::size_t nV, array3D
const *V, array3D &V0, array3D &V1)
3069 V1 = V[(edge+1) % nV];
3112 for (std::size_t i = 0; i < nV; i++) {
3113 for (
int d = 0; d < 3; d++) {
3117 for (
int d = 0; d < 3; d++) {
3120 V1 = V[triangle%nV];
3121 V2 = V[(triangle+1)%nV];
void edgeOfPolygon(int, std::vector< array3D > const &, array3D &, array3D &)
std::vector< double > distanceCloudTriangle(std::vector< array3D > const &, array3D const &, array3D const &, array3D const &)
double distancePointLine(array3D const &, array3D const &, array3D const &, array3D &)
double distancePointCone(array3D const &, array3D const &, array3D const &, double)
array3D projectPointLine(array3D const &, array3D const &, array3D const &)
void edgeOfTriangle(int, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
const std::array< std::array< int, 2 >, 12 > boxEdgeVertexConnectivity
bool intersectPlaneBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
void unionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
bool intersectPointTriangle(array3D const &, array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectBoxBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
array3D projectPointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
array3D rotateVector(array3D const &, array3D const &, double)
array3D projectPointSegment(array3D const &, array3D const &, array3D const &)
double distancePointPlane(array3D const &, array3D const &, array3D const &, array3D &)
bool intersectBoxTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
int convertBarycentricToFlagSegment(std::array< double, 2 > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
void computeAABBTriangle(array3D const &, array3D const &, array3D const &, array3D &, array3D &)
bool validBarycentric(double const *, int)
void intersectionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
double distanceLineLine(array3D const &, array3D const &, array3D const &, array3D const &)
array3D reconstructPointFromBarycentricTriangle(array3D const &, array3D const &, array3D const &, std::array< double, 3 > const &)
array3D reconstructPointFromBarycentricSegment(array3D const &, array3D const &, std::array< double, 2 > const &)
const std::array< std::array< int, 4 >, 6 > boxFaceVertexConnectivity
std::vector< double > distanceCloudPolygon(std::vector< array3D > const &, std::vector< array3D > const &, std::vector< array3D > &, std::vector< int > &)
void vertexOfSegment(int, array3D const &, array3D const &, array3D &)
void vertexOfTriangle(int, array3D const &, array3D const &, array3D const &, array3D &)
int convertBarycentricToFlagPolygon(std::vector< double > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectSegmentPlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectLineTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectSegmentSegment(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
double distancePointTriangle(array3D const &, array3D const &, array3D const &, array3D const &)
bool intersectPointLine(array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
int polygonEdgesCount(std::vector< array3D > const &)
int polygonSubtriangleCount(std::vector< array3D > const &)
bool intersectBoxSphere(array3D const &A0, array3D const &A1, array3D const ¢re, double radius, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
int convertBarycentricToFlagTriangle(std::array< double, 3 > const &, double tolerance=DEFAULT_DISTANCE_TOLERANCE)
double areaTriangle(array3D const &, array3D const &, array3D const &)
array3D projectPointPlane(array3D const &, array3D const &, array3D const &)
void subtriangleOfPolygon(int, std::vector< array3D > const &, array3D &, array3D &, array3D &)
bool intersectSegmentBox(array3D const &, array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectPlanePlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &, const double coplanarityTolerance=DEFAULT_COPLANARITY_TOLERANCE)
void computeGeneralizedBarycentric(array3D const &, std::vector< array3D > const &, std::vector< double > &)
double distancePointSegment(array3D const &, array3D const &, array3D const &)
bool intersectLinePlane(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double coplanarityTolerance=DEFAULT_COPLANARITY_TOLERANCE)
bool validPlane(array3D const &, array3D const &)
array3D rotatePoint(const array3D &P, const array3D &n0, const array3D &n1, double angle)
double distancePointPolygon(array3D const &, std::vector< array3D > const &, array3D &, int &)
bool validLine(array3D const &, array3D const &)
void computeAABBPolygon(std::vector< array3D > const &, array3D &, array3D &)
bool validTriangle(array3D const &, array3D const &, array3D const &)
array3D reconstructPointFromBarycentricPolygon(std::vector< array3D > const &, std::vector< double > const &)
bool intersectSegmentTriangle(array3D const &, array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
array3D restrictPointTriangle(array3D const &, array3D const &, array3D const &, array3D &)
bool intersectBoxPolygon(array3D const &, array3D const &, std::vector< array3D > const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
void faceOfBox(int, array3D const &, array3D const &, array3D &, array3D &, array3D &, array3D &)
std::vector< array3D > projectCloudTriangle(std::vector< array3D > const &, array3D const &, array3D const &, array3D const &, std::vector< array3D > &)
array3D projectPointCone(array3D const &, array3D const &, array3D const &, double)
void vertexOfBox(int, array3D const &, array3D const &, array3D &)
void edgeOfBox(int, array3D const &, array3D const &, array3D &, array3D &)
void subtractionAABB(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, array3D &)
array3D projectPointPolygon(array3D const &, std::vector< array3D > const &)
bool validSegment(array3D const &, array3D const &)
void computeAABBSegment(array3D const &, array3D const &, array3D &, array3D &)
bool intersectPointBox(array3D const &, array3D const &, array3D const &, int dim=3, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectPointSegment(array3D const &, array3D const &, array3D const &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectLineLine(array3D const &, array3D const &, array3D const &, array3D const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectBoxCircle(array3D const &A0, array3D const &A1, array3D const ¢re, double radius, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectLinePolygon(array3D const &, array3D const &, std::vector< array3D > const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
bool intersectSegmentPolygon(array3D const &, array3D const &, std::vector< array3D > const &, array3D &, const double distanceTolerance=DEFAULT_DISTANCE_TOLERANCE)
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)
#define BITPIT_UNUSED(variable)
#define BITPIT_CREATE_WORKSPACE(workspace, item_type, size, stack_size)