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
16Triangle::Triangle(const Point & p0, const Point & p1, const Point & p2) : _p0(p0), _p1(p1), _p2(p2)
17{
18}
19
20Point
22{
23 const auto v1 = _p1 - _p0;
24 const auto v2 = _p2 - _p0;
25
26 const auto n = v1.cross(v2);
27 const Real norm = n.norm();
28 if (norm == 0.0)
29 mooseError("Triangle: cannot compute the normal of a degenerate triangle.");
30
31 return n / norm;
32}
33
34bool
35Triangle::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;
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
80bool
81Triangle::intersect(const LineSegment & line_segment) const
82{
84 return intersect(line_segment, p);
85}
86
87Ball
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}
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:21
bool intersect(const LineSegment &l, libMesh::Point &intersect_p) const
Check if a line segment intersects this triangle.
Ball computeBoundingBall() const override
Compute a bounding ball for this triangle.
Definition Triangle.C:88
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
const Real radius