https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
LineSegment Class Reference

The LineSegment class is used by the LineMaterialSamplerBase class and for some ray tracing stuff. More...

#include <LineSegment.h>

Inheritance diagram for LineSegment:
[legend]

Public Member Functions

 LineSegment ()=default
 
 LineSegment (const Point &p0, const Point &p1)
 
 ~LineSegment () override=default
 
Point closest_point (const Point &p) const
 Returns the closest point on the LineSegment to the passed in point.
 
bool closest_normal_point (const Point &p, Point &closest_p) const
 Finds the closest point on the Line determined by the Line Segments.
 
bool contains_point (const Point &p) const
 Determines whether a point is in a line segment or not.
 
bool intersect (const libMesh::Plane &pl, Point &intersect_p) const
 Check if a line segment intersects a plane, and if so, return the intersection point.
 
bool intersect (const LineSegment &l1, Point &intersect_p) const
 Check if a line segment intersects another line segment, and if so, return the intersection point.
 
bool intersect (const LineSegment &line_segment) const override
 Check if a line segment intersects another line segment, without returning the intersection point.
 
Ball computeBoundingBall () const override
 Compute a bounding ball for this line segment.
 
const Point & start () const
 Beginning of the line segment.
 
const Point & end () const
 Ending of the line segment.
 
void setStart (const Point &p0)
 Sets the beginning of the line segment.
 
void setEnd (const Point &p1)
 Sets the end of the line segment.
 
void set (const Point &p0, const Point &p1)
 Sets the points on the line segment.
 
Real length () const
 Length of segment.
 
Point normal () const
 normal vector of the line segment
 

Private Member Functions

bool closest_point (const Point &p, bool clamp_to_segment, Point &closest_p) const
 

Private Attributes

Point _p0
 
Point _p1
 

Detailed Description

The LineSegment class is used by the LineMaterialSamplerBase class and for some ray tracing stuff.

Definition at line 30 of file LineSegment.h.

Constructor & Destructor Documentation

◆ LineSegment() [1/2]

LineSegment::LineSegment ( )
default

◆ LineSegment() [2/2]

LineSegment::LineSegment ( const Point &  p0,
const Point &  p1 
)

Definition at line 18 of file LineSegment.C.

18: _p0(p0), _p1(p1) {}

◆ ~LineSegment()

LineSegment::~LineSegment ( )
overridedefault

Member Function Documentation

◆ closest_normal_point()

bool LineSegment::closest_normal_point ( const Point &  p,
Point &  closest_p 
) const

Finds the closest point on the Line determined by the Line Segments.

Returns a boolean indicating whether that normal point is within the LineSegment or not

Definition at line 54 of file LineSegment.C.

55{
56 return closest_point(p, false, closest_p);
57}
Point closest_point(const Point &p) const
Returns the closest point on the LineSegment to the passed in point.
Definition LineSegment.C:46

◆ closest_point() [1/2]

Point LineSegment::closest_point ( const Point &  p) const

Returns the closest point on the LineSegment to the passed in point.

Note that the closest point may be one of the ends of the LineSegment.

Definition at line 46 of file LineSegment.C.

47{
48 Point closest_p;
49 closest_point(p, true, closest_p);
50 return closest_p;
51}

Referenced by closest_normal_point(), closest_point(), and contains_point().

◆ closest_point() [2/2]

bool LineSegment::closest_point ( const Point &  p,
bool  clamp_to_segment,
Point &  closest_p 
) const
private

Definition at line 21 of file LineSegment.C.

22{
23 Point p0_p = p - _p0;
24 Point p0_p1 = _p1 - _p0;
25 Real p0_p1_2 = p0_p1.norm_sq();
26 Real perp = p0_p(0) * p0_p1(0) + p0_p(1) * p0_p1(1) + p0_p(2) * p0_p1(2);
27 Real t = perp / p0_p1_2;
28 bool on_segment = true;
29
30 if (t < 0.0 || t > 1.0)
31 on_segment = false;
32
33 if (clamp_to_segment)
34 {
35 if (t < 0.0)
36 t = 0.0;
37 else if (t > 1.0)
38 t = 1.0;
39 }
40
41 closest_p = _p0 + p0_p1 * t;
42 return on_segment;
43}
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ computeBoundingBall()

Ball LineSegment::computeBoundingBall ( ) const
overridevirtual

Compute a bounding ball for this line segment.

The ball is defined by the midpoint of the segment and a radius equal to half the segment length.

Implements GeometryBase.

Reimplemented in SurfaceEdge2.

Definition at line 302 of file LineSegment.C.

303{
304 const Point center = 0.5 * (_p0 + _p1);
305 const Real radius = 0.5 * (_p1 - _p0).norm();
306 return Ball(center, radius);
307}
Point center
Definition MortarUtils.C:58
Ball primitive: a circle in 2D or a sphere in 3D.
Definition Ball.h:35
auto norm(const T &a)
const Real radius

Referenced by SurfaceEdge2::computeBoundingBall().

◆ contains_point()

bool LineSegment::contains_point ( const Point &  p) const

Determines whether a point is in a line segment or not.

Definition at line 60 of file LineSegment.C.

61{
62 Point closest_p;
63 return closest_point(p, false, closest_p) && closest_p.absolute_fuzzy_equals(p);
64}

Referenced by intersect(), and Moose::sideIntersectedByLine().

◆ end()

const Point & LineSegment::end ( ) const
inline

Ending of the line segment.

Definition at line 90 of file LineSegment.h.

90{ return _p1; }

Referenced by dataStore(), IntersectionPointsAlongLine::execute(), Ball::intersect(), Moose::recursivelyFindElementsIntersectedByLine(), and to_json().

◆ intersect() [1/3]

bool LineSegment::intersect ( const libMesh::Plane pl,
Point &  intersect_p 
) const

Check if a line segment intersects a plane, and if so, return the intersection point.

There are three cases in 3D for intersection of a line and a plane Case 1: The line is parallel to the plane - No intersection Numerator = non-zero Denominator = zero

Case 2: The line is within the plane - Inf intersection Numerator = zero Denominator = zero

Case 3: The line intersects the plane at a single point Denominator = non-zero

Definition at line 67 of file LineSegment.C.

68{
83 Point pl0 = pl.get_planar_point();
85 RealVectorValue I = (_p1 - _p0).unit();
86
87 Real numerator = (pl0 - _p0) * N;
88 Real denominator = I * N;
89
90 // The Line is parallel to the plane
91 if (std::abs(denominator) < 1.e-10)
92 {
93 // The Line is on the plane
94 if (std::abs(numerator) < 1.e-10)
95 {
96 // The solution is not unique so we'll just pick an end point for now
97 intersect_p = _p0;
98 return true;
99 }
100 return false;
101 }
102
103 Real d = numerator / denominator;
104
105 // Make sure we haven't moved off the line segment!
106 if (d + libMesh::TOLERANCE < 0 || d - libMesh::TOLERANCE > (_p1 - _p0).norm())
107 return false;
108
109 intersect_p = d * I + _p0;
110
111 return true;
112}
const Point & get_planar_point() const
virtual Point unit_normal(const Point &p) const override
VectorValue< Real > RealVectorValue
Definition SubProblem.h:34

Referenced by intersect(), SurfaceEdge2::intersect(), and Moose::sideIntersectedByLine().

◆ intersect() [2/3]

bool LineSegment::intersect ( const LineSegment l1,
Point &  intersect_p 
) const

Check if a line segment intersects another line segment, and if so, return the intersection point.

First check for concurance:

| x1 y1 z1 1 | | x2 y2 z2 1 | = (x3 - x1) * [(x2-x1) x (x4-x3)] = 0 | x3 y3 z3 1 | | x4 y4 z4 1 |

Solve: x = _p0 + (_p1 - _p0)*s x = l.p0 + (l._p1 - l.p0)*t

where a = _p1 - _p0 b = l._p1 - l._p0 c = l._p0 - _p0

s = (c x b) * (a x b) / | a x b |^2

 Parameteric Equation of lines
 _p0 + t(v0) = l._p0 + u(v1)

 Case 1: Parallel Lines
         v0 x v1 == 0

 Case 1a: Collinear Lines
         v0 x v1 == 0
         (l._p0 - _p0) x (_p1 - _p0) == 0

 Case 2: Intersecting Lines
         0 <= t <= 1
         0 <= u <= 1


 Case 1: The lines do not intersect
         vleft cross vright = non-zero

 Case 2: The lines are co-linear
         vleft cross vright = zero
         vleft (Denominator) = zero

 Case 3: The line intersect at a single point
         vleft cross vright = zero
         vleft (Denominator) = non-zero

RealVectorValue v0 = _p1 - _p0; RealVectorValue v1 = l._p1 - l._p0; RealVectorValue v2 = l._p0 - _p0;

RealVectorValue vbot = v0.cross(v1); RealVectorValue vtop = v2.cross(v1);

RealVectorValue crossed = vleft.cross(vright);

Case 1: No intersection if (std::abs(vleft.cross(vright).size()) > 1.e-10) return false;

Case 2: Co-linear (just return one of the end points) if (std::abs(vleft.size()) < 1.e-10) { intersect_p = _p0; return true; }

Case 3:

TODO: We could detect whether the Line Segments actually overlap instead of whether the Lines are co-linear

Real a = vright.size()/vleft.size(); intersect_p = _p0 + a*v0; return true;

Definition at line 115 of file LineSegment.C.

116{
138 RealVectorValue a = _p1 - _p0;
139 RealVectorValue b = l._p1 - l._p0;
140 RealVectorValue c = l._p0 - _p0;
141
142 RealVectorValue v = a.cross(b);
143
144 const auto tol = 1.e-10;
145
146 // Parallel lines check
147 if (v.norm() < tol)
148 {
149 // Parallel but not collinear: no intersection
150 if (c.cross(a).norm() >= tol)
151 return false;
152
153 // Collinear: segments overlap if any endpoint lies on the other segment
154 const bool overlap = this->contains_point(l._p0) || this->contains_point(l._p1) ||
155 l.contains_point(_p0) || l.contains_point(_p1);
156
157 if (!overlap)
158 return false;
159
160 // Pick a deterministic intersection point on the overlap
161 if (this->contains_point(l._p0))
162 intersect_p = l._p0;
163 else if (this->contains_point(l._p1))
164 intersect_p = l._p1;
165 else if (l.contains_point(_p0))
166 intersect_p = _p0;
167 else
168 intersect_p = _p1;
169
170 return true;
171 }
172
173 // Check that the lines are coplanar
174 Real concur = c * (a.cross(b));
175 if (std::abs(concur) > 1.e-10)
176 return false;
177
178 Real s = (c.cross(b) * v) / (v * v);
179 Real t = (c.cross(a) * v) / (v * v);
180
181 // if s and t are between 0 and 1 then the Line Segments intersect
182 // TODO: We could handle other case of clamping to the end of Line
183 // Segements if we want to here
184
185 if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
186 {
187 intersect_p = _p0 + s * a;
188 return true;
189 }
190 return false;
191
247}
bool contains_point(const Point &p) const
Determines whether a point is in a line segment or not.
Definition LineSegment.C:60
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const

◆ intersect() [3/3]

bool LineSegment::intersect ( const LineSegment line_segment) const
overridevirtual

Check if a line segment intersects another line segment, without returning the intersection point.

Implements GeometryBase.

Reimplemented in SurfaceEdge2, and SurfaceEdge2.

Definition at line 250 of file LineSegment.C.

251{
252 Point p;
253 return intersect(line_segment, p);
254}
bool intersect(const libMesh::Plane &pl, Point &intersect_p) const
Check if a line segment intersects a plane, and if so, return the intersection point.
Definition LineSegment.C:67

◆ length()

Real LineSegment::length ( ) const
inline

Length of segment.

Definition at line 112 of file LineSegment.h.

112{ return (_p0 - _p1).norm(); }

◆ normal()

Point LineSegment::normal ( ) const

normal vector of the line segment

Definition at line 288 of file LineSegment.C.

289{
290 const auto tangent = _p1 - _p0;
291
292 // Rotate 90 degrees counter-clockwise (2D)
293 Point n(-tangent(1), tangent(0), 0.0);
294 const Real norm = n.norm();
295 if (norm == 0.0)
296 mooseError("LineSegment: cannot compute the normal of a zero-length line segment.");
297
298 return n / norm;
299}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311

◆ set()

void LineSegment::set ( const Point &  p0,
const Point &  p1 
)

Sets the points on the line segment.

Parameters
p0The start point of the line segment
p1The end point of the line segment

Definition at line 257 of file LineSegment.C.

258{
259 setStart(p0);
260 setEnd(p1);
261}
void setStart(const Point &p0)
Sets the beginning of the line segment.
Definition LineSegment.h:95
void setEnd(const Point &p1)
Sets the end of the line segment.

Referenced by dataLoad().

◆ setEnd()

void LineSegment::setEnd ( const Point &  p1)
inline

Sets the end of the line segment.

Definition at line 100 of file LineSegment.h.

100{ _p1 = p1; }

Referenced by set().

◆ setStart()

void LineSegment::setStart ( const Point &  p0)
inline

Sets the beginning of the line segment.

Definition at line 95 of file LineSegment.h.

95{ _p0 = p0; }

Referenced by set().

◆ start()

const Point & LineSegment::start ( ) const
inline

Beginning of the line segment.

Definition at line 85 of file LineSegment.h.

85{ return _p0; }

Referenced by dataStore(), Ball::intersect(), and to_json().

Member Data Documentation

◆ _p0

Point LineSegment::_p0
private

◆ _p1

Point LineSegment::_p1
private

The documentation for this class was generated from the following files: