Loading...
Searching...
No Matches
faceIntersection.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "face.H"
30#include "pointHit.H"
31#include "triangle.H"
32#include "line.H"
33
34// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35
37(
38 const point& p,
39 const vector& n,
40 const UList<point>& meshPoints,
43) const
44{
45 // Return potential intersection with face with a ray starting
46 // at p, direction n (does not need to be normalized)
47 // Does face-center decomposition and returns triangle intersection
48 // point closest to p.
49
50 // In case of miss the point is the nearest point intersection of the
51 // face plane and the ray and the distance is the distance between the
52 // intersection point and the nearest point on the face
53
54 // If the face is a triangle, do a direct calculation
55 if (size() == 3)
56 {
57 return triPointRef
58 (
59 meshPoints[operator[](0)],
60 meshPoints[operator[](1)],
61 meshPoints[operator[](2)]
62 ).ray(p, n, alg, dir);
63 }
64
65 point ctr = Foam::average(points(meshPoints));
66
67 scalar nearestHitDist = GREAT;
68 scalar nearestMissDist = GREAT;
69 bool eligible = false;
70
71 // Initialize to miss, distance = GREAT
72 pointHit nearest(p);
73
74 const labelList& f = *this;
75
76 const label nPoints = size();
77
78 point nextPoint = ctr;
79
80 for (label pI = 0; pI < nPoints; pI++)
81 {
82 nextPoint = meshPoints[f[fcIndex(pI)]];
83
84 // Note: for best accuracy, centre point always comes last
85 //
86 pointHit curHit = triPointRef
87 (
88 meshPoints[f[pI]],
89 nextPoint,
90 ctr
91 ).ray(p, n, alg, dir);
92
93 if (curHit.hit())
94 {
95 if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
96 {
97 nearestHitDist = curHit.distance();
98 nearest.hitPoint(curHit.point());
99 }
100 }
101 else if (!nearest.hit())
102 {
103 // Miss and no hit yet. Update miss statistics.
104 if (curHit.eligibleMiss())
105 {
106 eligible = true;
107
108 // Miss distance is the distance between the plane intersection
109 // point and the nearest point of the triangle
110 scalar missDist = curHit.point().dist(p + curHit.distance()*n);
111
112 if (missDist < nearestMissDist)
113 {
114 nearestMissDist = missDist;
115 nearest.setDistance(curHit.distance());
116 nearest.setPoint(curHit.point());
117 }
118 }
119 }
120 }
121
122 if (nearest.hit())
123 {
124 nearest.setDistance(nearestHitDist);
125 }
126 else
127 {
128 // Haven't hit a single face triangle
129 nearest.setMiss(eligible);
130 }
131
132 return nearest;
133}
134
135
137(
138 const point& p,
139 const vector& q,
140 const point& ctr,
141 const UList<point>& meshPoints,
142 const intersection::algorithm alg,
143 const scalar tol
144) const
145{
146 // If the face is a triangle, do a direct calculation
147 if (size() == 3)
148 {
149 return triPointRef
150 (
151 meshPoints[operator[](0)],
152 meshPoints[operator[](1)],
153 meshPoints[operator[](2)]
154 ).intersection(p, q, alg, tol);
155 }
156
157 scalar nearestHitDist = VGREAT;
158
159 // Initialize to miss, distance = GREAT
160 pointHit nearest(p);
161
162 const labelList& f = *this;
163
164 forAll(f, pI)
165 {
166 // Note: for best accuracy, centre point always comes last
167 pointHit curHit = triPointRef
168 (
169 meshPoints[f[pI]],
170 meshPoints[f[fcIndex(pI)]],
171 ctr
172 ).intersection(p, q, alg, tol);
173
174 if (curHit.hit())
175 {
176 if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
177 {
178 nearestHitDist = curHit.distance();
179 nearest.hitPoint(curHit.point());
180 }
181 }
182 }
183
184 if (nearest.hit())
185 {
186 nearest.setDistance(nearestHitDist);
187 }
188
189 return nearest;
190}
191
192
194(
195 const point& p,
196 const UList<point>& meshPoints
197) const
198{
199 // Dummy labels
200 label nearType = -1;
201 label nearLabel = -1;
202
203 return nearestPointClassify(p, meshPoints, nearType, nearLabel);
204}
205
206
208(
209 const point& p,
210 const UList<point>& meshPoints,
211 label& nearType,
212 label& nearLabel
213) const
214{
215 // If the face is a triangle, do a direct calculation
216 if (size() == 3)
217 {
218 return triPointRef
219 (
220 meshPoints[operator[](0)],
221 meshPoints[operator[](1)],
222 meshPoints[operator[](2)]
223 ).nearestPointClassify(p, nearType, nearLabel);
224 }
225
226 const face& f = *this;
227 point ctr = centre(meshPoints);
228
229 // Initialize to miss, distance=GREAT
230 pointHit nearest(p);
231
232 nearType = -1;
233 nearLabel = -1;
234
235 const label nPoints = f.size();
236
237 point nextPoint = ctr;
238
239 for (label pI = 0; pI < nPoints; pI++)
240 {
241 nextPoint = meshPoints[f[fcIndex(pI)]];
242
243 label tmpNearType = -1;
244 label tmpNearLabel = -1;
245
246 // Note: for best accuracy, centre point always comes last
247 triPointRef tri
248 (
249 meshPoints[f[pI]],
250 nextPoint,
251 ctr
252 );
253
254 pointHit curHit = tri.nearestPointClassify
255 (
256 p,
257 tmpNearType,
258 tmpNearLabel
259 );
260
261 if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
262 {
263 nearest.setDistance(curHit.distance());
264
265 // Assume at first that the near type is NONE on the
266 // triangle (i.e. on the face of the triangle) then it is
267 // therefore also for the face.
268
269 nearType = NONE;
270
271 if (tmpNearType == triPointRef::EDGE && tmpNearLabel == 0)
272 {
273 // If the triangle edge label is 0, then this is also
274 // an edge of the face, if not, it is on the face
275
276 nearType = EDGE;
277
278 nearLabel = pI;
279 }
280 else if (tmpNearType == triPointRef::POINT && tmpNearLabel < 2)
281 {
282 // If the triangle point label is 0 or 1, then this is
283 // also a point of the face, if not, it is on the face
284
285 nearType = POINT;
286
287 nearLabel = pI + tmpNearLabel;
288 }
289
290 if (curHit.hit())
291 {
292 nearest.hitPoint(curHit.point());
293 }
294 else
295 {
296 // In nearest point, miss is always eligible
297 nearest.setMiss(true);
298 nearest.setPoint(curHit.point());
299 }
301 }
302
303 return nearest;
304}
305
306
308(
309 const point& p,
310 const UList<point>& points,
311 const scalar tol
312) const
313{
314 // Take three points [0, 1/3, 2/3] from the face
315 // - assumes the face is not severely warped
316
317 return triPointRef
318 (
319 points[operator[](0)],
320 points[operator[](size()/3)],
321 points[operator[]((2*size())/3)]
322 ).sign(p, tol);
323}
324
325
326// ************************************************************************* //
label n
bool eligibleMiss() const noexcept
Is this an eligible miss.
Definition pointHit.H:153
scalar distance() const noexcept
Return distance to hit.
Definition pointHit.H:169
void setPoint(const point_type &p)
Set the point.
Definition pointHit.H:235
void setDistance(const scalar d) noexcept
Set the distance.
Definition pointHit.H:243
bool hit() const noexcept
Is there a hit.
Definition pointHit.H:145
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition pointHit.H:226
const point_type & point() const noexcept
Return the point, no checks.
Definition pointHit.H:161
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition pointHit.H:177
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
label size() const noexcept
Definition UList.H:706
void size(const label n)
Definition UList.H:118
label fcIndex(const label i) const noexcept
scalar dist(const Vector< Cmpt > &v2) const
The L2-norm distance from another vector. The mag() of the difference.
Definition VectorI.H:107
pointHit ray(const point &p, const vector &n, const UList< point > &meshPoints, const intersection::algorithm alg=intersection::FULL_RAY, const intersection::direction dir=intersection::VECTOR) const
Return potential intersection with face with a ray starting at p, direction n (does not need to be no...
pointHit nearestPointClassify(const point &p, const UList< point > &meshPoints, label &nearType, label &nearLabel) const
Return nearest point to face and classify it:
pointHit intersection(const point &p, const vector &q, const point &ctr, const UList< point > &meshPoints, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
@ POINT
Close to point.
Definition face.H:130
@ EDGE
Close to edge.
Definition face.H:131
@ NONE
Unknown proximity.
Definition face.H:129
pointHit nearestPoint(const point &p, const UList< point > &meshPoints) const
Return nearest point to face.
point centre(const UList< point > &points) const
Centre point of face.
Definition face.C:506
pointField points(const UList< point > &pts) const
Return the points corresponding to this face.
Definition faceI.H:80
int sign(const point &p, const UList< point > &points, const scalar tol=SMALL) const
The sign for the side of the face plane the point is on, using three evenly distributed face points f...
constexpr face() noexcept=default
Default construct.
pointHit nearestPointClassify(const point &p, label &nearType, label &nearLabel) const
Find the nearest point to p on the triangle and classify it:
Definition triangleI.H:754
pointHit ray(const point &p, const vector &q, const intersection::algorithm=intersection::FULL_RAY, const intersection::direction dir=intersection::VECTOR) const
Return point intersection with a ray.
Definition triangleI.H:557
pointHit intersection(const point &p, const vector &q, const intersection::algorithm alg, const scalar tol=0.0) const
Fast intersection with a ray.
Definition triangleI.H:672
int sign(const point &p, const scalar tol=SMALL) const
The sign for which side of the face plane the point is on.
Definition triangleI.H:1053
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
volScalarField & p
const pointField & points
label nPoints
PointHit< point > pointHit
A PointHit with a 3D point.
Definition pointHit.H:51
List< label > labelList
A List of labels.
Definition List.H:62
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vector point
Point is a vector.
Definition point.H:37
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition triangleFwd.H:46
Vector< scalar > vector
Definition vector.H:57
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &f1, const label comm)
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299