100 template <
class TGeometryType>
102 const TGeometryType& rTriangleGeometry,
106 const double epsilon = 1
e-12) {
129 if (std::abs(
b) < epsilon){
138 const double r =
a /
b;
141 }
else if (r > 1.0) {
145 rIntersectionPoint = rLinePoint1 + r*
dir;
148 if (PointInTriangle(rTriangleGeometry[0], rTriangleGeometry[1], rTriangleGeometry[2], rIntersectionPoint)) {
161 template <
class TGeometryType>
163 const TGeometryType& rTriangle,
167 return TriangleLineIntersection2D(rTriangle[0], rTriangle[1], rTriangle[2], rPoint0, rPoint1);
188 if (ComputeLineLineIntersection(rVert0, rVert1, rPoint0, rPoint1, int_point))
return true;
189 if (ComputeLineLineIntersection(rVert1, rVert2, rPoint0, rPoint1, int_point))
return true;
190 if (ComputeLineLineIntersection(rVert2, rVert0, rPoint0, rPoint1, int_point))
return true;
193 if (PointInTriangle(rVert0, rVert1, rVert2, rPoint0))
return true;
216 const double Tolerance = std::numeric_limits<double>::epsilon())
227 const double denom = uv * uv - uu * vv;
229 const double xi = (uv * wv - vv * wu) / denom;
230 const double eta = (uv * wu - uu * wv) / denom;
232 if (xi < -Tolerance)
return false;
233 if (eta < -Tolerance)
return false;
234 if (xi + eta > 1.0 + Tolerance)
return false;
254 template <
class TGeometryType,
class TCoordinatesType>
256 const TGeometryType& rTriangleGeometry,
257 const TCoordinatesType& rLinePoint1,
258 const TCoordinatesType& rLinePoint2,
259 TCoordinatesType& rIntersectionPoint1,
260 TCoordinatesType& rIntersectionPoint2,
262 const double Epsilon = 1
e-12
266 auto is_inside_projected = [&Epsilon] (
auto& rGeometry,
const TCoordinatesType& rPoint) ->
bool {
268 const Point point_to_project(rPoint);
269 Point point_projected;
273 if (std::abs(distance) > Epsilon * rGeometry.Length()) {
277 return rGeometry.IsInside(point_projected, local_coordinates);
281 for (
auto& r_edge : rTriangleGeometry.GenerateEdges()) {
282 const auto& r_edge_point_1 = r_edge[0].Coordinates();
283 const auto& r_edge_point_2 = r_edge[1].Coordinates();
285 const auto check_1 = ComputeLineLineIntersection(rLinePoint1, rLinePoint2, r_edge_point_1, r_edge_point_2, intersection_point_1, Epsilon);
286 const auto check_2 = ComputeLineLineIntersection(r_edge_point_1, r_edge_point_2, rLinePoint1, rLinePoint2, intersection_point_2, Epsilon);
287 if (check_1 == 0 && check_2 == 0)
continue;
288 array_1d<double, 3> intersection_point = check_1 != 0 ? intersection_point_1 : intersection_point_2;
289 if (check_1 == 2 || check_2 == 2) {
292 vector_line /=
norm_2(vector_line);
294 const double diff_coor_1_norm =
norm_2(diff_coor_1);
295 if (diff_coor_1_norm > std::numeric_limits<double>::epsilon()) {
296 diff_coor_1 /= diff_coor_1_norm;
298 diff_coor_1 = rLinePoint1 - r_edge_point_2;
299 diff_coor_1 /=
norm_2(diff_coor_1);
302 const double diff_coor_2_norm =
norm_2(diff_coor_2);
303 if (diff_coor_2_norm > std::numeric_limits<double>::epsilon()) {
304 diff_coor_2 /= diff_coor_2_norm;
306 diff_coor_2 = rLinePoint2 - r_edge_point_2;
307 diff_coor_2 /=
norm_2(diff_coor_2);
309 const double diff1m =
norm_2(diff_coor_1 - vector_line);
310 const double diff1p =
norm_2(diff_coor_1 + vector_line);
311 const double diff2m =
norm_2(diff_coor_2 - vector_line);
312 const double diff2p =
norm_2(diff_coor_2 + vector_line);
315 if ((diff1m < Epsilon || diff1p < Epsilon) && (diff2m < Epsilon || diff2p < Epsilon)) {
317 if (is_inside_projected(r_edge, rLinePoint1)) {
318 if (rSolution == 0) {
319 noalias(rIntersectionPoint1) = rLinePoint1;
322 if (
norm_2(rIntersectionPoint1 - rLinePoint1) > Epsilon) {
323 noalias(rIntersectionPoint2) = rLinePoint1;
329 if (rSolution == 0) {
330 noalias(rIntersectionPoint1) =
norm_2(r_edge_point_1 - rLinePoint1) <
norm_2(r_edge_point_2 - rLinePoint1) ? r_edge_point_1 : r_edge_point_2;
333 noalias(intersection_point) =
norm_2(r_edge_point_1 - rLinePoint1) <
norm_2(r_edge_point_2 - rLinePoint1) ? r_edge_point_1 : r_edge_point_2;
334 if (
norm_2(rIntersectionPoint1 - intersection_point) > Epsilon) {
335 noalias(rIntersectionPoint2) = intersection_point;
342 if (rSolution == 2) {
343 if (is_inside_projected(r_edge, rLinePoint2)) {
344 if (
norm_2(rIntersectionPoint1 - rLinePoint2) > Epsilon) {
345 noalias(rIntersectionPoint2) = rLinePoint2;
350 noalias(intersection_point) =
norm_2(r_edge_point_1 - rLinePoint2) <
norm_2(r_edge_point_2 - rLinePoint2) ? r_edge_point_1 : r_edge_point_2;
351 if (
norm_2(rIntersectionPoint1 - intersection_point) > Epsilon) {
352 noalias(rIntersectionPoint2) = intersection_point;
362 if (rSolution == 0) {
363 noalias(rIntersectionPoint1) = intersection_point;
366 if (
norm_2(rIntersectionPoint1 - intersection_point) > Epsilon) {
367 noalias(rIntersectionPoint2) = intersection_point;
413 template <
class TGeometryType,
class TCoordinatesType,
bool TCons
iderIns
idePo
ints = true>
415 const TGeometryType& rTetrahedraGeometry,
416 const TCoordinatesType& rLinePoint1,
417 const TCoordinatesType& rLinePoint2,
418 TCoordinatesType& rIntersectionPoint1,
419 TCoordinatesType& rIntersectionPoint2,
420 const double Epsilon = 1
e-12
424 for (
auto& r_face : rTetrahedraGeometry.GenerateFaces()) {
426 const int face_solution = ComputeTriangleLineIntersection(r_face, rLinePoint1, rLinePoint2, intersection_point, Epsilon);
427 if (face_solution == 1) {
429 noalias(rIntersectionPoint1) = intersection_point;
432 if (
norm_2(rIntersectionPoint1 - intersection_point) > Epsilon) {
433 noalias(rIntersectionPoint2) = intersection_point;
438 }
else if (face_solution == 2) {
439 ComputeTriangleLineIntersectionInTheSamePlane(r_face, rLinePoint1, rLinePoint2, rIntersectionPoint1, rIntersectionPoint2,
solution, Epsilon);
445 if constexpr (TConsiderInsidePoints) {
448 if (rTetrahedraGeometry.IsInside(rLinePoint1, local_coordinates)) {
449 noalias(rIntersectionPoint1) = rLinePoint1;
452 if (rTetrahedraGeometry.IsInside(rLinePoint2, local_coordinates)) {
454 noalias(rIntersectionPoint1) = rLinePoint2;
457 noalias(rIntersectionPoint2) = rLinePoint2;
463 if (rTetrahedraGeometry.IsInside(rLinePoint1, local_coordinates)) {
464 if (
norm_2(rIntersectionPoint1 - rLinePoint1) > Epsilon) {
465 noalias(rIntersectionPoint2) = rLinePoint1;
470 if (rTetrahedraGeometry.IsInside(rLinePoint2, local_coordinates)) {
471 if (
norm_2(rIntersectionPoint1 - rLinePoint2) > Epsilon) {
472 noalias(rIntersectionPoint2) = rLinePoint2;
484 for (
int i_node = 0; i_node < 4; ++i_node) {
485 if (
norm_2(rTetrahedraGeometry[i_node].Coordinates() - rIntersectionPoint1) < Epsilon) {
491 if (index_node > -1) {
492 return index_node + 5;
511 template<
class TGeometryType>
513 const TGeometryType& rSegment1,
514 const TGeometryType& rSegment2
518 const double zero_tolerance = std::numeric_limits<double>::epsilon();
529 double d1343,d4321,d1321,d4343,d2121;
534 const Point& p1 = rSegment1[0];
535 const Point& p2 = rSegment1[1];
536 const Point& p3 = rSegment2[0];
537 const Point& p4 = rSegment2[1];
539 p13[0] = p1.
X() - p3.
X();
540 p13[1] = p1.
Y() - p3.
Y();
541 p13[2] = p1.
Z() - p3.
Z();
543 p43[0] = p4.
X() - p3.
X();
544 p43[1] = p4.
Y() - p3.
Y();
545 p43[2] = p4.
Z() - p3.
Z();
546 if (std::abs(p43[0]) < zero_tolerance && std::abs(p43[1]) < zero_tolerance && std::abs(p43[2]) < zero_tolerance)
547 return resulting_line;
549 p21[0] = p2.
X() - p1.
X();
550 p21[1] = p2.
Y() - p1.
Y();
551 p21[2] = p2.
Z() - p1.
Z();
552 if (std::abs(p21[0]) < zero_tolerance && std::abs(p21[1]) < zero_tolerance && std::abs(p21[2]) < zero_tolerance)
553 return resulting_line;
555 d1343 = p13[0] * p43[0] + p13[1] * p43[1] + p13[2] * p43[2];
556 d4321 = p43[0] * p21[0] + p43[1] * p21[1] + p43[2] * p21[2];
557 d1321 = p13[0] * p21[0] + p13[1] * p21[1] + p13[2] * p21[2];
558 d4343 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2];
559 d2121 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2];
561 denom = d2121 * d4343 - d4321 * d4321;
562 auto pa = Kratos::make_shared<Point>(0.0, 0.0, 0.0);
563 auto pb = Kratos::make_shared<Point>(0.0, 0.0, 0.0);
564 if (std::abs(denom) < zero_tolerance) {
566 Point projected_point;
570 if (rSegment2.IsInside(projected_point, local_coords)) {
571 pa->Coordinates() = rSegment1[0].Coordinates();
572 pb->Coordinates() = projected_point;
575 if (rSegment2.IsInside(projected_point, local_coords)) {
576 pa->Coordinates() = rSegment1[1].Coordinates();
577 pb->Coordinates() = projected_point;
580 if (rSegment1.IsInside(projected_point, local_coords)) {
581 pa->Coordinates() = rSegment2[0].Coordinates();
582 pb->Coordinates() = projected_point;
585 if (rSegment1.IsInside(projected_point, local_coords)) {
586 pa->Coordinates() = rSegment2[1].Coordinates();
587 pb->Coordinates() = projected_point;
589 return resulting_line;
595 numer = d1343 * d4321 - d1321 * d4343;
598 mub = (d1343 + d4321 * mua) / d4343;
600 pa->
X() = p1.
X() + mua * p21[0];
601 pa->Y() = p1.
Y() + mua * p21[1];
602 pa->Z() = p1.
Z() + mua * p21[2];
603 pb->X() = p3.
X() + mub * p43[0];
604 pb->Y() = p3.
Y() + mub * p43[1];
605 pb->Z() = p3.
Z() + mub * p43[2];
608 resulting_line.push_back(pa);
609 resulting_line.push_back(pb);
610 return resulting_line;
625 template <
class TGeometryType>
627 const TGeometryType& rLineGeometry,
631 const double epsilon = 1
e-12)
633 return ComputeLineLineIntersection(
634 rLineGeometry[0], rLineGeometry[1], rLinePoint0, rLinePoint1, rIntersectionPoint, epsilon);
656 const double epsilon = 1
e-12)
662 const double aux_1 = CrossProd2D(r,s);
663 const double aux_2 = CrossProd2D(q_p,r);
664 const double aux_3 = CrossProd2D(q_p,s);
668 if (std::abs(aux_1) < epsilon && std::abs(aux_2) < epsilon){
672 const double t_1 = t_0 + aux_5/aux_4;
674 if (t_1 >= 0.0 && t_0 <= 1.0){
678 if (t_0 >= 0.0 && t_1 <= 1.0){
683 }
else if (std::abs(aux_1) < epsilon && std::abs(aux_2) > epsilon){
686 }
else if (std::abs(aux_1) > epsilon){
687 const double u = aux_2/aux_1;
688 const double t = aux_3/aux_1;
689 if (((
u >= 0.0) && (
u <= 1.0)) && ((
t >= 0.0) && (
t <= 1.0))){
690 rIntersectionPoint = rLine2Point0 +
u*s;
692 if (
u < epsilon || (1.0 -
u) < epsilon) {
721 const double epsilon = 1
e-12)
731 const double a =
inner_prod(rPlaneNormal,( rPlaneBasePoint - rLinePoint1 ));
732 const double b =
inner_prod(rPlaneNormal,line_dir);
733 if (std::abs(
b) < epsilon){
734 if (std::abs(
a) < epsilon){
742 const double r =
a /
b;
745 }
else if (r > 1.0) {
748 rIntersectionPoint = rLinePoint1 + r * line_dir;
773 if (rLinePoint1[0] < rBoxPoint0[0] && rLinePoint0[0] < rBoxPoint0[0])
return false;
774 if (rLinePoint1[0] > rBoxPoint1[0] && rLinePoint0[0] > rBoxPoint1[0])
return false;
775 if (rLinePoint1[1] < rBoxPoint0[1] && rLinePoint0[1] < rBoxPoint0[1])
return false;
776 if (rLinePoint1[1] > rBoxPoint1[1] && rLinePoint0[1] > rBoxPoint1[1])
return false;
777 if (rLinePoint1[2] < rBoxPoint0[2] && rLinePoint0[2] < rBoxPoint0[2])
return false;
778 if (rLinePoint1[2] > rBoxPoint1[2] && rLinePoint0[2] > rBoxPoint1[2])
return false;
779 if (rLinePoint0[0] > rBoxPoint0[0] && rLinePoint0[0] < rBoxPoint1[0] &&
780 rLinePoint0[1] > rBoxPoint0[1] && rLinePoint0[1] < rBoxPoint1[1] &&
781 rLinePoint0[2] > rBoxPoint0[2] && rLinePoint0[2] < rBoxPoint1[2]) {
784 if ((GetLineBoxIntersection(rLinePoint0[0]-rBoxPoint0[0], rLinePoint1[0]-rBoxPoint0[0], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 1 )) ||
785 (GetLineBoxIntersection(rLinePoint0[1]-rBoxPoint0[1], rLinePoint1[1]-rBoxPoint0[1], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 2 )) ||
786 (GetLineBoxIntersection(rLinePoint0[2]-rBoxPoint0[2], rLinePoint1[2]-rBoxPoint0[2], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 3 )) ||
787 (GetLineBoxIntersection(rLinePoint0[0]-rBoxPoint1[0], rLinePoint1[0]-rBoxPoint1[0], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 1 )) ||
788 (GetLineBoxIntersection(rLinePoint0[1]-rBoxPoint1[1], rLinePoint1[1]-rBoxPoint1[1], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 2 )) ||
789 (GetLineBoxIntersection(rLinePoint0[2]-rBoxPoint1[2], rLinePoint1[2]-rBoxPoint1[2], rLinePoint0, rLinePoint1, intersection_point) && InBox(intersection_point, rBoxPoint0, rBoxPoint1, 3 ))){
836 return (
a(0)*
b(1) -
a(1)*
b(0));
839 static inline int GetLineBoxIntersection(
842 const array_1d<double,3> &rPoint1,
843 const array_1d<double,3> &rPoint2,
844 array_1d<double,3> &rIntersectionPoint)
846 if ((Dist1 * Dist2) >= 0.0){
850 if (std::abs(Dist1-Dist2) < 1
e-12){
853 rIntersectionPoint = rPoint1 + (rPoint2-rPoint1)*(-Dist1/(Dist2-Dist1));
857 static inline int InBox(
858 const array_1d<double,3> &rIntersectionPoint,
859 const array_1d<double,3> &rBoxPoint0,
860 const array_1d<double,3> &rBoxPoint1,
861 const unsigned int Axis)
863 if ( Axis==1 && rIntersectionPoint[2] > rBoxPoint0[2] && rIntersectionPoint[2] < rBoxPoint1[2] && rIntersectionPoint[1] > rBoxPoint0[1] && rIntersectionPoint[1] < rBoxPoint1[1])
return 1;
864 if ( Axis==2 && rIntersectionPoint[2] > rBoxPoint0[2] && rIntersectionPoint[2] < rBoxPoint1[2] && rIntersectionPoint[0] > rBoxPoint0[0] && rIntersectionPoint[0] < rBoxPoint1[0])
return 1;
865 if ( Axis==3 && rIntersectionPoint[0] > rBoxPoint0[0] && rIntersectionPoint[0] < rBoxPoint1[0] && rIntersectionPoint[1] > rBoxPoint0[1] && rIntersectionPoint[1] < rBoxPoint1[1])
return 1;
static double FastProjectOnLine(const TGeometryType &rGeometry, const PointType &rPointToProject, PointType &rPointProjected)
Project a point over a line (2D or 3D)
Definition: geometrical_projection_utilities.h:192
Utilities to compute intersections between different geometries.
Definition: intersection_utilities.h:60
IntersectionUtilities()
Default constructor.
Definition: intersection_utilities.h:79
static bool TriangleLineIntersection2D(const array_1d< double, 3 > &rVert0, const array_1d< double, 3 > &rVert1, const array_1d< double, 3 > &rVert2, const array_1d< double, 3 > &rPoint0, const array_1d< double, 3 > &rPoint1)
Definition: intersection_utilities.h:179
static int ComputeTriangleLineIntersectionInTheSamePlane(const TGeometryType &rTriangleGeometry, const TCoordinatesType &rLinePoint1, const TCoordinatesType &rLinePoint2, TCoordinatesType &rIntersectionPoint1, TCoordinatesType &rIntersectionPoint2, int &rSolution, const double Epsilon=1e-12)
Find the 3D intersection of a line (bounded) with a triangle (bounded) in the same plane.
Definition: intersection_utilities.h:255
static int ComputeLineBoxIntersection(const array_1d< double, 3 > &rBoxPoint0, const array_1d< double, 3 > &rBoxPoint1, const array_1d< double, 3 > &rLinePoint0, const array_1d< double, 3 > &rLinePoint1)
Compute a segment box intersection Provided the minimum and maximum points of a box cell,...
Definition: intersection_utilities.h:765
KRATOS_CLASS_POINTER_DEFINITION(IntersectionUtilities)
Pointer definition of IntersectionUtilities.
static int ComputeTetrahedraLineIntersection(const TGeometryType &rTetrahedraGeometry, const TCoordinatesType &rLinePoint1, const TCoordinatesType &rLinePoint2, TCoordinatesType &rIntersectionPoint1, TCoordinatesType &rIntersectionPoint2, const double Epsilon=1e-12)
Find the 3D intersection of a line (bounded) with a tetrahedra (bounded)
Definition: intersection_utilities.h:414
static bool PointInTriangle(const array_1d< double, 3 > &rVert0, const array_1d< double, 3 > &rVert1, const array_1d< double, 3 > &rVert2, const array_1d< double, 3 > &rPoint, const double Tolerance=std::numeric_limits< double >::epsilon())
This uses the Cramer's rule for solving a linear system and obtain the barycentric coordinates.
Definition: intersection_utilities.h:211
static int ComputeLineLineIntersection(const array_1d< double, 3 > &rLine1Point0, const array_1d< double, 3 > &rLine1Point1, const array_1d< double, 3 > &rLine2Point0, const array_1d< double, 3 > &rLine2Point1, array_1d< double, 3 > &rIntersectionPoint, const double epsilon=1e-12)
Definition: intersection_utilities.h:650
static bool TriangleLineIntersection2D(const TGeometryType &rTriangle, const array_1d< double, 3 > &rPoint0, const array_1d< double, 3 > &rPoint1)
Definition: intersection_utilities.h:162
static int ComputeTriangleLineIntersection(const TGeometryType &rTriangleGeometry, const array_1d< double, 3 > &rLinePoint1, const array_1d< double, 3 > &rLinePoint2, array_1d< double, 3 > &rIntersectionPoint, const double epsilon=1e-12)
Definition: intersection_utilities.h:101
static int ComputePlaneLineIntersection(const array_1d< double, 3 > &rPlaneBasePoint, const array_1d< double, 3 > &rPlaneNormal, const array_1d< double, 3 > &rLinePoint1, const array_1d< double, 3 > &rLinePoint2, array_1d< double, 3 > &rIntersectionPoint, const double epsilon=1e-12)
Find the 3D intersection of a plane (infinite) with a segment (bounded)
Definition: intersection_utilities.h:715
static PointerVector< Point > ComputeShortestLineBetweenTwoLines(const TGeometryType &rSegment1, const TGeometryType &rSegment2)
Calculates the line to line intersection (shortest line). If line is length 0, it is considered a poi...
Definition: intersection_utilities.h:512
static int ComputeLineLineIntersection(const TGeometryType &rLineGeometry, const array_1d< double, 3 > &rLinePoint0, const array_1d< double, 3 > &rLinePoint1, array_1d< double, 3 > &rIntersectionPoint, const double epsilon=1e-12)
Definition: intersection_utilities.h:626
virtual ~IntersectionUtilities()
Destructor.
Definition: intersection_utilities.h:82
Various mathematical utilitiy functions.
Definition: math_utils.h:62
Point class.
Definition: point.h:59
double Y() const
Definition: point.h:187
double Z() const
Definition: point.h:193
double X() const
Definition: point.h:181
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
solution
Definition: KratosDEM.py:9
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
v
Definition: generate_convection_diffusion_explicit_element.py:114
w
Definition: generate_convection_diffusion_explicit_element.py:108
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
u
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:30
int t
Definition: ode_solve.py:392
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
dir
Definition: radii_error_plotter.py:10
e
Definition: run_cpp_mpi_tests.py:31