Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
PointTriangle.h
Go to the documentation of this file.
1/** @file PointTriangle.h
2 */
3#define vecdot(a,b) ((a).x*(b).x + (a).y*(b).y + (a).z*(b).z)
4#define vecdotproduct(a,b) ((coord){(a).y*(b).z - (a).z*(b).y, \
5 (a).z*(b).x - (a).x*(b).z, \
6 (a).x*(b).y - (a).y*(b).x})
7#define vecdiff(a,b) ((coord){(a).x - (b).x, (a).y - (b).y, (a).z - (b).z})
8#define vecdist2(a,b) (sq((a).x - (b).x) + sq((a).y - (b).y) + sq((a).z - (b).z))
9
10/**
11 * Returns the squared distance between point P and triangle P0, P1,
12 * P2. Squared distance is returned in d2. s and t returns the
13 * closest point in parametric form in terms of edges P0P1 and P0P2.
14 */
16 const coord * P0,
17 const coord * P1,
18 const coord * P2,
19 double * s, double * t)
20{
21 // From http://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf
22 double d2;
23 coord diff = vecdiff (*P0, *P);
24 coord edge0 = vecdiff(*P1, *P0);
25 coord edge1 = vecdiff(*P2, *P0);
26 double a00 = vecdot(edge0, edge0);
27 double a01 = vecdot(edge0, edge1);
28 double a11 = vecdot(edge1, edge1);
29 double b0 = vecdot(diff, edge0);
30 double b1 = vecdot(diff, edge1);
31 double c = vecdot(diff, diff);
32 double det = fabs(a00*a11 - a01*a01);
33 *s = a01*b1 - a11*b0;
34 *t = a01*b0 - a00*b1;
35
36 if (*s + *t <= det)
37 {
38 if (*s < 0.0)
39 {
40 if (*t < 0.0) // region 4
41 {
42 if (b0 < 0.0)
43 {
44 *t = 0.0;
45 if (-b0 >= a00)
46 {
47 *s = 1.0;
48 d2 = a00 + 2.0*b0 + c;
49 }
50 else
51 {
52 *s = -b0/a00;
53 d2 = b0**s + c;
54 }
55 }
56 else
57 {
58 *s = 0.0;
59 if (b1 >= 0.0)
60 {
61 *t = 0.0;
62 d2 = c;
63 }
64 else if (-b1 >= a11)
65 {
66 *t = 1.0;
67 d2 = a11 + 2.0*b1 + c;
68 }
69 else
70 {
71 *t = -b1/a11;
72 d2 = b1**t + c;
73 }
74 }
75 }
76 else // region 3
77 {
78 *s = 0.0;
79 if (b1 >= 0.0)
80 {
81 *t = 0.0;
82 d2 = c;
83 }
84 else if (-b1 >= a11)
85 {
86 *t = 1.0;
87 d2 = a11 + 2.0*b1 + c;
88 }
89 else
90 {
91 *t = -b1/a11;
92 d2 = b1**t + c;
93 }
94 }
95 }
96 else if (*t < 0.0) // region 5
97 {
98 *t = 0.0;
99 if (b0 >= 0.0)
100 {
101 *s = 0.0;
102 d2 = c;
103 }
104 else if (-b0 >= a00)
105 {
106 *s = 1.0;
107 d2 = a00 + 2.0*b0 + c;
108 }
109 else
110 {
111 *s = -b0/a00;
112 d2 = b0**s + c;
113 }
114 }
115 else // region 0
116 {
117 if (det == 0.) // degenerate triangle
118 d2 = HUGE;
119 else {
120 double invDet = 1.0/det;
121 *s *= invDet;
122 *t *= invDet;
123 d2 = *s*(a00**s + a01**t + 2.0*b0) + *t*(a01**s + a11**t + 2.0*b1) + c;
124 }
125 }
126 }
127 else
128 {
129 if (*s < 0.0) // region 2
130 {
131 double tmp0 = a01 + b0;
132 double tmp1 = a11 + b1;
133 if (tmp1 > tmp0)
134 {
135 double numer = tmp1 - tmp0;
136 double denom = a00 - 2.0*a01 + a11;
137 if (numer >= denom)
138 {
139 *s = 1.0;
140 *t = 0.0;
141 d2 = a00 + 2.0*b0 + c;
142 }
143 else
144 {
145 *s = numer/denom;
146 *t = 1.0 - *s;
147 d2 = *s*(a00**s + a01**t + 2.0*b0) + *t*(a01**s + a11**t + 2.0*b1) + c;
148 }
149 }
150 else
151 {
152 *s = 0.0;
153 if (tmp1 <= 0.0)
154 {
155 *t = 1.0;
156 d2 = a11 + 2.0*b1 + c;
157 }
158 else if (b1 >= 0.0)
159 {
160 *t = 0.0;
161 d2 = c;
162 }
163 else
164 {
165 *t = -b1/a11;
166 d2 = b1**t + c;
167 }
168 }
169 }
170 else if (*t < 0.0) // region 6
171 {
172 double tmp0 = a01 + b1;
173 double tmp1 = a00 + b0;
174 if (tmp1 > tmp0)
175 {
176 double numer = tmp1 - tmp0;
177 double denom = a00 - 2.0*a01 + a11;
178 if (numer >= denom)
179 {
180 *t = 1.0;
181 *s = 0.0;
182 d2 = a11 + 2.0*b1 + c;
183 }
184 else
185 {
186 *t = numer/denom;
187 *s = 1.0 - *t;
188 d2 = *s*(a00**s + a01**t + 2.0*b0) + *t*(a01**s + a11**t + 2.0*b1) + c;
189 }
190 }
191 else
192 {
193 *t = 0.0;
194 if (tmp1 <= 0.0)
195 {
196 *s = 1.0;
197 d2 = a00 + 2.0*b0 + c;
198 }
199 else if (b0 >= 0.0)
200 {
201 *s = 0.0;
202 d2 = c;
203 }
204 else
205 {
206 *s = -b0/a00;
207 d2 = b0**s + c;
208 }
209 }
210 }
211 else // region 1
212 {
213 double numer = a11 + b1 - a01 - b0;
214 if (numer <= 0.0)
215 {
216 *s = 0.0;
217 *t = 1.0;
218 d2 = a11 + 2.0*b1 + c;
219 }
220 else
221 {
222 double denom = a00 - 2.0*a01 + a11;
223 if (numer >= denom)
224 {
225 *s = 1.0;
226 *t = 0.0;
227 d2 = a00 + 2.0*b0 + c;
228 }
229 else
230 {
231 *s = numer/denom;
232 *t = 1.0 - *s;
233 d2 = *s*(a00**s + a01**t + 2.0*b0) + *t*(a01**s + a11**t + 2.0*b1) + c;
234 }
235 }
236 }
237 }
238
239 // Account for numerical round-off error
240 if (d2 < 0.0)
241 {
242 d2 = 0.0;
243 }
244
245 return d2;
246}
247
249 const coord * P0,
250 const coord * P1,
251 const coord * P2)
252{
253 coord diff = vecdiff (*P0, *P);
254 coord edge0 = vecdiff (*P1, *P0);
255 coord edge1 = vecdiff (*P2, *P0);
257 return sign (vecdot (diff, n));
258}
259
260/**
261 Returns the squared distance between p and [p0:p1].
262*/
263double PointSegmentDistance (const coord * p, const coord * p0, const coord * p1,
265{
266 // The direction vector is not unit length. The normalization is deferred
267 // until it is needed.
268 coord direction = vecdiff (*p1, *p0);
269 coord diff = vecdiff (*p, *p1);
270 double t = vecdot(direction, diff);
271 if (t >= (double)0)
272 {
274 *segmentClosest = *p1;
275 }
276 else
277 {
278 diff = vecdiff (*p, *p0);
280 if (t <= (double)0)
281 {
283 *segmentClosest = *p0;
284 }
285 else
286 {
288 if (sqrLength > (double)0)
289 {
290 t /= sqrLength;
292 (*segmentClosest).z = 0.;
293 for (int _d = 0; _d < dimension; _d++)
294 (*segmentClosest).x = (*p0).x + t * direction.x;
295 }
296 else
297 {
299 *segmentClosest = *p0;
300 }
301 }
302 }
303
305 return vecdot(diff, diff);
306}
307
309 const coord * P0,
310 const coord * P1)
311{
312 coord diff = vecdiff (*P0, *P);
313 coord edge0 = vecdiff (*P0, *P1);
315 return sign(n.z);
316}
double b1
Definition NASG.h:19
#define vecdot(a, b)
double PointSegmentDistance(const coord *p, const coord *p0, const coord *p1, coord *segmentClosest, double *segmentParameter)
Returns the squared distance between p and [p0:p1].
double PointTriangleDistance(const coord *P, const coord *P0, const coord *P1, const coord *P2, double *s, double *t)
Returns the squared distance between point P and triangle P0, P1, P2.
#define vecdotproduct(a, b)
int PointSegmentOrientation(const coord *P, const coord *P0, const coord *P1)
#define vecdiff(a, b)
int PointTriangleOrientation(const coord *P, const coord *P0, const coord *P1, const coord *P2)
#define dimension
Definition bitree.h:3
int x
Definition common.h:76
#define HUGE
Definition common.h:6
static int sign(number x)
Definition common.h:13
#define p
Definition tree.h:320
else return n
Definition curvature.h:101
scalar s
Definition embed-tree.h:56
double t
Definition events.h:24
Definition common.h:78
scalar c
Definition vof.h:57