FreeFOAM The Cross-Platform CFD Toolkit
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 | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Return intersection of a line with the face
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "face.H"
30 #include <OpenFOAM/pointHit.H>
31 #include <OpenFOAM/triPointRef.H>
32 #include <OpenFOAM/line.H>
33 
34 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
35 
36 // Return potential intersection with face with a ray starting
37 // at p, direction n (does not need to be normalized)
38 // Does face-center decomposition and returns triangle intersection
39 // point closest to p.
40 
41 // In case of miss the point is the nearest point intersection of the
42 // face plane and the ray and the distance is the distance between the
43 // intersection point and the nearest point on the face
44 
46 (
47  const point& p,
48  const vector& n,
49  const pointField& meshPoints,
50  const intersection::algorithm alg,
51  const intersection::direction dir
52 ) const
53 {
54  point ctr = Foam::average(points(meshPoints));
55 
56  scalar nearestHitDist = GREAT;
57 
58  scalar nearestMissDist = GREAT;
59  bool eligible = false;
60 
61  // Initialize to miss, distance = GREAT
62  pointHit nearest(p);
63 
64  const labelList& f = *this;
65 
66  label nPoints = size();
67 
68  point nextPoint = ctr;
69 
70  for (label pI = 0; pI < nPoints; pI++)
71  {
72  nextPoint = meshPoints[f[fcIndex(pI)]];
73 
74  // Note: for best accuracy, centre point always comes last
75  //
76  pointHit curHit = triPointRef
77  (
78  meshPoints[f[pI]],
79  nextPoint,
80  ctr
81  ).ray(p, n, alg, dir);
82 
83  if (curHit.hit())
84  {
85  if (Foam::mag(curHit.distance()) < Foam::mag(nearestHitDist))
86  {
87  nearestHitDist = curHit.distance();
88  nearest.setHit();
89  nearest.setPoint(curHit.hitPoint());
90  }
91  }
92  else if (!nearest.hit())
93  {
94  // Miss and no hit yet. Update miss statistics.
95  if (curHit.eligibleMiss())
96  {
97  eligible = true;
98 
99  // Miss distance is the distance between the plane intersection
100  // point and the nearest point of the triangle
101  scalar missDist =
102  Foam::mag
103  (
104  p + curHit.distance()*n
105  - curHit.missPoint()
106  );
107 
108  if (missDist < nearestMissDist)
109  {
110  nearestMissDist = missDist;
111  nearest.setDistance(curHit.distance());
112  nearest.setPoint(curHit.missPoint());
113  }
114  }
115  }
116  }
117 
118  if (nearest.hit())
119  {
120  nearest.setDistance(nearestHitDist);
121  }
122  else
123  {
124  // Haven't hit a single face triangle
125  nearest.setMiss(eligible);
126  }
127 
128  return nearest;
129 }
130 
131 
133 (
134  const point& p,
135  const vector& q,
136  const point& ctr,
137  const pointField& meshPoints,
138  const intersection::algorithm alg,
139  const scalar tol
140 ) const
141 {
142  scalar nearestHitDist = VGREAT;
143 
144  // Initialize to miss, distance = GREAT
145  pointHit nearest(p);
146 
147  const labelList& f = *this;
148 
149  forAll(f, pI)
150  {
151  // Note: for best accuracy, centre point always comes last
152  pointHit curHit = triPointRef
153  (
154  meshPoints[f[pI]],
155  meshPoints[f[fcIndex(pI)]],
156  ctr
157  ).intersection(p, q, alg, tol);
158 
159  if (curHit.hit())
160  {
161  if (Foam::mag(curHit.distance()) < nearestHitDist)
162  {
163  nearestHitDist = Foam::mag(curHit.distance());
164  nearest.setHit();
165  nearest.setPoint(curHit.hitPoint());
166  }
167  }
168  }
169 
170  if (nearest.hit())
171  {
172  nearest.setDistance(nearestHitDist);
173  }
174 
175  return nearest;
176 }
177 
178 
180 (
181  const point& p,
182  const pointField& meshPoints
183 ) const
184 {
185  const face& f = *this;
186  point ctr = centre(meshPoints);
187 
188  // Initialize to miss, distance=GREAT
189  pointHit nearest(p);
190 
191  label nPoints = f.size();
192 
193  point nextPoint = ctr;
194 
195  for (label pI = 0; pI < nPoints; pI++)
196  {
197  nextPoint = meshPoints[f[fcIndex(pI)]];
198 
199  // Note: for best accuracy, centre point always comes last
200  //
201  triPointRef tri
202  (
203  meshPoints[f[pI]],
204  nextPoint,
205  ctr
206  );
207 
208  pointHit curHit = tri.nearestPoint(p);
209 
210  if (Foam::mag(curHit.distance()) < Foam::mag(nearest.distance()))
211  {
212  nearest.setDistance(curHit.distance());
213 
214  if (curHit.hit())
215  {
216  nearest.setHit();
217  nearest.setPoint(curHit.hitPoint());
218  }
219  else
220  {
221  // In nearest point, miss is always eligible
222  nearest.setMiss(true);
223  nearest.setPoint(curHit.missPoint());
224  }
225  }
226  }
227 
228  return nearest;
229 }
230 
231 
232 // ************************ vim: set sw=4 sts=4 et: ************************ //