ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/REPOS_ERICCA/magic/lib/diamesh/src/p3d_inter.cpp
Revision: 5
Committed: Tue Jun 12 20:26:34 2007 UTC (17 years, 11 months ago)
Original Path: magic/lib/diamesh/diamesh/src/p3d_inter.cpp
File size: 8748 byte(s)
Log Message:

File Contents

# User Rev Content
1 5
2     #include <stdio.h>
3     #include <math.h>
4     #include "p3d_cst.h"
5     #include "m3d_struct.h"
6     #include "m3d_hotes.h"
7     #include "prototype.h"
8     extern int debug ;
9     void p3d_inter(float *coord,int *tabele,SURFACE *surf,ELEMENT *ele,int *nb_inter,int *nb_reel,int *nb_neg,float *vec_posi,int *ierr)
10     {
11     /* ************************************************* */
12     /* declaration des variables internes a la procedure */
13     float vec_j1j2[3], vec_n[3], vec_b[3], norme, vec_o[3], vec_j1j3[3] ;
14     int j1, j2, j3, i, i1, i2, i3, iordre[NB_MAX_INTER] ;
15     int icont,gtrouve, position ;
16     float vl1, vl2, vl3 ;
17     ELEMENT *tete ;
18     float vec_oi1[3],vec_g[3], vec_gj1[3], vec_gj2[3], vec_gj3[3] ;
19     float vec_i[3], vn[3], vec_i1i2[3], vec_i1i3[3] ;
20     float prosca, dist ;
21    
22     /* ************************************************* */
23     /* debut du code executable */
24    
25     *nb_inter = 0 ;
26     /* calcul des parametres de l'element */
27    
28     /* numero des sommets */
29     /* tete de liste des elements */
30    
31     /* ********************************* */
32     /* element j1,j2,j3 de normale vec_n */
33     /* ********************************* */
34     j1 = tabele[3*(ele->num)] ;
35     j2 = tabele[3*(ele->num)+1] ;
36     j3 = tabele[3*(ele->num)+2] ;
37    
38     vec_j1j2[0]=coord[x(j2)]-coord[x(j1)] ;
39     vec_j1j2[1]=coord[y(j2)]-coord[y(j1)] ;
40     vec_j1j2[2]=coord[z(j2)]-coord[z(j1)] ;
41    
42     vec_j1j3[0]=coord[x(j3)]-coord[x(j1)] ;
43     vec_j1j3[1]=coord[y(j3)]-coord[y(j1)] ;
44     vec_j1j3[2]=coord[z(j3)]-coord[z(j1)] ;
45    
46     /* normale a l'element triangulaire */
47    
48     vec_n[0] = PVECX(vec_j1j2,vec_j1j3) ;
49     vec_n[1] = PVECY(vec_j1j2,vec_j1j3) ;
50     vec_n[2] = PVECZ(vec_j1j2,vec_j1j3) ;
51    
52     norme = NORME(vec_n) ;
53     if (norme<EPSILON)
54     {
55     *ierr = VRAI ;
56     if (debug) printf("%s\n"," erreur norme nulle P3D_INTER ") ;
57     return ;
58     }
59     /* on norme le vecteur normal */
60     for (i=0;i<3;i++) vec_n[i] = vec_n[i]/norme ;
61    
62     norme = NORME(vec_j1j2) ;
63     if (norme<EPSILON)
64     {
65     *ierr = VRAI ;
66     if (debug) printf("%s\n"," erreur norme nulle P3D_INTER ") ;
67     return ;
68     }
69     /* on norme le vecteur vec_j1j2 */
70     for (i=0;i<3;i++) vec_j1j2[i] = vec_j1j2[i]/norme ;
71    
72     vec_b[0] = PVECX(vec_n,vec_j1j2) ;
73     vec_b[1] = PVECY(vec_n,vec_j1j2) ;
74     vec_b[2] = PVECZ(vec_n,vec_j1j2) ;
75     /* barycentre de la face j1,j2,j3 */
76     vec_g[0]=(coord[x(j1)]+coord[x(j2)]+coord[x(j3)])/3. ;
77     vec_g[1]=(coord[y(j1)]+coord[y(j2)]+coord[y(j3)])/3. ;
78     vec_g[2]=(coord[z(j1)]+coord[z(j2)]+coord[z(j3)])/3. ;
79    
80     vec_gj1[0]= coord[x(j1)] - vec_g[0] ;
81     vec_gj1[1]= coord[y(j1)] - vec_g[1] ;
82     vec_gj1[2]= coord[z(j1)] - vec_g[2] ;
83    
84     vec_gj2[0]= coord[x(j2)] - vec_g[0] ;
85     vec_gj2[1]= coord[y(j2)] - vec_g[1] ;
86     vec_gj2[2]= coord[z(j2)] - vec_g[2] ;
87    
88     vec_gj3[0]= coord[x(j3)] - vec_g[0] ;
89     vec_gj3[1]= coord[y(j3)] - vec_g[1] ;
90     vec_gj3[2]= coord[z(j3)] - vec_g[2] ;
91    
92     icont = 0 ;/* compteur */
93     gtrouve=FAUX ;
94     /* si la postion du point origine ne permet pas de conclure, on change cette position en restant
95     proche du centre de gravite */
96     /* on dispose de 4 points, si on ne peut conclure, il faut alors changer d'element */
97     while ((gtrouve==FAUX)&&(icont<4))
98     {
99     *nb_inter = 0 ;
100     if (icont==0)
101     {
102     vl1 = 0. ;
103     vl2 = 0. ;
104     vl3 = 0. ;
105     }
106     if (icont==1)
107     {
108     vl1 = 0.1 ;
109     vl2 = 0. ;
110     vl3 = 0. ;
111     }
112     if (icont==2)
113     {
114     vl1 = 0. ;
115     vl2 = 0.1 ;
116     vl3 = 0. ;
117     }
118     if (icont==3)
119     {
120     vl1 = 0. ;
121     vl2 = 0. ;
122     vl3 = 0.1 ;
123     }
124    
125     /* position du point origine sur la facette j1,j2,j3 */
126     /* si tous les vli sont nuls : centre de gravite */
127     vec_o[0]= vec_g[0] + (vl1 * vec_gj1[0]) + (vl2 * vec_gj2[0]) + (vl3 * vec_gj3[0]) ;
128     vec_o[1]= vec_g[1] + (vl1 * vec_gj1[1]) + (vl2 * vec_gj2[1]) + (vl3 * vec_gj3[1]) ;
129     vec_o[2]= vec_g[2] + (vl1 * vec_gj1[2]) + (vl2 * vec_gj2[2]) + (vl3 * vec_gj3[2]) ;
130    
131     /* parcours des elements de la surface */
132     tete = surf->ele ; /* on se place en tete de liste des elements de la surface */
133     while (tete!=NULL)/* parcours des elements */
134     {
135     if (tete==ele)/* l'element est sur la surface */
136     {
137     if (*nb_inter>=NB_MAX_INTER)
138     {
139     *ierr = VRAI ;
140     if (debug) printf("%s\n"," erreur tableau P3D_INTER") ;
141     return ;
142     }
143     vec_posi[*nb_inter] = 0. ;
144     *nb_inter = (*nb_inter) + 1 ;
145     }
146     else
147     {
148     /* sommets */
149    
150     /* calcul du point intersection sur le plan */
151    
152     /* numero du triangle courant */
153     i1 = tabele[3*(tete->num)] ;
154     i2 = tabele[3*(tete->num)+1] ;
155     i3 = tabele[3*(tete->num)+2] ;
156    
157     /* calcul de la normale a la facette */
158    
159     vec_i1i2[0]=coord[x(i2)]-coord[x(i1)] ;
160     vec_i1i2[1]=coord[y(i2)]-coord[y(i1)] ;
161     vec_i1i2[2]=coord[z(i2)]-coord[z(i1)] ;
162    
163     vec_i1i3[0]=coord[x(i3)]-coord[x(i1)] ;
164     vec_i1i3[1]=coord[y(i3)]-coord[y(i1)] ;
165     vec_i1i3[2]=coord[z(i3)]-coord[z(i1)] ;
166    
167     /* normale a la facette i1,i2,i3 */
168     vn[0] = PVECX(vec_i1i2,vec_i1i3) ;
169     vn[1] = PVECY(vec_i1i2,vec_i1i3) ;
170     vn[2] = PVECZ(vec_i1i2,vec_i1i3) ;
171    
172     norme = NORME(vn) ;
173     if (norme<EPSILON)
174     {
175     *ierr = VRAI ;
176     if (debug) printf("%s\n"," erreur norme nulle P3D_INTER ") ;
177     return ;
178     }
179     /* on norme le vecteur normal */
180     for (i=0;i<3;i++) vn[i] = vn[i]/norme ;
181     /* produit scalaire des normales */
182    
183     prosca = PROSCA(vec_n,vn) ;
184    
185     vec_oi1[0] = coord[x(i1)]-vec_o[0] ;
186     vec_oi1[1] = coord[y(i1)]-vec_o[1] ;
187     vec_oi1[2] = coord[z(i1)]-vec_o[2] ;
188     /* la normale a la face j1,j2,j3 est parallele a la facette i1,i2,i3 de la surface
189     par consequent, il est delicat de determiner le nombre d'intersection de la droite
190     avec la surface dont la facette i1,i2,i3 fait partie */
191     if ((float)fabs((double)prosca)<EPSILON)
192     {
193     /* tester la distance de la droite (o,vec_n) issue de j1,j2,j3
194     au plan de normal vn de la facette i1,i2,i3 */
195     /* si cette distance est non nulle il est clair que meme si la normale est parallele
196     a la facette, il n'y a pas intersection */
197     prosca = PROSCA(vec_oi1,vn) ;
198     prosca = (float)fabs((double)prosca) ;
199     if (prosca<EPSILON)
200     {
201     *nb_inter = UNKNOWN ;
202     /* on ne peut pas conclure
203     la droite issue de vec_o et de normale vec_n : la droite issue de j1 ,j2,j3
204     est dans le plan de la facette, on ne peut conclure quant au nombre de points
205     d'intersection, il faut deplacer le centre vec_o en conservant bien sur l'orientation
206     de la facette j1,j2,j3( on a 4 essais) */
207     }
208     /* sinon pas d'intersection */
209     }
210     else
211     {
212     /* projection sur le plan */
213    
214     dist = PROSCA(vec_oi1,vn)/prosca ;
215     /* point intersection avec la facette i1,i2,i3*/
216     vec_i[0] = dist*vec_n[0] + vec_o[0] ;
217     vec_i[1] = dist*vec_n[1] + vec_o[1] ;
218     vec_i[2] = dist*vec_n[2] + vec_o[2] ;
219    
220     /* le point I appartient il au triangle i1, i2, i3 */
221     position = m3d_pt_tri(coord,vec_i,i1,i2,i3,vn) ;
222     if ((position==INTERIEUR)||(position==DESSUS))
223     /* en fait vmin>=0.*/
224     {
225     if (*nb_inter>=NB_MAX_INTER)
226     {
227     *ierr = VRAI ;
228     return ;
229     }
230     if (*nb_inter!=UNKNOWN)
231     {
232     vec_posi[*nb_inter] = dist ;
233     *nb_inter = (*nb_inter) + 1. ;
234     }
235     }
236     }
237     }
238     tete=tete->suivant ;/* on passe a l'element suivant sur la surface */
239     /* cas ou il n'a pas ete possible de conclure, on fait un essai avec un nouveau point */
240     if (*nb_inter==UNKNOWN) tete=NULL ;/* fin de parcours, on passe au point origine suivant */
241     }
242    
243     *nb_reel = *nb_inter ;
244     *nb_neg = *nb_inter ;
245    
246     if (*nb_inter>1)
247     {
248     /* collage en fin de parcours, il se peut qu'une intersection,soit commune a plusieurs elements */
249     /* tri croissant des distances sur la droite, le tableau est modifie */
250     for (i=0;i<*nb_inter;i++) iordre[i] = i+1 ;/* attention passage c fortran */
251     trirea(vec_posi,nb_inter,iordre) ;
252     for (i=0;i<*nb_inter-1;i++)
253     {
254     /* attention au choix de EPSILON */
255     if ((vec_posi[i+1]-vec_posi[i])<100.*EPSILON)
256     {
257     *nb_reel = (*nb_reel) - 1 ;
258     *nb_neg = (*nb_neg) -1 ;
259     }
260     else
261     {
262     if (vec_posi[i]>-EPSILON) *nb_neg = (*nb_neg) -1 ;
263     }
264     }
265     if (vec_posi[*nb_inter-1]>-EPSILON) *nb_neg = (*nb_neg) -1 ;
266     /* on teste les points doubles pour eviter les ambiguites */
267     if (*nb_reel!=*nb_inter) *nb_inter = UNKNOWN ;
268     }
269     if (*nb_inter!=UNKNOWN) gtrouve=VRAI ;/* on peut conclure */
270     icont ++ ;
271     }
272     /* l'element n'a pas permis de conclure */
273     if ((icont==4)&&(gtrouve==FAUX))
274     {
275     *ierr=VRAI ;
276     if (debug) printf("%s\n"," erreur systeme P3D_INTER") ;
277     *nb_inter = UNKNOWN ;
278     return ;
279     }
280     return ;
281     }