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

File Contents

# User Rev Content
1 5 //------------------------------------------------------------
2     //------------------------------------------------------------
3     // MAGiC
4     // Jean Christophe Cuillière et Vincent FRANCOIS
5     // Département de Génie Mécanique - UQTR
6     //------------------------------------------------------------
7     // Le projet MAGIC est un projet de recherche du département
8     // de génie mécanique de l'Université du Québec à
9     // Trois Rivières
10     // Les librairies ne peuvent être utilisées sans l'accord
11     // des auteurs (contact : francois@uqtr.ca)
12     //------------------------------------------------------------
13     //------------------------------------------------------------
14     //
15     // mailleur2d_outil.cpp
16     //
17     //------------------------------------------------------------
18     //------------------------------------------------------------
19     // COPYRIGHT 2000
20     // Version du 02/03/2006 à 11H23
21     //------------------------------------------------------------
22     //------------------------------------------------------------
23    
24    
25     #include "gestionversion.h"
26     #include <math.h>
27     #include "mailleur2d.h"
28     #include "ot_mathematique.h"
29     #include "ot_boite_2D.h"
30     #include "tpl_map_entite.h"
31     #include "m3d_triangle.h"
32    
33    
34    
35    
36    
37    
38     int MAILLEUR2D::noeud_est_dans_triangle(MG_NOEUD* noeud,MG_TRIANGLE *triangle)
39     {
40     return noeud_est_dans_triangle(noeud,triangle->get_noeud1(),triangle->get_noeud2(),triangle->get_noeud3());
41     }
42    
43    
44     int MAILLEUR2D::noeud_est_dans_triangle(MG_NOEUD* noeud,MG_NOEUD *noeud1,MG_NOEUD *noeud2,MG_NOEUD *noeud3)
45     {
46     double du=decalage->calcul_decalage_parametre_u(noeud1->get_u());
47     double dv=decalage->calcul_decalage_parametre_v(noeud1->get_v());
48    
49     double u1=decalage->decalage_parametre_u(noeud1->get_u(),du);
50     double v1=decalage->decalage_parametre_v(noeud1->get_v(),dv);
51     double u2=decalage->decalage_parametre_u(noeud2->get_u(),du);
52     double v2=decalage->decalage_parametre_v(noeud2->get_v(),dv);
53     double u3=decalage->decalage_parametre_u(noeud3->get_u(),du);
54     double v3=decalage->decalage_parametre_v(noeud3->get_v(),dv);
55     double u=decalage->decalage_parametre_u(noeud->get_u(),du);
56     double v=decalage->decalage_parametre_v(noeud->get_v(),dv);
57     double eps=0.0001;
58     double delta=(u2-u1)*(v3-v1)-(v2-v1)*(u3-u1);
59     double precision=std::max(fabs(u1),fabs(v1));
60     precision=std::max(precision,fabs(u2));
61     precision=std::max(precision,fabs(v2));
62     precision=std::max(precision,fabs(u3));
63     precision=std::max(precision,fabs(v3));
64     precision=std::max(precision,fabs(u));
65     precision=std::max(precision,fabs(v));
66     if (OPERATEUR::egal(delta,0.0,precision*eps)) return(0);
67     double xsi=1.0/delta*((v3-v1)*(u-u1)-(u3-u1)*(v-v1));
68     double eta=1.0/delta*((u2-u1)*(v-v1)-(v2-v1)*(u-u1));
69     if (!((eta > eps) && (xsi > eps) && ((eta+xsi) < 1.0-eps))) return(0);
70     return (1);
71     }
72    
73    
74    
75    
76    
77    
78     int MAILLEUR2D::insere_segment(MG_FACE *mgface,MG_SEGMENT **nv_segment,MG_NOEUD* noeud1,MG_NOEUD* noeud2,int type_validation)
79     {
80    
81     double du=decalage->calcul_decalage_parametre_u(noeud1->get_u());
82     double dv=decalage->calcul_decalage_parametre_v(noeud1->get_v());
83     double u1=decalage->decalage_parametre_u(noeud1->get_u(),du);
84     double v1=decalage->decalage_parametre_v(noeud1->get_v(),dv);
85     double u2=decalage->decalage_parametre_u(noeud2->get_u(),du);
86     double v2=decalage->decalage_parametre_v(noeud2->get_v(),dv);
87     double ui=0.5*(u1+u2);
88     double vi=0.5*(v1+v2);
89     double uii=decalage->decalage_parametre_u(ui,-du);
90     double vii=decalage->decalage_parametre_v(vi,-dv);
91     double longueur=sqrt((u2-u1)*(u2-u1)+(v2-v1)*(v2-v1));
92    
93     if (type_validation==TOUS_SEGMENT)
94     {
95     TPL_MAP_ENTITE<MG_SEGMENT*> liste_trouvee;
96     quadtree_de_segment->rechercher(uii,vii,longueur/2.,liste_trouvee);
97     for (int j=0;j<liste_trouvee.get_nb();j++)
98     {
99     MG_SEGMENT* mgsegment=liste_trouvee.get(j);
100     if ( ((noeud1==mgsegment->get_noeud1()) && (noeud2==mgsegment->get_noeud2())) || ((noeud1==mgsegment->get_noeud2()) && (noeud2==mgsegment->get_noeud1())))
101     return(0);
102     int res=intersection_segment_segment(noeud1,noeud2,mgsegment->get_noeud1(),mgsegment->get_noeud2());
103     if (res!=0)
104     return(0);
105     }
106     }
107     if (type_validation==TOUS_FRONT)
108     {
109     TPL_MAP_ENTITE<MG_FRONT_2D*> liste_trouvee;
110     quadtree_de_front->rechercher(uii,vii,longueur/2.,liste_trouvee);
111     for (int j=0;j<liste_trouvee.get_nb();j++)
112     {
113     MG_FRONT_2D* ft=liste_trouvee.get(j);
114     MG_SEGMENT* mgsegment=ft->get_segment();
115     if ( ((noeud1==mgsegment->get_noeud1()) && (noeud2==mgsegment->get_noeud2())) || ((noeud1==mgsegment->get_noeud2()) && (noeud2==mgsegment->get_noeud1())))
116     return(0);
117     int res=intersection_segment_segment(noeud1,noeud2,mgsegment->get_noeud1(),mgsegment->get_noeud2());
118     if (res!=0)
119     return(0);
120     }
121     }
122    
123     MG_SEGMENT* mgsegment=mg_maillage->ajouter_mg_segment(mgface,noeud1,noeud2);
124     quadtree_de_segment->inserer(mgsegment);
125     *nv_segment=mgsegment;
126     return(1);
127     }
128    
129    
130     void MAILLEUR2D::supprime_segment(MG_SEGMENT* mgsegment)
131     {
132     quadtree_de_segment->supprimer(mgsegment);
133     mg_maillage->supprimer_mg_segmentid(mgsegment->get_id());
134     }
135    
136    
137     int MAILLEUR2D::genere_noeud(MG_FACE* mgface,MG_FRONT_2D* front,MG_FRONT_2D **front_rencontre,MG_NOEUD **noeud_rencontre)
138     {
139     OT_VECTEUR_3D w(0.,0.,1.);
140     MG_NOEUD* noeud1=front->get_noeud1();
141     MG_NOEUD* noeud2=front->get_noeud2();
142     double du=decalage->calcul_decalage_parametre_u(noeud1->get_u());
143     double dv=decalage->calcul_decalage_parametre_v(noeud1->get_v());
144     double u1=decalage->decalage_parametre_u(noeud1->get_u(),du);
145     double v1=decalage->decalage_parametre_v(noeud1->get_v(),dv);
146     double u2=decalage->decalage_parametre_u(noeud2->get_u(),du);
147     double v2=decalage->decalage_parametre_v(noeud2->get_v(),dv);
148    
149     double longueur_segment=calcule_longueur_segment_metrique(mgface,front->get_segment());
150     double longueur_desiree=0.8660254037844386*(MAILLEUR2D::priorite_metrique+longueur_segment-longueur_segment*MAILLEUR2D::priorite_metrique);
151     longueur_desiree=longueur_desiree/front->get_ifail();
152    
153    
154     double longueur_calculee=0.;
155     double longueur_calculee_pas_precedent;
156     double umilieu=0.5*(u1+u2);
157     double vmilieu=0.5*(v1+v2);
158     double param_milieu[2]={umilieu-du,vmilieu-dv};
159     double E,F,G;
160    
161     // je pense qu il faudrait changer ici
162     // perpendiculaire dans l espace parametrique ou perpendiculaire dans la metrique ou dans la combinaison des deux
163     mgface->get_EFG(param_milieu,E,F,G);
164     double deno=E*(u2-u1)*(u2-u1)+G*(v2-v1)*(v2-v1)+2*F*(u2-u1)*(v2-v1);
165     double nume=(v2-v1)*(u2-u1)*(E-G)+F*((v2-v1)*(v2-v1)-(u2-u1)*(u2-u1));
166     double teta=atan(nume/deno);
167    
168     /*double tenseur_metrique[9];
169     double xyzdu[3];
170     double xyzdv[3];
171     metrique->evaluer(param_milieu,tenseur_metrique);
172     mgface->deriver(param_milieu,xyzdu,xyzdv);
173    
174     E = (xyzdu[0]*tenseur_metrique[0]+xyzdu[1]*tenseur_metrique[1]+xyzdu[2]*tenseur_metrique[2])*xyzdu[0]+(xyzdu[0]*tenseur_metrique[1]+xyzdu[1]*tenseur_metrique[4]+xyzdu[2]*tenseur_metrique[5])*xyzdu[1]+(xyzdu[0]*tenseur_metrique[2]+xyzdu[1]*tenseur_metrique[5]+xyzdu[2]*tenseur_metrique[8])*xyzdu[2];
175     F = (xyzdv[0]*tenseur_metrique[0]+xyzdv[1]*tenseur_metrique[1]+xyzdv[2]*tenseur_metrique[2])*xyzdu[0]+(xyzdv[0]*tenseur_metrique[1]+xyzdv[1]*tenseur_metrique[4]+xyzdv[2]*tenseur_metrique[5])*xyzdu[1]+(xyzdv[0]*tenseur_metrique[2]+xyzdv[1]*tenseur_metrique[5]+xyzdv[2]*tenseur_metrique[8])*xyzdu[2];
176     G = (xyzdv[0]*tenseur_metrique[0]+xyzdv[1]*tenseur_metrique[1]+xyzdv[2]*tenseur_metrique[2])*xyzdv[0]+(xyzdv[0]*tenseur_metrique[1]+xyzdv[1]*tenseur_metrique[4]+xyzdv[2]*tenseur_metrique[5])*xyzdv[1]+(xyzdv[0]*tenseur_metrique[2]+xyzdv[1]*tenseur_metrique[5]+xyzdv[2]*tenseur_metrique[8])*xyzdv[2];
177    
178     double deno=E*(u2-u1)*(u2-u1)+G*(v2-v1)*(v2-v1)+2*F*(u2-u1)*(v2-v1);
179     double nume=(v2-v1)*(u2-u1)*(E-G)+F*((v2-v1)*(v2-v1)-(u2-u1)*(u2-u1));
180     double teta=atan(nume/deno);
181    
182     */
183    
184     OT_VECTEUR_3D vecteur_du_front(u2-u1,v2-v1,0.);
185     OT_VECTEUR_3D vecteur_normal_front=w&vecteur_du_front;
186     double longueur_parametrique=vecteur_du_front.get_longueur();
187     vecteur_du_front.norme();
188     vecteur_normal_front.norme();
189     double dt=0.03125;
190     double ti;
191     double tii=0;
192     double uii;
193     double vii;
194     while (longueur_calculee<longueur_desiree)
195     {
196     refresh();
197     ti=tii;
198     dt=0.03125;
199     double param_tii[2];
200     int valide_u=0;
201     int valide_v=0;
202     int valide_xyz=0;
203     while ((valide_u & valide_v & valide_xyz)!=1)
204     {
205     tii=ti+longueur_parametrique*dt;
206     uii=umilieu+tii*(vecteur_du_front.get_x()*sin(teta)+vecteur_normal_front.get_x()*cos(teta));
207     vii=vmilieu+tii*(vecteur_du_front.get_y()*sin(teta)+vecteur_normal_front.get_y()*cos(teta));
208     param_tii[0]=uii-du;
209     param_tii[1]=vii-dv;
210     if (mgface->valide_parametre_u(param_tii[0])) valide_u=1;
211     if (mgface->valide_parametre_v(param_tii[1])) valide_v=1;
212     if ((valide_u & valide_v)!=1) dt=dt/2.;
213     if ((valide_u & valide_v)==1)
214     {
215     double xyz[3];
216     mgface->evaluer(param_tii,xyz);
217     valide_xyz=metrique->valide_parametre(xyz);
218     if ((valide_xyz)!=1) dt=dt/2.;
219     }
220     if (dt<0.0000001) return ERREUR;
221     }
222     longueur_calculee_pas_precedent=longueur_calculee;
223     double t=0.7886751345*ti+0.2113248654*tii;
224     double ut=vecteur_du_front.get_x()*sin(teta)+vecteur_normal_front.get_x()*cos(teta);
225     double vt=vecteur_du_front.get_y()*sin(teta)+vecteur_normal_front.get_y()*cos(teta);
226     double u=umilieu+t*ut;
227     double v=vmilieu+t*vt;;
228     double param_integration1[2]={u-du,v-dv};
229     double tenseur_metrique[9];
230     double xyzdu[3];
231     double xyzdv[3];
232     if (creation_metrique) metrique->evaluer(param_integration1,tenseur_metrique);
233     else
234     {
235     double xyz[3];
236     mgface->evaluer(param_integration1,xyz);
237     metrique->evaluer(xyz,tenseur_metrique);
238     }
239     mgface->deriver(param_integration1,xyzdu,xyzdv);
240     double t3 = xyzdu[0]*ut+xyzdv[0]*vt;
241     double t7 = xyzdu[1]*ut+xyzdv[1]*vt;
242     double t11 = xyzdu[2]*ut+xyzdv[2]*vt;
243     double t13 = t3*tenseur_metrique[0]+t7*tenseur_metrique[3]+t11*tenseur_metrique[6];
244     double t18 = t3*tenseur_metrique[1]+t7*tenseur_metrique[4]+t11*tenseur_metrique[7];
245     double t23 = t3*tenseur_metrique[2]+t7*tenseur_metrique[5]+t11*tenseur_metrique[8];
246     double facteur = (t13*xyzdu[0]+t18*xyzdu[1]+t23*xyzdu[2])*ut+(t13*xyzdv[0]+t18*xyzdv[1]+t23*xyzdv[2])*vt;
247     longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(facteur);
248     t=0.7886751345*tii+0.2113248654*ti;
249     u=umilieu+t*ut;
250     v=vmilieu+t*vt;;
251     double param_integration2[2]={u-du,v-dv};
252     if (creation_metrique) metrique->evaluer(param_integration2,tenseur_metrique);
253     else
254     {
255     double xyz[3];
256     mgface->evaluer(param_integration2,xyz);
257     metrique->evaluer(xyz,tenseur_metrique);
258     }
259     mgface->deriver(param_integration2,xyzdu,xyzdv);
260     t3 = xyzdu[0]*ut+xyzdv[0]*vt;
261     t7 = xyzdu[1]*ut+xyzdv[1]*vt;
262     t11 = xyzdu[2]*ut+xyzdv[2]*vt;
263     t13 = t3*tenseur_metrique[0]+t7*tenseur_metrique[3]+t11*tenseur_metrique[6];
264     t18 = t3*tenseur_metrique[1]+t7*tenseur_metrique[4]+t11*tenseur_metrique[7];
265     t23 = t3*tenseur_metrique[2]+t7*tenseur_metrique[5]+t11*tenseur_metrique[8];
266     facteur = (t13*xyzdu[0]+t18*xyzdu[1]+t23*xyzdu[2])*ut+(t13*xyzdv[0]+t18*xyzdv[1]+t23*xyzdv[2])*vt;
267     longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(facteur);
268     }
269     double ut=vecteur_du_front.get_x()*sin(teta)+vecteur_normal_front.get_x()*cos(teta);
270     double vt=vecteur_du_front.get_y()*sin(teta)+vecteur_normal_front.get_y()*cos(teta);
271     double t=ti+(tii-ti)*(longueur_desiree-longueur_calculee_pas_precedent)/(longueur_calculee-longueur_calculee_pas_precedent);
272     double udecale=umilieu+t*ut;
273     double vdecale=vmilieu+t*vt;
274     double u=decalage->decalage_parametre_u(udecale,-du);
275     double v=decalage->decalage_parametre_v(vdecale,-dv);
276     double param_noeud_cree[2]={u,v};
277    
278    
279     // recherhce des element du front proche de u,v;
280     TPL_MAP_ENTITE<MG_FRONT_2D*> liste_trouvee;
281    
282     double umin=std::min(u1,u2);
283     umin=std::min(umin,udecale);
284     double umax=std::max(u1,u2);
285     umax=std::max(umax,udecale);
286     double vmin=std::min(v1,v2);
287     vmin=std::min(vmin,vdecale);
288     double vmax=std::max(v1,v2);
289     vmax=std::max(vmax,vdecale);
290     BOITE_2D boite_recherche(umin,vmin,umax,vmax);
291     double longueur_recherche=boite_recherche.get_rayon()*2.;
292    
293     quadtree_de_front->rechercher(u,v,longueur_recherche,liste_trouvee);
294     int nb_entite=liste_trouvee.get_nb();
295    
296     double distance_reference = -1.;
297     double angle_reference=2.*M_PI;
298     unsigned long id_noeud_reference = 0;
299     MG_FRONT_2D* front_reference=NULL;
300    
301     for (int i=0;i<nb_entite;i++)
302     {
303     MG_FRONT_2D* front_courant=liste_trouvee.get(i);
304     MG_NOEUD* noeud_front1=front_courant->get_noeud1();
305     MG_NOEUD* noeud_front2=front_courant->get_noeud2();
306     double unoeudfront1=decalage->decalage_parametre_u(noeud_front1->get_u(),du);
307     double vnoeudfront1=decalage->decalage_parametre_v(noeud_front1->get_v(),dv);
308     double unoeudfront2=decalage->decalage_parametre_u(noeud_front2->get_u(),du);
309     double vnoeudfront2=decalage->decalage_parametre_v(noeud_front2->get_v(),dv);
310     double distance_noeudfront1=calcule_distance_metrique(mgface,udecale,vdecale,unoeudfront1,vnoeudfront1,du,dv);
311     if ((distance_noeudfront1<distance_reference) || (distance_reference<0.) || (id_noeud_reference==noeud_front1->get_id()))
312     if (noeud_front1->get_id()!=noeud1->get_id())
313     if (noeud_front1->get_id()!=noeud2->get_id())
314     if (id_noeud_reference==noeud_front1->get_id())
315     {
316     refresh();
317     OT_VECTEUR_3D vecteur_baseu(u1-unoeudfront1,v1-vnoeudfront1,0.);
318     OT_VECTEUR_3D vecteur_front(unoeudfront2-unoeudfront1,vnoeudfront2-vnoeudfront1,0.);
319     OT_VECTEUR_3D vecteur_basev=w&vecteur_baseu;
320     vecteur_baseu.norme();
321     vecteur_basev.norme();
322     vecteur_front.norme();
323     double cosangle=vecteur_baseu*vecteur_front;
324     double sinangle=vecteur_basev*vecteur_front;
325     sinangle=-sinangle;
326     if (cosangle>1.) cosangle=1.;
327     if (cosangle<-1.) cosangle=(-1.);
328     double angle=acos(cosangle);
329     if (sinangle<(-0.0001)) angle=(-angle);
330     if (angle<0.) angle=angle+2.*M_PI;
331     if (angle<angle_reference)
332     {
333     angle_reference=angle;
334     front_reference=front_courant;
335     }
336     }
337     else
338     {
339     refresh();
340     OT_VECTEUR_3D vecteur_baseu(u1-unoeudfront1,v1-vnoeudfront1,0.);
341     OT_VECTEUR_3D vecteur_front(unoeudfront2-unoeudfront1,vnoeudfront2-vnoeudfront1,0.);
342     OT_VECTEUR_3D vecteur_basev=w&vecteur_baseu;
343     vecteur_baseu.norme();
344     vecteur_basev.norme();
345     vecteur_front.norme();
346     double cosangle=vecteur_baseu*vecteur_front;
347     double sinangle=vecteur_basev*vecteur_front;
348     sinangle=-sinangle;
349     if (cosangle>1.) cosangle=1.;
350     if (cosangle<-1.) cosangle=(-1.);
351     double angle=acos(cosangle);
352     if (sinangle<(-0.0001)) angle=(-angle);
353     if (angle<0.) angle=angle+2.*M_PI;
354     distance_reference=distance_noeudfront1;
355     angle_reference=angle;
356     id_noeud_reference=noeud_front1->get_id();
357     front_reference=front_courant;
358     }
359     }
360    
361     if ((front_reference!=NULL) && (distance_reference<longueur_desiree*2./sqrt(3)))
362     {
363     MG_NOEUD* noeud=mg_maillage->get_mg_noeudid(id_noeud_reference);
364     double uref=decalage->decalage_parametre_u(noeud->get_u(),du);
365     double vref=decalage->decalage_parametre_v(noeud->get_v(),dv);
366     double distance=calcule_distance_metrique(mgface,umilieu,vmilieu,uref,vref,du,dv);
367     if (distance<1.5*longueur_desiree)
368     {
369     (*front_rencontre)=front_reference;
370     (*noeud_rencontre)=noeud;
371     return FRONT_RENCONTRE;
372     }
373     }
374     double coord[3];
375     mgface->evaluer(param_noeud_cree,coord);
376     MG_NOEUD* noeud=mg_maillage->ajouter_mg_noeud(mgface,coord[0],coord[1],coord[2]);
377     noeud->change_u(param_noeud_cree[0]);
378     noeud->change_v(param_noeud_cree[1]);
379     (*noeud_rencontre)=noeud;
380     (*front_rencontre)=NULL;
381     return NOEUD_CREE;
382     }
383    
384    
385     double MAILLEUR2D::calcule_longueur_segment_metrique(MG_FACE* mgface,MG_SEGMENT* mgsegment)
386     {
387     MG_NOEUD* noeud1=mgsegment->get_noeud1();
388     MG_NOEUD* noeud2=mgsegment->get_noeud2();
389    
390     double du=decalage->calcul_decalage_parametre_u(noeud1->get_u());
391     double dv=decalage->calcul_decalage_parametre_v(noeud1->get_v());
392     double u1=decalage->decalage_parametre_u(noeud1->get_u(),du);
393     double v1=decalage->decalage_parametre_v(noeud1->get_v(),dv);
394     double u2=decalage->decalage_parametre_u(noeud2->get_u(),du);
395     double v2=decalage->decalage_parametre_v(noeud2->get_v(),dv);
396     return calcule_distance_metrique(mgface,u1,v1,u2,v2,du,dv);
397     }
398    
399    
400     double MAILLEUR2D::calcule_distance_metrique(MG_FACE* mgface,double u1,double v1,double u2,double v2,double du,double dv)
401     {
402     double longueur_calculee=0.;
403     double param_debut[2]={u1-du,v1-dv};
404     double E,F,G;
405     mgface->get_EFG(param_debut,E,F,G);
406    
407     double dt=0.03125;
408     double ti;
409     double tii=0;
410    
411     while (tii<1.)
412     {
413     refresh();
414     ti=tii;
415     tii=ti+dt;
416     if (tii>1.) tii=1.;
417     double t=0.7886751345*ti+0.2113248654*tii;
418     double u=u1+t*(u2-u1);
419     double v=v1+t*(v2-v1);
420     double ut=u2-u1;
421     double vt=v2-v1;
422     double param_integration1[2]={u-du,v-dv};
423     double tenseur_metrique[9];
424     double xyzdu[3];
425     double xyzdv[3];
426     if (creation_metrique) metrique->evaluer(param_integration1,tenseur_metrique);
427     else
428     {
429     double xyz[3];
430     mgface->evaluer(param_integration1,xyz);
431     metrique->evaluer(xyz,tenseur_metrique);
432     }
433     mgface->deriver(param_integration1,xyzdu,xyzdv);
434     double t3 = xyzdu[0]*ut+xyzdv[0]*vt;
435     double t7 = xyzdu[1]*ut+xyzdv[1]*vt;
436     double t11 = xyzdu[2]*ut+xyzdv[2]*vt;
437     double t13 = t3*tenseur_metrique[0]+t7*tenseur_metrique[3]+t11*tenseur_metrique[6];
438     double t18 = t3*tenseur_metrique[1]+t7*tenseur_metrique[4]+t11*tenseur_metrique[7];
439     double t23 = t3*tenseur_metrique[2]+t7*tenseur_metrique[5]+t11*tenseur_metrique[8];
440     double facteur = (t13*xyzdu[0]+t18*xyzdu[1]+t23*xyzdu[2])*ut+(t13*xyzdv[0]+t18*xyzdv[1]+t23*xyzdv[2])*vt;
441     longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(facteur);
442     t=0.7886751345*tii+0.2113248654*ti;
443     u=u1+t*(u2-u1);
444     v=v1+t*(v2-v1);
445     double param_integration2[2]={u-du,v-dv};
446     if (creation_metrique) metrique->evaluer(param_integration2,tenseur_metrique);
447     else
448     {
449     double xyz[3];
450     mgface->evaluer(param_integration2,xyz);
451     metrique->evaluer(xyz,tenseur_metrique);
452     }
453     mgface->deriver(param_integration2,xyzdu,xyzdv);
454     t3 = xyzdu[0]*ut+xyzdv[0]*vt;
455     t7 = xyzdu[1]*ut+xyzdv[1]*vt;
456     t11 = xyzdu[2]*ut+xyzdv[2]*vt;
457     t13 = t3*tenseur_metrique[0]+t7*tenseur_metrique[3]+t11*tenseur_metrique[6];
458     t18 = t3*tenseur_metrique[1]+t7*tenseur_metrique[4]+t11*tenseur_metrique[7];
459     t23 = t3*tenseur_metrique[2]+t7*tenseur_metrique[5]+t11*tenseur_metrique[8];
460     facteur = (t13*xyzdu[0]+t18*xyzdu[1]+t23*xyzdu[2])*ut+(t13*xyzdv[0]+t18*xyzdv[1]+t23*xyzdv[2])*vt;
461     longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(facteur);
462     }
463     return longueur_calculee;
464     }
465    
466    
467    
468    
469    
470    
471     MG_TRIANGLE* MAILLEUR2D::insere_triangle(MG_ELEMENT_TOPOLOGIQUE* topo,class MG_NOEUD *mgnoeud1,class MG_NOEUD *mgnoeud2,class MG_NOEUD *mgnoeud3)
472     {
473     MG_SEGMENT* mgsegment1=mg_maillage->get_mg_segment(mgnoeud1->get_id(),mgnoeud2->get_id());
474     MG_SEGMENT* mgsegment2=mg_maillage->get_mg_segment(mgnoeud2->get_id(),mgnoeud3->get_id());
475     MG_SEGMENT* mgsegment3=mg_maillage->get_mg_segment(mgnoeud3->get_id(),mgnoeud1->get_id());
476     if (mgsegment1==NULL) mgsegment1=mg_maillage->ajouter_mg_segment(topo,mgnoeud1,mgnoeud2);
477     if (mgsegment2==NULL) mgsegment2=mg_maillage->ajouter_mg_segment(topo,mgnoeud2,mgnoeud3);
478     if (mgsegment3==NULL) mgsegment3=mg_maillage->ajouter_mg_segment(topo,mgnoeud3,mgnoeud1);
479     M3D_TRIANGLE* mtriangle=new M3D_TRIANGLE(topo,mgnoeud1,mgnoeud2,mgnoeud3,mgsegment1,mgsegment2,mgsegment3);
480     mg_maillage->ajouter_mg_triangle(mtriangle);
481     double qual=OPERATEUR::qualite_triangle(mgnoeud1->get_coord(),mgnoeud2->get_coord(),mgnoeud3->get_coord());
482     mtriangle->change_qualite(qual);
483     std::pair<const double,M3D_TRIANGLE*> tmp(mtriangle->get_qualite(),mtriangle);
484     lst_tri_qual.insert(tmp);
485     return mtriangle;
486     }
487    
488     int MAILLEUR2D::triangle_est_dans_bon_sens(MG_FACE* face,MG_NOEUD* noeud1,MG_NOEUD *noeud2,MG_NOEUD *noeud3)
489     {
490     double* xyz1=noeud1->get_coord();
491     double* xyz2=noeud2->get_coord();
492     double* xyz3=noeud3->get_coord();
493     OT_VECTEUR_3D n1n3(xyz1,xyz3);
494     OT_VECTEUR_3D n1n2(xyz1,xyz2);
495     double uv[2];
496     face->inverser(uv,xyz1);
497     double n[3];
498     face->calcul_normale_unitaire(uv,n);
499     OT_VECTEUR_3D nmat=n&n1n3;
500     nmat.norme();
501     n1n2.norme();
502     if (nmat*n1n2<0) return 0;
503     return 1;
504     }
505    
506     int MAILLEUR2D::bouge_point(MG_FACE* mgface,MG_NOEUD* mg_noeud,double& crit,double &u,double& v,double& x,double& y, double& z)
507     {
508     if (mg_noeud->get_lien_topologie()!=mgface) return 0;
509     if (mg_noeud->get_id()<=idavantprogresse) return 0;
510     double du=decalage->calcul_decalage_parametre_u(mg_noeud->get_u());
511     double dv=decalage->calcul_decalage_parametre_v(mg_noeud->get_v());
512     double u1=decalage->decalage_parametre_u(mg_noeud->get_u(),du);
513     double v1=decalage->decalage_parametre_v(mg_noeud->get_v(),dv);
514    
515     double uopt=0.;
516     double vopt=0.;
517     double qual_dep=1.;
518     int nb_tri=mg_noeud->get_lien_triangle()->get_nb();
519     for (int i=0;i<nb_tri;i++)
520     {
521     M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i);
522     qual_dep=std::min(qual_dep,tri->get_qualite());
523     MG_NOEUD* no1=tri->get_noeud1();
524     MG_NOEUD* no2=tri->get_noeud2();
525     MG_NOEUD* no3=tri->get_noeud3();
526     MG_NOEUD *noeud1,*noeud2;
527     if (no1==mg_noeud)
528     {
529     noeud1=no2;
530     noeud2=no3;
531     }
532     if (no2==mg_noeud)
533     {
534     noeud1=no1;
535     noeud2=no3;
536     }
537     if (no3==mg_noeud)
538     {
539     noeud1=no1;
540     noeud2=no2;
541     }
542     double u2=noeud1->get_u()+du;
543     double v2=noeud1->get_v()+dv;
544     uopt=uopt+u2;
545     vopt=vopt+v2;
546     u2=noeud2->get_u()+du;
547     v2=noeud2->get_v()+dv;
548     uopt=uopt+u2;
549     vopt=vopt+v2;
550     }
551     uopt=uopt/2./nb_tri;
552     vopt=vopt/2./nb_tri;
553    
554     double ddeb=sqrt((u1-uopt)*(u1-uopt)+(v1-vopt)*(v1-vopt));
555     double alpha=0.5;
556     double d=alpha*ddeb;
557     double qual=qual_dep;
558     double testu[8]={1.,-1.,0.,0.,0.707106781,-0.707106781,-0.707106781,0.707106781};
559     double testv[8]={0.,0.,1.,-1.,0.707106781,0.707106781,-0.707106781,-0.707106781};
560     double uu=u1;
561     double vv=v1;
562     while (alpha>0.09)
563     {
564     double qualcoq=0.;
565     for (int nb_essai=0;nb_essai<8;nb_essai++)
566     {
567     double uv[2];
568     double xyz[3];
569     uv[0]=uu+d*testu[nb_essai]-du;
570     uv[1]=vv+d*testv[nb_essai]-dv;
571     int valide1=mgface->valide_parametre_u(uv[0]);
572     int valide2=mgface->valide_parametre_v(uv[1]);
573     if (!((valide1) && (valide2) )) break;
574     mgface->evaluer(uv,xyz);
575     double qual1=1.;
576     for (int i=0;i<nb_tri;i++)
577     {
578     M3D_TRIANGLE* tri=(M3D_TRIANGLE*)mg_noeud->get_lien_triangle()->get(i);
579     MG_NOEUD* no1=tri->get_noeud1();
580     MG_NOEUD* no2=tri->get_noeud2();
581     MG_NOEUD* no3=tri->get_noeud3();
582     double *xyz1=no1->get_coord();
583     double *xyz2=no2->get_coord();
584     double *xyz3=no3->get_coord();
585     if (no1==mg_noeud) xyz1=xyz;
586     if (no2==mg_noeud) xyz2=xyz;
587     if (no3==mg_noeud) xyz3=xyz;
588     double qualtmp=OPERATEUR::qualite_triangle(xyz1,xyz2,xyz3);
589     OT_VECTEUR_3D n1n3(xyz1,xyz3);
590     OT_VECTEUR_3D n1n2(xyz1,xyz2);
591     double xyznormal[3];
592     mgface->calcul_normale_unitaire(uv,xyznormal);
593     OT_VECTEUR_3D normalface(xyznormal);
594     OT_VECTEUR_3D normal=normalface&n1n3;
595     normal.norme();
596     n1n2.norme();
597     if (normal*n1n2<0.0001) qualtmp=0.;
598     if (qualtmp<qual1) qual1=qualtmp;
599     }
600     if (qual1>qualcoq)
601     {
602     qualcoq=qual1;
603     crit=qualcoq;
604     u=uv[0]+du;
605     v=uv[1]+dv;
606     }
607     }
608    
609     if (qualcoq<qual+0.0001) alpha=alpha-0.1;
610     else
611     {
612     qual=qualcoq;
613     uu=u;
614     vv=v;
615     }
616     d=ddeb*alpha;
617    
618     }
619     if (qual>qual_dep)
620     {
621     u=decalage->decalage_parametre_u(u,-du);
622     v=decalage->decalage_parametre_v(v,-dv);
623     double uv[2];
624     uv[0]=u;
625     uv[1]=v;
626     double xyz[3];
627     mgface->evaluer(uv,xyz);
628     x=xyz[0];
629     y=xyz[1];
630     z=xyz[2];
631     return 1;
632     }
633     return 0;
634     }
635    
636    
637    
638    
639    
640    
641    
642    
643    
644    
645    
646    
647    
648    
649    
650     // PARTIE DE CODE RECUPERER DE MON PROJET DE DEA
651     // TRES ILLISIBLE MAIS FONCTIONNEL
652     // POIL AU MARRON
653    
654     #define PSCA(a,b) (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])
655     #define EGAL(x,y,eps) (float)fabs((double)(x-y))<eps
656     #define DETER(a,b,c,d) (a*d-b*c)
657    
658     int MAILLEUR2D::intersection_segment_segment(MG_NOEUD* noeud1,MG_NOEUD* noeud2,MG_NOEUD* noeud3,MG_NOEUD* noeud4)
659     {
660    
661     double du=decalage->calcul_decalage_parametre_u(noeud1->get_u());
662     double dv=decalage->calcul_decalage_parametre_v(noeud1->get_v());
663     double ua=decalage->decalage_parametre_u(noeud1->get_u(),du);
664     double va=decalage->decalage_parametre_v(noeud1->get_v(),dv);
665     double ub=decalage->decalage_parametre_u(noeud2->get_u(),du);
666     double vb=decalage->decalage_parametre_v(noeud2->get_v(),dv);
667     double um=decalage->decalage_parametre_u(noeud3->get_u(),du);
668     double vm=decalage->decalage_parametre_v(noeud3->get_v(),dv);
669     double un=decalage->decalage_parametre_u(noeud4->get_u(),du);
670     double vn=decalage->decalage_parametre_v(noeud4->get_v(),dv);
671     double ab[3];
672     double nm[3];
673     double am[3];
674     ab[0]=ub-ua;
675     ab[1]=vb-va;
676     ab[2]=0.;
677     nm[0]=um-un;
678     nm[1]=vm-vn;
679     nm[2]=0.;
680     am[0]=um-ua;
681     am[1]=vm-va;
682     am[2]=0.;
683     int equation[4];
684     equation[0]=1; /* etat de l'equation 0 */
685     equation[1]=1;
686     equation[2]=1;
687     equation[3]=3; /* cette variable comporte le bilan du nombre d'equation */
688     double eps2=PSCA(ab,ab);
689     double eps=sqrt(eps2);
690     eps=eps*0.0001;
691     eps2=eps2*0.0001;
692     /* recherche du nombre d'equation -> inter franche ou para ou confondu */
693     if ( (EGAL(ab[0],0,eps)) && (EGAL(nm[0],0,eps)) )
694     if (EGAL(am[0],0,eps)) equation[0]=0; else return(0);
695     if ( (EGAL(ab[1],0,eps)) && (EGAL(nm[1],0,eps)) )
696     if (EGAL(am[1],0,eps)) equation[1]=0; else return(0);
697     if ( (EGAL(ab[2],0,eps)) && (EGAL(nm[2],0,eps)) )
698     if (EGAL(am[2],0,eps)) equation[2]=0; else return(0);
699     equation[3]=equation[0]+equation[1]+equation[2];
700     if (equation[3]==3)
701     {
702     double det=DETER(ab[0],nm[0],ab[1],nm[1]);
703     if (fabs(det)>eps2)
704     {
705     det=1/det;
706     double sol1=det*DETER(am[0],nm[0],am[1],nm[1]);
707     double sol2=det*DETER(ab[0],am[0],ab[1],am[1]);
708     if ( (float)fabs((double)(sol1*ab[2]-sol2*nm[2]-am[2]))>eps2) return(0);
709     return(examine_solution(sol1,sol2,1));
710     }
711     else
712     {
713     equation[0]=0;
714     equation[3]=2;
715     /* on verifie la compatibilite des deux equations dont le det est nul*/
716     double tmp;
717     if (ab[0]!=0) tmp=ab[1]*am[0]/ab[0]; else tmp=nm[1]*am[0]/nm[0];
718     if (!(EGAL(tmp,am[1],eps))) return(0);
719     }
720     }
721     if (equation[3]==2)
722     {
723     /* on repere les equations qui existent */
724     int ne1;
725     int ne2;
726     if (equation[0]!=0)
727     {
728     ne1=0;
729     if (equation[1]!=0) ne2=1; else ne2=2;
730     }
731     else
732     {
733     ne1=1;
734     ne2=2;
735     }
736    
737     double det=DETER(ab[ne1],nm[ne1],ab[ne2],nm[ne2]);
738     if (fabs(det)>eps2)
739     {
740     det=1/det;
741     double sol1=det*DETER(am[ne1],nm[ne1],am[ne2],nm[ne2]);
742     double sol2=det*DETER(ab[ne1],am[ne1],ab[ne2],am[ne2]);
743     return(examine_solution(sol1,sol2,1));
744     }
745     else
746     {
747     equation[ne1]=0;
748     equation[3]=1;
749     /* on verifie la compatibilite des deux equations dont le det est nul */
750     double tmp;
751     if (ab[ne1]!=0) tmp=ab[ne2]*am[ne1]/ab[ne1]; else tmp=nm[ne2]*am[ne1]/nm[ne1];
752     if (!(EGAL(tmp,am[ne2],eps))) return(0);
753     }
754    
755     }
756     if (equation[3]==1)
757     {
758     /* on repere l' equation qui existe */
759     int ne1;
760     if (equation[0]!=0) ne1=0; else
761     if (equation[1]!=0) ne1=1; else ne1=2;
762     double an[3];
763     an[0]=un-ua;
764     an[1]=vn-va;
765     an[2]=0.;
766     double tmp=1/ab[ne1];
767     double sol1=am[ne1]*tmp;
768     double sol2=an[ne1]*tmp;
769     return(examine_solution(sol1,sol2,2));
770     }
771     return(0);
772     }
773    
774    
775    
776     int MAILLEUR2D::examine_solution(double sol1,double sol2,int type)
777     {
778     double epsilon=0.0001;
779    
780     if (type==1)
781     {
782     if ( (sol1>epsilon) && ((sol1)<(1-epsilon)) && (sol2>epsilon) && ((sol2)<(1-epsilon)) ) return 1;
783     if ( ( (EGAL(sol1,0,epsilon)) || (EGAL(sol1,1,epsilon))) && ( (sol2>epsilon) && ((sol2)<(1-epsilon)) ) ) return 1;
784     if ( ( (EGAL(sol2,0,epsilon)) || (EGAL(sol2,1,epsilon))) && ( (sol1>epsilon) && ((sol1)<(1-epsilon)) ) ) return 1;
785     if ( (sol1>epsilon) && ((sol1)<(1-epsilon)) && (sol2>(-0.1-epsilon)) && ((sol2)<(1.1-epsilon)) ) return 1;
786     if ( (sol2>epsilon) && ((sol2)<(1-epsilon)) && (sol1>(-0.1-epsilon)) && ((sol1)<(1.1-epsilon)) ) return 1;
787    
788     }
789     if (type==2)
790     {
791     if ( (sol1>epsilon) && ((sol1)<(1-epsilon)) ) return 1;
792     if ( (sol2>epsilon) && ((sol2)<(1-epsilon)) ) return 1;
793     if ( ((sol1)>(1+epsilon)) && ((-sol2)>epsilon) ) return 1;
794     if ( ((sol2)>(1+epsilon)) && ((-sol1)>epsilon) ) return 1;
795     }
796     return 0;
797     }
798     #undef EGAL
799     #undef PSCA
800     #undef DETER
801     ///FIN DU CODE DE DEA