Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
tribox3.h
Go to the documentation of this file.
1/** @file tribox3.h
2 */
3/********************************************************/
4/* AABB-triangle overlap test code */
5/* by Tomas Akenine-Möller */
6/* Function: int triBoxOverlap(float boxcenter[3], */
7/* float boxhalfsize[3],float triverts[3][3]); */
8/* History: */
9/* 2001-03-05: released the code in its first version */
10/* 2001-06-18: changed the order of the tests, faster */
11/* */
12/* Acknowledgement: Many thanks to Pierre Terdiman for */
13/* suggestions and discussions on how to optimize code. */
14/* Thanks to David Hunt for finding a ">="-bug! */
15/* See also: https://doi.org/10.1145/1198555.1198747 */
16/* http://fileadmin.cs.lth.se/cs/personal/tomas_akenine-moller/code/ */
17/********************************************************/
18#include <math.h>
19#include <stdio.h>
20
21#define X 0
22#define Y 1
23#define Z 2
24
25#define CROSS(dest,v1,v2) \
26 dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \
27 dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \
28 dest[2]=v1[0]*v2[1]-v1[1]*v2[0];
29
30#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])
31
32#define SUB(dest,v1,v2) \
33 dest[0]=v1[0]-v2[0]; \
34 dest[1]=v1[1]-v2[1]; \
35 dest[2]=v1[2]-v2[2];
36
37#define FINDMINMAX(x0,x1,x2,min,max) \
38 min = max = x0; \
39 if(x1<min) min=x1;\
40 if(x1>max) max=x1;\
41 if(x2<min) min=x2;\
42 if(x2>max) max=x2;
43
44int planeBoxOverlap(float normal[3], float vert[3], float maxbox[3]) // -NJMP-
45{
46 int q;
47 float vmin[3],vmax[3],v;
48 for(q=X;q<=Z;q++)
49 {
50 v=vert[q]; // -NJMP-
51 if(normal[q]>0.0f)
52 {
53 vmin[q]=-maxbox[q] - v; // -NJMP-
54 vmax[q]= maxbox[q] - v; // -NJMP-
55 }
56 else
57 {
58 vmin[q]= maxbox[q] - v; // -NJMP-
59 vmax[q]=-maxbox[q] - v; // -NJMP-
60 }
61 }
62 if(DOT(normal,vmin)>0.0f) return 0; // -NJMP-
63 if(DOT(normal,vmax)>=0.0f) return 1; // -NJMP-
64
65 return 0;
66}
67
68
69/*======================== X-tests ========================*/
70#define AXISTEST_X01(a, b, fa, fb) \
71 p0 = a*v0[Y] - b*v0[Z]; \
72 p2 = a*v2[Y] - b*v2[Z]; \
73 if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
74 rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
75 if(min>rad || max<-rad) return 0;
76
77#define AXISTEST_X2(a, b, fa, fb) \
78 p0 = a*v0[Y] - b*v0[Z]; \
79 p1 = a*v1[Y] - b*v1[Z]; \
80 if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
81 rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \
82 if(min>rad || max<-rad) return 0;
83
84/*======================== Y-tests ========================*/
85#define AXISTEST_Y02(a, b, fa, fb) \
86 p0 = -a*v0[X] + b*v0[Z]; \
87 p2 = -a*v2[X] + b*v2[Z]; \
88 if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;} \
89 rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
90 if(min>rad || max<-rad) return 0;
91
92#define AXISTEST_Y1(a, b, fa, fb) \
93 p0 = -a*v0[X] + b*v0[Z]; \
94 p1 = -a*v1[X] + b*v1[Z]; \
95 if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
96 rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \
97 if(min>rad || max<-rad) return 0;
98
99/*======================== Z-tests ========================*/
100
101#define AXISTEST_Z12(a, b, fa, fb) \
102 p1 = a*v1[X] - b*v1[Y]; \
103 p2 = a*v2[X] - b*v2[Y]; \
104 if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;} \
105 rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
106 if(min>rad || max<-rad) return 0;
107
108#define AXISTEST_Z0(a, b, fa, fb) \
109 p0 = a*v0[X] - b*v0[Y]; \
110 p1 = a*v1[X] - b*v1[Y]; \
111 if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;} \
112 rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \
113 if(min>rad || max<-rad) return 0;
114
115int triBoxOverlap(float boxcenter[3],float boxhalfsize[3],float triverts[3][3])
116{
117
118 /* use separating axis theorem to test overlap between triangle and box */
119 /* need to test for overlap in these directions: */
120 /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
121 /* we do not even need to test these) */
122 /* 2) normal of the triangle */
123 /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
124 /* this gives 3x3=9 more tests */
125 float v0[3],v1[3],v2[3];
126// float axis[3];
127 float min,max,p0,p1,p2,rad,fex,fey,fez; // -NJMP- "d" local variable removed
128 float normal[3],e0[3],e1[3],e2[3];
129
130 /* This is the fastest branch on Sun */
131 /* move everything so that the boxcenter is in (0,0,0) */
135
136 /* compute triangle edges */
137 SUB(e0,v1,v0); /* tri edge 0 */
138 SUB(e1,v2,v1); /* tri edge 1 */
139 SUB(e2,v0,v2); /* tri edge 2 */
140
141 /* Bullet 3: */
142 /* test the 9 tests first (this was faster) */
143 fex = fabsf(e0[X]);
144 fey = fabsf(e0[Y]);
145 fez = fabsf(e0[Z]);
146 AXISTEST_X01(e0[Z], e0[Y], fez, fey);
147 AXISTEST_Y02(e0[Z], e0[X], fez, fex);
148 AXISTEST_Z12(e0[Y], e0[X], fey, fex);
149
150 fex = fabsf(e1[X]);
151 fey = fabsf(e1[Y]);
152 fez = fabsf(e1[Z]);
153 AXISTEST_X01(e1[Z], e1[Y], fez, fey);
154 AXISTEST_Y02(e1[Z], e1[X], fez, fex);
155 AXISTEST_Z0(e1[Y], e1[X], fey, fex);
156
157 fex = fabsf(e2[X]);
158 fey = fabsf(e2[Y]);
159 fez = fabsf(e2[Z]);
160 AXISTEST_X2(e2[Z], e2[Y], fez, fey);
161 AXISTEST_Y1(e2[Z], e2[X], fez, fex);
162 AXISTEST_Z12(e2[Y], e2[X], fey, fex);
163
164 /* Bullet 1: */
165 /* first test overlap in the {x,y,z}-directions */
166 /* find min, max of the triangle each direction, and test for overlap in */
167 /* that direction -- this is equivalent to testing a minimal AABB around */
168 /* the triangle against the AABB */
169
170 /* test in X-direction */
171 FINDMINMAX(v0[X],v1[X],v2[X],min,max);
172 if(min>boxhalfsize[X] || max<-boxhalfsize[X]) return 0;
173
174 /* test in Y-direction */
175 FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max);
176 if(min>boxhalfsize[Y] || max<-boxhalfsize[Y]) return 0;
177
178 /* test in Z-direction */
179 FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max);
180 if(min>boxhalfsize[Z] || max<-boxhalfsize[Z]) return 0;
181
182 /* Bullet 2: */
183 /* test if the box intersects the plane of the triangle */
184 /* compute plane equation of triangle: normal*x+d=0 */
185 CROSS(normal,e0,e1);
186 // -NJMP- (line removed here)
187 if(!planeBoxOverlap(normal,v0,boxhalfsize)) return 0; // -NJMP-
188
189 return 1; /* box and triangle overlaps */
190}
191
193 coord * p1, coord * p2)
194{
195 // Find min and max X for the segment
196
197 double minX = p1->x;
198 double maxX = p2->x;
199
200 if(p1->x > p2->x)
201 {
202 minX = p2->x;
203 maxX = p1->x;
204 }
205
206 // Find the intersection of the segment's and rectangle's x-projections
207
208 if(maxX > max->x)
209 {
210 maxX = max->x;
211 }
212
213 if(minX < min->x)
214 {
215 minX = min->x;
216 }
217
218 if(minX > maxX) // If their projections do not intersect return false
219 {
220 return false;
221 }
222
223 // Find corresponding min and max Y for min and max X we found before
224
225 double minY = p1->y;
226 double maxY = p2->y;
227
228 double dx = p2->x - p1->x;
229
230 if(fabs(dx) > 0.0000001)
231 {
232 double a = (p2->y - p1->y) / dx;
233 double b = p1->y - a * p1->x;
234 minY = a * minX + b;
235 maxY = a * maxX + b;
236 }
237
238 if(minY > maxY)
239 {
240 double tmp = maxY;
241 maxY = minY;
242 minY = tmp;
243 }
244
245 // Find the intersection of the segment's and rectangle's y-projections
246
247 if(maxY > max->y)
248 {
249 maxY = max->y;
250 }
251
252 if(minY < min->y)
253 {
254 minY = min->y;
255 }
256
257 if(minY > maxY) // If Y-projections do not intersect return false
258 {
259 return false;
260 }
261
262 return true;
263}
vector q[]
The primitive variables are the momentum , pressure , density , (face) specific volume ,...
Definition all-mach.h:44
const vector a
Definition all-mach.h:59
int min
Definition balance.h:192
int y
Definition common.h:76
int x
Definition common.h:76
double v[2]
Definition embed.h:383
#define dx(s)
We first define some useful macros, following the notations in Bonneton et al, 2011.
size_t max
Definition mtrace.h:8
size *double * b
Definition common.h:78
scalar x
Definition common.h:47
scalar y
Definition common.h:49
int triBoxOverlap(float boxcenter[3], float boxhalfsize[3], float triverts[3][3])
Definition tribox3.h:115
#define X
Definition tribox3.h:21
#define AXISTEST_Y02(a, b, fa, fb)
Definition tribox3.h:85
#define SUB(dest, v1, v2)
Definition tribox3.h:32
#define CROSS(dest, v1, v2)
Definition tribox3.h:25
#define FINDMINMAX(x0, x1, x2, min, max)
Definition tribox3.h:37
#define AXISTEST_Z12(a, b, fa, fb)
Definition tribox3.h:101
bool segBoxOverlap(coord *min, coord *max, coord *p1, coord *p2)
Definition tribox3.h:192
#define Z
Definition tribox3.h:23
#define AXISTEST_Y1(a, b, fa, fb)
Definition tribox3.h:92
#define DOT(v1, v2)
Definition tribox3.h:30
#define Y
Definition tribox3.h:22
#define AXISTEST_X2(a, b, fa, fb)
Definition tribox3.h:77
#define AXISTEST_X01(a, b, fa, fb)
Definition tribox3.h:70
int planeBoxOverlap(float normal[3], float vert[3], float maxbox[3])
Definition tribox3.h:44
#define AXISTEST_Z0(a, b, fa, fb)
Definition tribox3.h:108
Array * normal