https://mooseframework.inl.gov
Triangle.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "Triangle.h"
11 #include "LineSegment.h"
12 
13 #include <cmath>
14 
15 using libMesh::Point;
16 using libMesh::Real;
17 
18 Triangle::Triangle(const Point & p0, const Point & p1, const Point & p2) : _p0(p0), _p1(p1), _p2(p2)
19 {
20 }
21 
22 Point
24 {
25  const auto v1 = _p1 - _p0;
26  const auto v2 = _p2 - _p0;
27 
28  auto n = v1.cross(v2);
29  n /= n.norm();
30 
31  return n;
32 }
33 
34 bool
35 Triangle::intersect(const LineSegment & line_segment, Point & intersect_p) const
36 {
37  const auto & a = line_segment.start();
38  const auto & b = line_segment.end();
39 
40  // (a) Build basic vectors and choose a robust tolerance
41  const Point dir = b - a;
42 
43  const Point edge1 = _p1 - _p0;
44  const Point edge2 = _p2 - _p0;
45  constexpr Real eps = libMesh::TOLERANCE;
46 
47  // (b) Test for parallel or degenerate configuration
48  const Point pvec = dir.cross(edge2);
49  const Real det = edge1 * pvec;
50  if (std::abs(det) < eps)
51  return false; // ray nearly parallel to triangle
52 
53  const Real inv_det = 1.0 / det;
54 
55  // (c) Compute barycentric coordinate u and check 0 <= u <= 1
56  const Point tvec = a - _p0;
57  const Real u = (tvec * pvec) * inv_det;
58  if (!MooseUtils::absoluteFuzzyGreaterEqual(u, 0.0, eps) ||
59  !MooseUtils::absoluteFuzzyLessEqual(u, 1.0, eps))
60  return false;
61 
62  // (d) Compute barycentric coordinate v and check 0 <= v and u + v <= 1
63  const Point qvec = tvec.cross(edge1);
64  const Real v = (dir * qvec) * inv_det;
65  if (!MooseUtils::absoluteFuzzyGreaterEqual(v, 0.0, eps) ||
66  !MooseUtils::absoluteFuzzyLessEqual(u + v, 1.0, eps))
67  return false;
68 
69  // (e) Locate intersection along line segment (0 <= t <= 1 constrains to a--b)
70  const Real t = (edge2 * qvec) * inv_det;
71  if (!MooseUtils::absoluteFuzzyGreaterEqual(t, 0.0, eps) ||
72  !MooseUtils::absoluteFuzzyLessEqual(t, 1.0, eps))
73  return false;
74 
75  // (f) Intersection lies inside both the triangle and the segment
76  intersect_p = a + dir * t;
77  return true;
78 }
79 
80 bool
81 Triangle::intersect(const LineSegment & line_segment) const
82 {
84  return intersect(line_segment, p);
85 }
86 
87 Ball
89 {
90  const Point centroid = (_p0 + _p1 + _p2) / 3.0;
91 
92  Real max_sq_dist = 0.0;
93  for (const auto * p : {&_p0, &_p1, &_p2})
94  {
95  const Real dist_sq = (*p - centroid).norm_sq();
96  if (dist_sq > max_sq_dist)
97  max_sq_dist = dist_sq;
98  }
99 
100  const Real radius = std::sqrt(max_sq_dist);
101  return Ball(centroid, radius);
102 }
const Point & end() const
Ending of the line segment.
Definition: LineSegment.h:90
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:50
int eps(unsigned int i, unsigned int j)
2D version
Ball primitive: a circle in 2D or a sphere in 3D.
Definition: Ball.h:34
const Real radius
auto norm_sq(const T &a)
static constexpr Real TOLERANCE
The LineSegment class is used by the LineMaterialSamplerBase class and for some ray tracing stuff...
Definition: LineSegment.h:30
Ball computeBoundingBall() const override
Compute a bounding ball for this triangle.
Definition: Triangle.C:88
Triangle()=default
libMesh::Point _p2
Definition: Triangle.h:50
const Point & start() const
Beginning of the line segment.
Definition: LineSegment.h:85
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
bool intersect(const LineSegment &l, libMesh::Point &intersect_p) const
Check if a line segment intersects this triangle.
Definition: Triangle.C:35
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
libMesh::Point _p1
Definition: Triangle.h:50
libMesh::Point normal() const
Normal vector of the triangle.
Definition: Triangle.C:23
libMesh::Point _p0
Definition: Triangle.h:50