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-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "face.H"
29#include "pointHit.H"
30#include "triPointRef.H"
31#include "line.H"
32
33// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
34
36(
37 const point& p,
38 const vector& n,
39 const UList<point>& meshPoints,
42) const
43{
44 // Return potential intersection with face with a ray starting
45 // at p, direction n (does not need to be normalized)
46 // Does face-center decomposition and returns triangle intersection
47 // point closest to p.
48
49 // In case of miss the point is the nearest point intersection of the
50 // face plane and the ray and the distance is the distance between the
51 // intersection point and the nearest point on the face
52
53 // If the face is a triangle, do a direct calculation
54 if (size() == 3)
55 {
56 return triPointRef
57 (
58 meshPoints[operator[](0)],
59 meshPoints[operator[](1)],
60 meshPoints[operator[](2)]
61 ).ray(p, n, alg, dir);
62 }
63
64 point ctr = Foam::average(points(meshPoints));
65
66 scalar nearestHitDist = GREAT;
67 scalar nearestMissDist = GREAT;
68 bool eligible = false;
69
70 // Initialize to miss, distance = GREAT
71 pointHit nearest(p);
72
73 const labelList& f = *this;
74
75 const label nPoints = size();
76
77 point nextPoint = ctr;
78
79 for (label pI = 0; pI < nPoints; pI++)
80 {
81 nextPoint = meshPoints[f[fcIndex(pI)]];
82
83 // Note: for best accuracy, centre point always comes last
84 //
85 pointHit curHit = triPointRef
86 (
87 meshPoints[f[pI]],
88 nextPoint,
89 ctr
90 ).ray(p, n, alg, dir);
91
92 if (curHit.hit())
93 {
94 if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
95 {
96 nearestHitDist = curHit.distance();
97 nearest.setHit();
98 nearest.setPoint(curHit.hitPoint());
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 =
112 (
113 p + curHit.distance()*n
114 - curHit.missPoint()
115 );
116
117 if (missDist < nearestMissDist)
118 {
119 nearestMissDist = missDist;
120 nearest.setDistance(curHit.distance());
121 nearest.setPoint(curHit.missPoint());
122 }
123 }
124 }
125 }
126
127 if (nearest.hit())
128 {
129 nearest.setDistance(nearestHitDist);
130 }
131 else
132 {
133 // Haven't hit a single face triangle
134 nearest.setMiss(eligible);
135 }
136
137 return nearest;
138}
139
140
142(
143 const point& p,
144 const vector& q,
145 const point& ctr,
146 const UList<point>& meshPoints,
147 const intersection::algorithm alg,
148 const scalar tol
149) const
150{
151 // If the face is a triangle, do a direct calculation
152 if (size() == 3)
153 {
154 return triPointRef
155 (
156 meshPoints[operator[](0)],
157 meshPoints[operator[](1)],
158 meshPoints[operator[](2)]
159 ).intersection(p, q, alg, tol);
160 }
161
162 scalar nearestHitDist = VGREAT;
163
164 // Initialize to miss, distance = GREAT
165 pointHit nearest(p);
166
167 const labelList& f = *this;
168
169 forAll(f, pI)
170 {
171 // Note: for best accuracy, centre point always comes last
172 pointHit curHit = triPointRef
173 (
174 meshPoints[f[pI]],
175 meshPoints[f[fcIndex(pI)]],
176 ctr
177 ).intersection(p, q, alg, tol);
178
179 if (curHit.hit())
180 {
181 if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
182 {
183 nearestHitDist = curHit.distance();
184 nearest.setHit();
185 nearest.setPoint(curHit.hitPoint());
186 }
187 }
188 }
189
190 if (nearest.hit())
191 {
192 nearest.setDistance(nearestHitDist);
193 }
194
195 return nearest;
196}
197
198
200(
201 const point& p,
202 const UList<point>& meshPoints
203) const
204{
205 // Dummy labels
206 label nearType = -1;
207 label nearLabel = -1;
208
209 return nearestPointClassify(p, meshPoints, nearType, nearLabel);
210}
211
212
214(
215 const point& p,
216 const UList<point>& meshPoints,
217 label& nearType,
218 label& nearLabel
219) const
220{
221 // If the face is a triangle, do a direct calculation
222 if (size() == 3)
223 {
224 return triPointRef
225 (
226 meshPoints[operator[](0)],
227 meshPoints[operator[](1)],
228 meshPoints[operator[](2)]
229 ).nearestPointClassify(p, nearType, nearLabel);
230 }
231
232 const face& f = *this;
233 point ctr = centre(meshPoints);
234
235 // Initialize to miss, distance=GREAT
236 pointHit nearest(p);
237
238 nearType = -1;
239 nearLabel = -1;
240
241 const label nPoints = f.size();
242
243 point nextPoint = ctr;
244
245 for (label pI = 0; pI < nPoints; pI++)
246 {
247 nextPoint = meshPoints[f[fcIndex(pI)]];
248
249 label tmpNearType = -1;
250 label tmpNearLabel = -1;
251
252 // Note: for best accuracy, centre point always comes last
253 triPointRef tri
254 (
255 meshPoints[f[pI]],
256 nextPoint,
257 ctr
258 );
259
260 pointHit curHit = tri.nearestPointClassify
261 (
262 p,
263 tmpNearType,
264 tmpNearLabel
265 );
266
267 if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
268 {
269 nearest.setDistance(curHit.distance());
270
271 // Assume at first that the near type is NONE on the
272 // triangle (i.e. on the face of the triangle) then it is
273 // therefore also for the face.
274
275 nearType = NONE;
276
277 if (tmpNearType == triPointRef::EDGE && tmpNearLabel == 0)
278 {
279 // If the triangle edge label is 0, then this is also
280 // an edge of the face, if not, it is on the face
281
282 nearType = EDGE;
283
284 nearLabel = pI;
285 }
286 else if (tmpNearType == triPointRef::POINT && tmpNearLabel < 2)
287 {
288 // If the triangle point label is 0 or 1, then this is
289 // also a point of the face, if not, it is on the face
290
291 nearType = POINT;
292
293 nearLabel = pI + tmpNearLabel;
294 }
295
296 if (curHit.hit())
297 {
298 nearest.setHit();
299 nearest.setPoint(curHit.hitPoint());
300 }
301 else
302 {
303 // In nearest point, miss is always eligible
304 nearest.setMiss(true);
305 nearest.setPoint(curHit.missPoint());
306 }
307 }
308 }
309
310 return nearest;
311}
312
313
315(
316 const point& p,
317 const UList<point>& points,
318 const scalar tol
319) const
320{
321 // Take three points [0, 1/3, 2/3] from the face
322 // - assumes the face is not severely warped
323
324 return triPointRef
325 (
326 points[operator[](0)],
327 points[operator[](size()/3)],
328 points[operator[]((2*size())/3)]
329 ).sign(p, tol);
330}
331
332
333// ************************************************************************* //
label n
Describes the interaction of a face and a point. It carries the info of a successful hit and (if succ...
Definition: PointHit.H:54
void setHit() noexcept
Set the hit status on.
Definition: PointHit.H:181
bool eligibleMiss() const noexcept
Is this an eligible miss.
Definition: PointHit.H:127
scalar distance() const noexcept
Return distance to hit.
Definition: PointHit.H:139
void setPoint(const point_type &p)
Set the point.
Definition: PointHit.H:195
void setDistance(const scalar d) noexcept
Set the distance.
Definition: PointHit.H:201
const point_type & missPoint() const
Return the miss point. Fatal if hit.
Definition: PointHit.H:158
bool hit() const noexcept
Is there a hit.
Definition: PointHit.H:121
void setMiss(const bool eligible) noexcept
Set the hit status off and set the eligible miss status.
Definition: PointHit.H:188
const point_type & hitPoint() const
Return the hit point. Fatal if not hit.
Definition: PointHit.H:145
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:94
label size() const noexcept
The number of elements in the UList.
Definition: UListI.H:420
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label fcIndex(const label i) const noexcept
Definition: UListI.H:60
friend complex sign(const complex &c)
sgn() https://en.wikipedia.org/wiki/Sign_function#Complex_signum
Definition: complexI.H:228
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
pointHit nearestPointClassify(const point &p, const UList< point > &meshPoints, label &nearType, label &nearLabel) const
Return nearest point to face and classify it:
pointHit nearestPoint(const point &p, const UList< point > &meshPoints) const
Return nearest point to face.
Foam::intersection.
Definition: intersection.H:53
A reference point and direction.
Definition: plane.H:110
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:80
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:522
@ POINT
Close to point.
Definition: triangle.H:96
@ EDGE
Close to edge.
Definition: triangle.H:97
volScalarField & p
const pointField & points
label nPoints
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangle.H:71
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333