https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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#include "MooseError.h"
13
14#include <cmath>
15
16using libMesh::Point;
17using libMesh::Real;
18
19Triangle::Triangle(const Point & p0, const Point & p1, const Point & p2) : _p0(p0), _p1(p1), _p2(p2)
20{
21}
22
25{
26 const auto v1 = _p1 - _p0;
27 const auto v2 = _p2 - _p0;
28
29 const auto n = v1.cross(v2);
30 const Real norm = n.norm();
31 if (norm == 0.0)
32 mooseError("Triangle: cannot compute the normal of a degenerate triangle.");
33
34 return n / norm;
35}
36
37bool
38Triangle::intersect(const LineSegment & line_segment, Point & intersect_p) const
39{
40 const auto & a = line_segment.start();
41 const auto & b = line_segment.end();
43 // (a) Build basic vectors and choose a robust tolerance
44 const Point dir = b - a;
45
46 const Point edge1 = _p1 - _p0;
47 const Point edge2 = _p2 - _p0;
48 constexpr Real eps = libMesh::TOLERANCE;
49
50 // (b) Test for parallel or degenerate configuration
51 const Point pvec = dir.cross(edge2);
52 const Real det = edge1 * pvec;
53 if (std::abs(det) < eps)
54 return false; // ray nearly parallel to triangle
55
56 const Real inv_det = 1.0 / det;
57
58 // (c) Compute barycentric coordinate u and check 0 <= u <= 1
59 const Point tvec = a - _p0;
60 const Real u = (tvec * pvec) * inv_det;
61 if (!MooseUtils::absoluteFuzzyGreaterEqual(u, 0.0, eps) ||
62 !MooseUtils::absoluteFuzzyLessEqual(u, 1.0, eps))
63 return false;
64
65 // (d) Compute barycentric coordinate v and check 0 <= v and u + v <= 1
66 const Point qvec = tvec.cross(edge1);
67 const Real v = (dir * qvec) * inv_det;
68 if (!MooseUtils::absoluteFuzzyGreaterEqual(v, 0.0, eps) ||
69 !MooseUtils::absoluteFuzzyLessEqual(u + v, 1.0, eps))
70 return false;
71
72 // (e) Locate intersection along line segment (0 <= t <= 1 constrains to a--b)
73 const Real t = (edge2 * qvec) * inv_det;
74 if (!MooseUtils::absoluteFuzzyGreaterEqual(t, 0.0, eps) ||
75 !MooseUtils::absoluteFuzzyLessEqual(t, 1.0, eps))
76 return false;
77
78 // (f) Intersection lies inside both the triangle and the segment
79 intersect_p = a + dir * t;
80 return true;
81}
82
83bool
84Triangle::intersect(const LineSegment & line_segment) const
85{
87 return intersect(line_segment, p);
88}
89
90Ball
92{
93 const Point centroid = (_p0 + _p1 + _p2) / 3.0;
94
95 Real max_sq_dist = 0.0;
96 for (const auto * p : {&_p0, &_p1, &_p2})
97 {
98 const Real dist_sq = (*p - centroid).norm_sq();
99 if (dist_sq > max_sq_dist)
100 max_sq_dist = dist_sq;
101 }
102
103 const Real radius = std::sqrt(max_sq_dist);
104 return Ball(centroid, radius);
105}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Ball primitive: a circle in 2D or a sphere in 3D.
Definition Ball.h:35
The LineSegment class is used by the LineMaterialSamplerBase class and for some ray tracing stuff.
Definition LineSegment.h:31
const Point & end() const
Ending of the line segment.
Definition LineSegment.h:90
const Point & start() const
Beginning of the line segment.
Definition LineSegment.h:85
libMesh::Point _p2
Definition Triangle.h:50
libMesh::Point _p0
Definition Triangle.h:50
libMesh::Point normal() const
Normal vector of the triangle.
Definition Triangle.C:24
bool intersect(const LineSegment &l, libMesh::Point &intersect_p) const
Check if a line segment intersects this triangle.
Definition Triangle.C:38
Ball computeBoundingBall() const override
Compute a bounding ball for this triangle.
Definition Triangle.C:91
Triangle()=default
libMesh::Point _p1
Definition Triangle.h:50
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real radius