1*59599516SKenneth E. Jansen /* fortran wrapper for C program length which returns the length
2*59599516SKenneth E. Jansen of an element in a given direction.
3*59599516SKenneth E. Jansen */
4*59599516SKenneth E. Jansen #include "vec_func.h"
5*59599516SKenneth E. Jansen
6*59599516SKenneth E. Jansen
7*59599516SKenneth E. Jansen double length(double [][3],double []);
8*59599516SKenneth E. Jansen int intersect(double x[4][3],double u[],double points[4][3] );
9*59599516SKenneth E. Jansen int isPntInTri(double [][3],double [], double [], double );
10*59599516SKenneth E. Jansen
11*59599516SKenneth E. Jansen #ifdef sun4_5
get_h_(double xtmp[][4],double u[],double * h)12*59599516SKenneth E. Jansen get_h_(double xtmp[][4], double u[], double *h)
13*59599516SKenneth E. Jansen #endif
14*59599516SKenneth E. Jansen #ifdef LINUX
15*59599516SKenneth E. Jansen get_h_(double xtmp[][4], double u[], double *h)
16*59599516SKenneth E. Jansen #endif
17*59599516SKenneth E. Jansen #ifdef ibm
18*59599516SKenneth E. Jansen get_h(double xtmp[][4], double u[], double *h)
19*59599516SKenneth E. Jansen #endif
20*59599516SKenneth E. Jansen #ifdef sgi
21*59599516SKenneth E. Jansen void get_h(double xtmp[][4], double u[], double *h)
22*59599516SKenneth E. Jansen #endif
23*59599516SKenneth E. Jansen #ifdef decalp
24*59599516SKenneth E. Jansen void get_h(double xtmp[][4], double u[], double *h)
25*59599516SKenneth E. Jansen #endif
26*59599516SKenneth E. Jansen #ifdef intel
27*59599516SKenneth E. Jansen void GET_H(double xtmp[][4], double u[], double *h)
28*59599516SKenneth E. Jansen #endif
29*59599516SKenneth E. Jansen {
30*59599516SKenneth E. Jansen double x[4][3];
31*59599516SKenneth E. Jansen int i,j;
32*59599516SKenneth E. Jansen /*recall that arrays in fortran and C are transposed */
33*59599516SKenneth E. Jansen for(i=0; i < 4; i++)
34*59599516SKenneth E. Jansen for(j=0; j < 3; j++)
35*59599516SKenneth E. Jansen x[i][j] = xtmp[j][i];
36*59599516SKenneth E. Jansen
37*59599516SKenneth E. Jansen *h = length(x,u);
38*59599516SKenneth E. Jansen }
39*59599516SKenneth E. Jansen
length(double x[4][3],double u[])40*59599516SKenneth E. Jansen double length(double x[4][3],double u[] ){
41*59599516SKenneth E. Jansen int nint;
42*59599516SKenneth E. Jansen double tmp[3],he;
43*59599516SKenneth E. Jansen double points[4][3];
44*59599516SKenneth E. Jansen
45*59599516SKenneth E. Jansen /* compute the intersection points. nint is returned
46*59599516SKenneth E. Jansen as the number of faces that this line intersected
47*59599516SKenneth E. Jansen within the tet */
48*59599516SKenneth E. Jansen nint = intersect(x,u,points);
49*59599516SKenneth E. Jansen
50*59599516SKenneth E. Jansen /* if nint is larger than one, then the vector intersected
51*59599516SKenneth E. Jansen an edge (nint=3) or corner (nint=4) of the tet. In this
52*59599516SKenneth E. Jansen case, we need to make sure that we are computing the
53*59599516SKenneth E. Jansen length between two different points. */
54*59599516SKenneth E. Jansen
55*59599516SKenneth E. Jansen if(nint > 1){ /* vecEqual returns 1 if
56*59599516SKenneth E. Jansen these two vectors are the same.
57*59599516SKenneth E. Jansen */
58*59599516SKenneth E. Jansen if( vecEqual(points[0],points[1]) ){
59*59599516SKenneth E. Jansen if( vecEqual(points[0],points[2]) ){
60*59599516SKenneth E. Jansen diffVt(points[0],points[3],tmp);
61*59599516SKenneth E. Jansen }
62*59599516SKenneth E. Jansen else{
63*59599516SKenneth E. Jansen diffVt(points[0],points[2],tmp);
64*59599516SKenneth E. Jansen }
65*59599516SKenneth E. Jansen }
66*59599516SKenneth E. Jansen else{
67*59599516SKenneth E. Jansen diffVt(points[0],points[1],tmp);
68*59599516SKenneth E. Jansen }
69*59599516SKenneth E. Jansen }
70*59599516SKenneth E. Jansen else{
71*59599516SKenneth E. Jansen diffVt(points[0],points[1],tmp);
72*59599516SKenneth E. Jansen }
73*59599516SKenneth E. Jansen
74*59599516SKenneth E. Jansen /* compute the length of the element */
75*59599516SKenneth E. Jansen he = vecMag(tmp);
76*59599516SKenneth E. Jansen return he;
77*59599516SKenneth E. Jansen }
78*59599516SKenneth E. Jansen
79*59599516SKenneth E. Jansen /*
80*59599516SKenneth E. Jansen This function returns the intersection points of a line
81*59599516SKenneth E. Jansen through the centroid of a tet in a given direction.
82*59599516SKenneth E. Jansen */
83*59599516SKenneth E. Jansen
84*59599516SKenneth E. Jansen
85*59599516SKenneth E. Jansen /* u_line is a function that defines the parametric equation
86*59599516SKenneth E. Jansen of a line given a point on the lineg, a direction, and a
87*59599516SKenneth E. Jansen parameter value */
88*59599516SKenneth E. Jansen
89*59599516SKenneth E. Jansen void u_line(double s, double xc[3], double udir[3], double pnt[3]);
90*59599516SKenneth E. Jansen
91*59599516SKenneth E. Jansen /*
92*59599516SKenneth E. Jansen All points which intersect the tet are returned, however
93*59599516SKenneth E. Jansen only two of them need be used. The value of the function on
94*59599516SKenneth E. Jansen exit is the number of points of intersection, ie. the number
95*59599516SKenneth E. Jansen of faces not parallel to udir */
96*59599516SKenneth E. Jansen
intersect(double x[4][3],double u[],double points[4][3])97*59599516SKenneth E. Jansen int intersect(double x[4][3],double u[],double points[4][3] ){
98*59599516SKenneth E. Jansen int pos = 0;
99*59599516SKenneth E. Jansen double tol = 0.000001;
100*59599516SKenneth E. Jansen double eps = 0.000001;
101*59599516SKenneth E. Jansen int face,i,j,k;
102*59599516SKenneth E. Jansen double xc[3];
103*59599516SKenneth E. Jansen double xbar[3][3];
104*59599516SKenneth E. Jansen double xref[3],v1[3],v2[3],normal[3];
105*59599516SKenneth E. Jansen /* define local vertex numbers of four faces of the tet */
106*59599516SKenneth E. Jansen int f_index[4][3] = {{0,1,2},{1,3,2},{0,2,3},{0,3,1}};
107*59599516SKenneth E. Jansen double n_dot_u;
108*59599516SKenneth E. Jansen double xr_xc[3], s, pt[3];
109*59599516SKenneth E. Jansen
110*59599516SKenneth E. Jansen /* compute centroid coordinates */
111*59599516SKenneth E. Jansen for(i=0; i<3; i++)
112*59599516SKenneth E. Jansen xc[i] = 0.25*(x[0][i]+x[1][i]+x[2][i]+x[3][i]);
113*59599516SKenneth E. Jansen
114*59599516SKenneth E. Jansen /* loop over each face */
115*59599516SKenneth E. Jansen for( face= 0 ; face< 4; face++ ){
116*59599516SKenneth E. Jansen /* compute coordinates of this face */
117*59599516SKenneth E. Jansen for( j= 0 ; j<3 ; j++)
118*59599516SKenneth E. Jansen for( k= 0; k< 3; k++)
119*59599516SKenneth E. Jansen xbar[j][k] = x[f_index[face][j]][k];
120*59599516SKenneth E. Jansen
121*59599516SKenneth E. Jansen /* set reference coordinate */
122*59599516SKenneth E. Jansen if( face != 2 ){
123*59599516SKenneth E. Jansen for( i= 0; i<3; i++ )
124*59599516SKenneth E. Jansen xref[i] = xbar[0][i];
125*59599516SKenneth E. Jansen }
126*59599516SKenneth E. Jansen else{ /* face 2 is the only face that
127*59599516SKenneth E. Jansen can't use xbar[0] as a reference */
128*59599516SKenneth E. Jansen for( i= 0; i<3; i++ )
129*59599516SKenneth E. Jansen xref[i] = xbar[1][i];
130*59599516SKenneth E. Jansen }
131*59599516SKenneth E. Jansen
132*59599516SKenneth E. Jansen /* compute two vectors which describe the plane of this
133*59599516SKenneth E. Jansen face */
134*59599516SKenneth E. Jansen for( i=0; i< 3; i++){
135*59599516SKenneth E. Jansen v1[i] = xbar[1][i] - xbar[0][i];
136*59599516SKenneth E. Jansen v2[i] = xbar[2][i] - xbar[0][i];
137*59599516SKenneth E. Jansen }
138*59599516SKenneth E. Jansen /* get the normal to this plane */
139*59599516SKenneth E. Jansen crossProd(v1,v2,normal);
140*59599516SKenneth E. Jansen
141*59599516SKenneth E. Jansen n_dot_u = dotProd(normal,u);
142*59599516SKenneth E. Jansen
143*59599516SKenneth E. Jansen /* if u is not parallel to this face, then find
144*59599516SKenneth E. Jansen the point of intersection */
145*59599516SKenneth E. Jansen if( fabs(n_dot_u) > eps ){
146*59599516SKenneth E. Jansen diffVt( xref, xc, xr_xc );
147*59599516SKenneth E. Jansen
148*59599516SKenneth E. Jansen /* s is the parameter value where the line parallel to
149*59599516SKenneth E. Jansen to the vector u intersects this face*/
150*59599516SKenneth E. Jansen s = dotProd(normal,xr_xc)/n_dot_u;
151*59599516SKenneth E. Jansen
152*59599516SKenneth E. Jansen u_line(s,xc,u,pt); /* find intersection point */
153*59599516SKenneth E. Jansen
154*59599516SKenneth E. Jansen /* if this point lies on the tet, then save it */
155*59599516SKenneth E. Jansen if( isPntInTri(xbar,normal,pt,tol) ){
156*59599516SKenneth E. Jansen for(i=0; i<3; i++)
157*59599516SKenneth E. Jansen points[pos][i] = pt[i];
158*59599516SKenneth E. Jansen pos += 1;
159*59599516SKenneth E. Jansen }
160*59599516SKenneth E. Jansen }
161*59599516SKenneth E. Jansen else{ /* do nothing */
162*59599516SKenneth E. Jansen
163*59599516SKenneth E. Jansen }
164*59599516SKenneth E. Jansen }
165*59599516SKenneth E. Jansen
166*59599516SKenneth E. Jansen return pos;
167*59599516SKenneth E. Jansen }
168*59599516SKenneth E. Jansen
169*59599516SKenneth E. Jansen /* parametric equation of the line passing through xc
170*59599516SKenneth E. Jansen in the direction of u.
171*59599516SKenneth E. Jansen */
172*59599516SKenneth E. Jansen
u_line(double s,double xc[3],double udir[3],double pnt[3])173*59599516SKenneth E. Jansen void u_line(double s, double xc[3], double udir[3], double pnt[3]){
174*59599516SKenneth E. Jansen int i;
175*59599516SKenneth E. Jansen for(i=0; i<3; i++)
176*59599516SKenneth E. Jansen pnt[i] = xc[i]+s*udir[i];
177*59599516SKenneth E. Jansen }
178*59599516SKenneth E. Jansen
179*59599516SKenneth E. Jansen
diffVt(double vec1[3],double vec2[3],double ans[3])180*59599516SKenneth E. Jansen void diffVt(double vec1[3],double vec2[3], double ans[3]){
181*59599516SKenneth E. Jansen ans[0] = vec1[0]-vec2[0];
182*59599516SKenneth E. Jansen ans[1] = vec1[1]-vec2[1];
183*59599516SKenneth E. Jansen ans[2] = vec1[2]-vec2[2];
184*59599516SKenneth E. Jansen }
185*59599516SKenneth E. Jansen
crossProd(double a[3],double b[3],double ans[3])186*59599516SKenneth E. Jansen void crossProd(double a[3], double b[3], double ans[3]){
187*59599516SKenneth E. Jansen ans[0] = a[1]*b[2]-b[1]*a[2];
188*59599516SKenneth E. Jansen ans[1] = a[2]*b[0]-b[2]*a[0];
189*59599516SKenneth E. Jansen ans[2] = a[0]*b[1]-b[0]*a[1];
190*59599516SKenneth E. Jansen }
191*59599516SKenneth E. Jansen
dotProd(double a[3],double b[3])192*59599516SKenneth E. Jansen double dotProd(double a[3], double b[3]){
193*59599516SKenneth E. Jansen return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
194*59599516SKenneth E. Jansen }
195*59599516SKenneth E. Jansen
vecMag(double a[3])196*59599516SKenneth E. Jansen double vecMag(double a[3]){
197*59599516SKenneth E. Jansen return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
198*59599516SKenneth E. Jansen }
199*59599516SKenneth E. Jansen
vecEqual(double a[3],double b[3])200*59599516SKenneth E. Jansen int vecEqual(double a[3], double b[3]){
201*59599516SKenneth E. Jansen return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2]);
202*59599516SKenneth E. Jansen }
203*59599516SKenneth E. Jansen
204*59599516SKenneth E. Jansen /*
205*59599516SKenneth E. Jansen Determines if a point is inside or out of a triangle
206*59599516SKenneth E. Jansen Pt will be declared in triangle if distance to side < tol
207*59599516SKenneth E. Jansen if u want the tolerancing to be relative to 't_xyz',
208*59599516SKenneth E. Jansen pass tol (absolute tolerance) * size of 't_xyz'
209*59599516SKenneth E. Jansen */
210*59599516SKenneth E. Jansen
isPntInTri(double t_xyz[3][3],double t_normal[3],double p_xyz[3],double tol)211*59599516SKenneth E. Jansen int isPntInTri(
212*59599516SKenneth E. Jansen double t_xyz[3][3],
213*59599516SKenneth E. Jansen double t_normal[3], /* Normal to triangle (not normed) */
214*59599516SKenneth E. Jansen double p_xyz[3],
215*59599516SKenneth E. Jansen double tol
216*59599516SKenneth E. Jansen )
217*59599516SKenneth E. Jansen
218*59599516SKenneth E. Jansen {
219*59599516SKenneth E. Jansen
220*59599516SKenneth E. Jansen double cross_p[3];
221*59599516SKenneth E. Jansen double d;
222*59599516SKenneth E. Jansen int side;
223*59599516SKenneth E. Jansen int status;
224*59599516SKenneth E. Jansen double cross_p_sqnorm;
225*59599516SKenneth E. Jansen double dnbr;
226*59599516SKenneth E. Jansen double dtol;
227*59599516SKenneth E. Jansen double t_vec[3];
228*59599516SKenneth E. Jansen double t_vec_norm;
229*59599516SKenneth E. Jansen double tp_vec[3];
230*59599516SKenneth E. Jansen double tp_vec_sqnorm;
231*59599516SKenneth E. Jansen
232*59599516SKenneth E. Jansen status= 1;
233*59599516SKenneth E. Jansen
234*59599516SKenneth E. Jansen for ( side= 0 ; side< 3 ; side++ ) {
235*59599516SKenneth E. Jansen
236*59599516SKenneth E. Jansen diffVt(t_xyz[(side+1)%3],t_xyz[side],t_vec);
237*59599516SKenneth E. Jansen crossProd(t_normal,t_vec,cross_p);
238*59599516SKenneth E. Jansen cross_p_sqnorm= dotProd(cross_p,cross_p);
239*59599516SKenneth E. Jansen
240*59599516SKenneth E. Jansen diffVt(p_xyz,t_xyz[side],tp_vec);
241*59599516SKenneth E. Jansen
242*59599516SKenneth E. Jansen d= dotProd(cross_p,tp_vec);
243*59599516SKenneth E. Jansen dnbr= d * d;
244*59599516SKenneth E. Jansen dtol= tol*tol*cross_p_sqnorm;
245*59599516SKenneth E. Jansen
246*59599516SKenneth E. Jansen if ( dnbr < dtol ) {
247*59599516SKenneth E. Jansen
248*59599516SKenneth E. Jansen /*
249*59599516SKenneth E. Jansen Pt is considered to be on the side (extended to infinity)
250*59599516SKenneth E. Jansen */
251*59599516SKenneth E. Jansen
252*59599516SKenneth E. Jansen /*
253*59599516SKenneth E. Jansen Make sure distance to point 0 or 1 less than ...
254*59599516SKenneth E. Jansen */
255*59599516SKenneth E. Jansen
256*59599516SKenneth E. Jansen t_vec_norm= vecMag(t_vec);
257*59599516SKenneth E. Jansen dtol= t_vec_norm + tol;
258*59599516SKenneth E. Jansen dtol *= dtol;
259*59599516SKenneth E. Jansen
260*59599516SKenneth E. Jansen tp_vec_sqnorm= dotProd(tp_vec,tp_vec);
261*59599516SKenneth E. Jansen if ( tp_vec_sqnorm > dtol ) {
262*59599516SKenneth E. Jansen status= 0;
263*59599516SKenneth E. Jansen break;
264*59599516SKenneth E. Jansen }
265*59599516SKenneth E. Jansen
266*59599516SKenneth E. Jansen diffVt(p_xyz,t_xyz[(side+1)%3],tp_vec);
267*59599516SKenneth E. Jansen tp_vec_sqnorm= dotProd(tp_vec,tp_vec);
268*59599516SKenneth E. Jansen if ( tp_vec_sqnorm > dtol ) {
269*59599516SKenneth E. Jansen status= 0;
270*59599516SKenneth E. Jansen break;
271*59599516SKenneth E. Jansen }
272*59599516SKenneth E. Jansen
273*59599516SKenneth E. Jansen continue;
274*59599516SKenneth E. Jansen }
275*59599516SKenneth E. Jansen
276*59599516SKenneth E. Jansen if ( d > 0.0 ) {
277*59599516SKenneth E. Jansen
278*59599516SKenneth E. Jansen /*
279*59599516SKenneth E. Jansen Pt is strictly in the interior of the side
280*59599516SKenneth E. Jansen */
281*59599516SKenneth E. Jansen }
282*59599516SKenneth E. Jansen else if ( d < 0.0 ) {
283*59599516SKenneth E. Jansen
284*59599516SKenneth E. Jansen /*
285*59599516SKenneth E. Jansen Pt is strictly in the outisde of the side
286*59599516SKenneth E. Jansen */
287*59599516SKenneth E. Jansen
288*59599516SKenneth E. Jansen status= 0;
289*59599516SKenneth E. Jansen break;
290*59599516SKenneth E. Jansen }
291*59599516SKenneth E. Jansen
292*59599516SKenneth E. Jansen }
293*59599516SKenneth E. Jansen
294*59599516SKenneth E. Jansen return status;
295*59599516SKenneth E. Jansen
296*59599516SKenneth E. Jansen }
297*59599516SKenneth E. Jansen
298*59599516SKenneth E. Jansen
299*59599516SKenneth E. Jansen
300*59599516SKenneth E. Jansen
301*59599516SKenneth E. Jansen
302*59599516SKenneth E. Jansen
303*59599516SKenneth E. Jansen
304*59599516SKenneth E. Jansen
305*59599516SKenneth E. Jansen
306*59599516SKenneth E. Jansen
307*59599516SKenneth E. Jansen
308