1 |
francois |
283 |
/* BOUGE DE POINTS SAUCE P.L.GEORGE Article INRIA STRUCOME 1994 */ |
2 |
|
|
#include <stdio.h> |
3 |
|
|
#include <math.h> |
4 |
|
|
#include "m3d_struct.h" |
5 |
|
|
#include "m3d_const.h" |
6 |
|
|
#include "m3d_hotes.h" |
7 |
|
|
#include "m3d_erreur.h" |
8 |
|
|
#include "prototype.h" |
9 |
|
|
extern int debug ; |
10 |
|
|
extern float crit_min ; |
11 |
|
|
int m3d_move2(float *coord,int nb_noeud,int nb_face,int *tabele,float *vcorg,float *critere,int *numele) |
12 |
|
|
{ |
13 |
|
|
int num_p ; |
14 |
|
|
int tab_tetra[400] ; |
15 |
|
|
int nb_ele, i, j, k, nump ; |
16 |
|
|
float tab_crit[1000], vec_opt[3], cmin ; |
17 |
|
|
float tab_opt[3000] ; |
18 |
|
|
int sens ; |
19 |
|
|
float gamma, vn[3], xi, yi, zi, vab[3], vac[3], vbc[3], pvec[3], hauteur, vap[3] ; |
20 |
|
|
float dab, dac, dbc, perimetre, norme, coeff, alpha ; |
21 |
|
|
float delta[3] ; |
22 |
|
|
float vec_save[3], bmin, bmax, eps, crit_save ; |
23 |
|
|
float calpha, calpha_moins_eps, vresu[3] ; |
24 |
|
|
|
25 |
|
|
nump = nb_noeud ; |
26 |
|
|
coord[x(nump)] = vcorg[0] ; |
27 |
|
|
coord[y(nump)] = vcorg[1] ; |
28 |
|
|
coord[z(nump)] = vcorg[2] ; |
29 |
|
|
|
30 |
|
|
/* sauvegarde des coordonnees du noeud */ |
31 |
|
|
vec_save[0] = coord[x(nump)] ; |
32 |
|
|
vec_save[1] = coord[y(nump)] ; |
33 |
|
|
vec_save[2] = coord[z(nump)] ; |
34 |
|
|
|
35 |
|
|
for (nb_ele=0;nb_ele<nb_face;nb_ele++) |
36 |
|
|
{ |
37 |
|
|
numele[4*nb_ele] = tabele[3*nb_ele] ; |
38 |
|
|
numele[4*nb_ele+1] = tabele[3*nb_ele+1] ; |
39 |
|
|
numele[4*nb_ele+2] = tabele[3*nb_ele+2] ; |
40 |
|
|
numele[4*nb_ele+3] = nump ; |
41 |
|
|
/* determination du point optimal de la face nb_ele */ |
42 |
|
|
|
43 |
|
|
xi = (coord[x(tabele[3*nb_ele])] + coord[x(tabele[3*nb_ele+1])] + coord[x(tabele[3*nb_ele+2])])/3. ; |
44 |
|
|
yi = (coord[y(tabele[3*nb_ele])] + coord[y(tabele[3*nb_ele+1])] + coord[y(tabele[3*nb_ele+2])])/3. ; |
45 |
|
|
zi = (coord[z(tabele[3*nb_ele])] + coord[z(tabele[3*nb_ele+1])] + coord[z(tabele[3*nb_ele+2])])/3. ; |
46 |
|
|
|
47 |
|
|
/* calcul de la normale a la face */ |
48 |
|
|
vab[0] = coord[x(tabele[3*nb_ele+1])] - coord[x(tabele[3*nb_ele])] ; |
49 |
|
|
vab[1] = coord[y(tabele[3*nb_ele+1])] - coord[y(tabele[3*nb_ele])] ; |
50 |
|
|
vab[2] = coord[z(tabele[3*nb_ele+1])] - coord[z(tabele[3*nb_ele])] ; |
51 |
|
|
dab = NORME(vab) ; |
52 |
|
|
vac[0] = coord[x(tabele[3*nb_ele+2])] - coord[x(tabele[3*nb_ele])] ; |
53 |
|
|
vac[1] = coord[y(tabele[3*nb_ele+2])] - coord[y(tabele[3*nb_ele])] ; |
54 |
|
|
vac[2] = coord[z(tabele[3*nb_ele+2])] - coord[z(tabele[3*nb_ele])] ; |
55 |
|
|
dac = NORME(vac) ; |
56 |
|
|
vbc[0] = coord[x(tabele[3*nb_ele+2])] - coord[x(tabele[3*nb_ele+1])] ; |
57 |
|
|
vbc[1] = coord[y(tabele[3*nb_ele+2])] - coord[y(tabele[3*nb_ele+1])] ; |
58 |
|
|
vbc[2] = coord[z(tabele[3*nb_ele+2])] - coord[z(tabele[3*nb_ele+1])] ; |
59 |
|
|
dbc = NORME(vbc) ; |
60 |
|
|
|
61 |
|
|
pvec[0] = PVECX(vab,vac) ; |
62 |
|
|
pvec[1] = PVECY(vab,vac) ; |
63 |
|
|
pvec[2] = PVECZ(vab,vac) ; |
64 |
|
|
perimetre = dab + dbc + dac ; |
65 |
|
|
hauteur = (perimetre/3.) * 0.8 ; |
66 |
|
|
|
67 |
|
|
vn[0] = PVECX(vab,vac) ; |
68 |
|
|
vn[1] = PVECY(vab,vac) ; |
69 |
|
|
vn[2] = PVECZ(vab,vac) ; |
70 |
|
|
norme = NORME(vn) ; |
71 |
|
|
if (norme<EPSILON) |
72 |
|
|
{ |
73 |
|
|
//if (debug) aff_text("normale nulle M3D_MOVE\n ") ; |
74 |
|
|
m3d_erreur(ERR_SYST) ; |
75 |
|
|
return(FAUX) ; |
76 |
|
|
} |
77 |
|
|
for (i=0;i<3;i++) vn[i] = vn[i]/norme ; |
78 |
|
|
/* calcul du vecteur AP et orientation de la face */ |
79 |
|
|
vap[0] = coord[x(nump)] - coord[x(tabele[3*nb_ele])] ; |
80 |
|
|
vap[1] = coord[y(nump)] - coord[y(tabele[3*nb_ele])] ; |
81 |
|
|
vap[2] = coord[z(nump)] - coord[z(tabele[3*nb_ele])] ; |
82 |
|
|
if (PROSCA(vap,vn) < EPSILON) |
83 |
|
|
{ |
84 |
|
|
for (i=0;i<3;i++) vn[i] = -1. * vn[i] ; |
85 |
|
|
i = tabele[3*nb_ele+1] ; |
86 |
|
|
tabele[3*nb_ele+1] = tabele[3*nb_ele+2] ; |
87 |
|
|
tabele[3*nb_ele+2] = i ; |
88 |
|
|
} |
89 |
|
|
/* point optimal */ |
90 |
|
|
tab_opt[x(nb_ele)] = xi + hauteur * vn[0] ; |
91 |
|
|
tab_opt[y(nb_ele)] = yi + hauteur * vn[1] ; |
92 |
|
|
tab_opt[z(nb_ele)] = zi + hauteur * vn[2] ; |
93 |
|
|
} |
94 |
|
|
nb_ele = nb_face ; |
95 |
|
|
/* calcul de la qualite de chaque tetraedre */ |
96 |
|
|
cmin = 1. ; |
97 |
|
|
for (i=0;i<nb_ele;i++) |
98 |
|
|
{ |
99 |
|
|
/* calcul du critere */ |
100 |
|
|
tab_crit[i] = m3d_e_qual2(coord,tabele[3*i],tabele[3*i+1],tabele[3*i+2],nump) ; |
101 |
|
|
if (tab_crit[i]<EPSILON) |
102 |
|
|
{ |
103 |
|
|
// if (debug) aff_text(" critere nul M3D_MOVE \n") ; |
104 |
|
|
m3d_erreur(ERR_SYST) ; |
105 |
|
|
return(FAUX) ; |
106 |
|
|
} |
107 |
|
|
if (tab_crit[i] < cmin) cmin = tab_crit[i] ; |
108 |
|
|
} |
109 |
|
|
/* calcul des coordonnees du point ideal */ |
110 |
|
|
gamma = 0. ; |
111 |
|
|
for (i=0;i<nb_ele;i++) |
112 |
|
|
{ |
113 |
|
|
gamma = gamma + 1./(tab_crit[i]*tab_crit[i]) ;/* somme des carres des inverses */ |
114 |
|
|
} |
115 |
|
|
/* calcul du point optimal pour la boule */ |
116 |
|
|
gamma = 1./gamma ; |
117 |
|
|
vec_opt[0] = 0. ; |
118 |
|
|
vec_opt[1] = 0. ; |
119 |
|
|
vec_opt[2] = 0. ; |
120 |
|
|
|
121 |
|
|
for (i=0;i<nb_ele;i++) |
122 |
|
|
{ |
123 |
|
|
coeff = gamma/(tab_crit[i]*tab_crit[i]) ; |
124 |
|
|
vec_opt[0] = vec_opt[0] + coeff * tab_opt[x(i)] ; |
125 |
|
|
vec_opt[1] = vec_opt[1] + coeff * tab_opt[y(i)] ; |
126 |
|
|
vec_opt[2] = vec_opt[2] + coeff * tab_opt[z(i)] ; |
127 |
|
|
} |
128 |
|
|
|
129 |
|
|
delta[0] = vec_opt[0] - coord[x(nump)] ; |
130 |
|
|
delta[1] = vec_opt[1] - coord[y(nump)] ; |
131 |
|
|
delta[2] = vec_opt[2] - coord[z(nump)] ; |
132 |
|
|
/* sauvegarde du critere mini */ |
133 |
|
|
crit_save = cmin ; |
134 |
|
|
*critere = cmin ; |
135 |
|
|
/* initialisation des bornes du parametre */ |
136 |
|
|
bmin = 0. ; |
137 |
|
|
bmax = 1. ; |
138 |
|
|
sens = 1 ;/* augmnentation */ |
139 |
|
|
|
140 |
|
|
vresu[0] = vec_save[0] ; |
141 |
|
|
vresu[1] = vec_save[1] ; |
142 |
|
|
vresu[2] = vec_save[2] ; |
143 |
|
|
|
144 |
|
|
for (i=0;i<5;i++) |
145 |
|
|
{ |
146 |
|
|
alpha = 0.5 * (bmin + bmax) ; |
147 |
|
|
coord[x(nump)] = vec_save[0] + alpha * delta[0] ; |
148 |
|
|
coord[y(nump)] = vec_save[1] + alpha * delta[1] ; |
149 |
|
|
coord[z(nump)] = vec_save[2] + alpha * delta[2] ; |
150 |
|
|
|
151 |
|
|
/* evaluation de la qualite pour la valeur alpha */ |
152 |
|
|
/* on evalue la qualite cmin pour alpha */ |
153 |
|
|
calpha = 1. ; |
154 |
|
|
for (j=0;j<nb_ele;j++) |
155 |
|
|
{ |
156 |
|
|
/* calcul du critere */ |
157 |
|
|
tab_crit[j] = m3d_e_qual2(coord,tabele[3*j],tabele[3*j+1],tabele[3*j+2],nump) ; |
158 |
|
|
if (tab_crit[j] < calpha) calpha = tab_crit[j] ; |
159 |
|
|
} |
160 |
|
|
/* la valeur du critere pour alpha est superieure, il faut la stocker */ |
161 |
|
|
if (calpha > crit_save) |
162 |
|
|
{ |
163 |
|
|
vresu[0] = coord[x(nump)] ; |
164 |
|
|
vresu[1] = coord[y(nump)] ; |
165 |
|
|
vresu[2] = coord[z(nump)] ; |
166 |
|
|
crit_save = calpha ; |
167 |
|
|
*critere = crit_save ; |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
/* on evalue la qualite c1 pour alpha - eps */ |
171 |
|
|
eps = (bmax-bmin)/50. ; |
172 |
|
|
coord[x(nump)] = vec_save[0] + (alpha - eps) * delta[0] ; |
173 |
|
|
coord[y(nump)] = vec_save[1] + (alpha - eps) * delta[1] ; |
174 |
|
|
coord[z(nump)] = vec_save[2] + (alpha - eps) * delta[2] ; |
175 |
|
|
calpha_moins_eps = 1. ; |
176 |
|
|
for (j=0;j<nb_ele;j++) |
177 |
|
|
{ |
178 |
|
|
/* calcul du critere */ |
179 |
|
|
tab_crit[j] = m3d_e_qual2(coord,tabele[3*j],tabele[3*j+1],tabele[3*j+2],nump) ; |
180 |
|
|
if (tab_crit[j] < calpha_moins_eps) calpha_moins_eps = tab_crit[j] ; |
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
coord[x(nump)] = vec_save[0] + alpha * delta[0] ; |
184 |
|
|
coord[y(nump)] = vec_save[1] + alpha * delta[1] ; |
185 |
|
|
coord[z(nump)] = vec_save[2] + alpha * delta[2] ; |
186 |
|
|
|
187 |
|
|
if (calpha_moins_eps < calpha) |
188 |
|
|
{ |
189 |
|
|
bmin = alpha ; |
190 |
|
|
/* bmax est inchange */ |
191 |
|
|
} |
192 |
|
|
else |
193 |
|
|
{ |
194 |
|
|
/* bmin est inchange */ |
195 |
|
|
bmax = alpha ; |
196 |
|
|
} |
197 |
|
|
} |
198 |
|
|
coord[x(nump)] = vresu[0] ; |
199 |
|
|
coord[y(nump)] = vresu[1] ; |
200 |
|
|
coord[z(nump)] = vresu[2] ; |
201 |
|
|
|
202 |
|
|
return(VRAI) ; |
203 |
|
|
} |
204 |
|
|
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
|
208 |
|
|
|
209 |
|
|
|
210 |
|
|
|