MAGiC  V5.0
Mailleurs Automatiques de Géometries intégrés à la Cao
fct_taille_face.cpp
Aller à la documentation de ce fichier.
1 //####//------------------------------------------------------------
2 //####//------------------------------------------------------------
3 //####// MAGiC
4 //####// Jean Christophe Cuilliere et Vincent FRANCOIS
5 //####// Departement de Genie Mecanique - UQTR
6 //####//------------------------------------------------------------
7 //####// MAGIC est un projet de recherche de l equipe ERICCA
8 //####// du departement de genie mecanique de l Universite du Quebec a Trois Rivieres
9 //####// http://www.uqtr.ca/ericca
10 //####// http://www.uqtr.ca/
11 //####//------------------------------------------------------------
12 //####//------------------------------------------------------------
13 //####//
14 //####// fct_taille_face.cpp
15 //####//
16 //####//------------------------------------------------------------
17 //####//------------------------------------------------------------
18 //####// COPYRIGHT 2000-2024
19 //####// jeu 13 jun 2024 11:58:52 EDT
20 //####//------------------------------------------------------------
21 //####//------------------------------------------------------------
22 
23 
24 #include "gestionversion.h"
25 #include <math.h>
26 #include "fct_taille_face.h"
27 #include "ot_mathematique.h"
28 
29 
30 
31 
32 
33 FCT_TAILLE_FACE::FCT_TAILLE_FACE(double eps,double dist,MG_FACE* mgface,LISTE_FRONTIERE *segment_frontiere):FCT_TAILLE_METRIQUE(),epsilon(eps),distance_maximale(dist),face(mgface),frontiere(segment_frontiere)
34 {
35  double periode_u=mgface->get_surface()->get_periode_u();
36  double periode_v=mgface->get_surface()->get_periode_v();
37  decalage=new OT_DECALAGE_PARAMETRE(periode_u,periode_v);
38 }
39 
40 
42 {
43  delete decalage;
44 }
45 
46 void FCT_TAILLE_FACE::evaluer(double *param,double *resultat)
47 {
48  double M1,M2,M3;
49  face->get_M(param,M1,M2,M3);
50  double facteur_eps;
51  if (!(OPERATEUR::egal(M1+2.*M2+M3,0.,0.000001)))
52  facteur_eps=sqrt(4.5*epsilon/(M1+2.*M2+M3));
53  else
54  facteur_eps=distance_maximale*2.;
55  double facteur_dist=distance_maximale;
56  double h=std::min(facteur_eps,facteur_dist);
57  resultat[0]=1./h/h;
58  resultat[1]=0.;
59  resultat[2]=0.;
60  resultat[3]=0.;
61  resultat[4]=1./h/h;
62  resultat[5]=0.;
63  resultat[6]=0.;
64  resultat[7]=0.;
65  resultat[8]=1./h/h;
66 }
67 
69 {
70  double du=decalage->calcul_decalage_parametre_u(param[0]);
71  double dv=decalage->calcul_decalage_parametre_v(param[1]);
72  double u=decalage->decalage_parametre_u(param[0],du);
73  double v=decalage->decalage_parametre_v(param[1],dv);
74  double E,F,G;
75  face->get_EFG(param,E,F,G);
76  TPL_MAP_ENTITE<MG_SEGMENT*> liste_trouvee;
77  double dist_reference=4.*sqrt(E*G-F*F)*distance_maximale;
78  frontiere->rechercher(u-du,v-dv,dist_reference,liste_trouvee);
79  FRONTIERE_INFLUENTE frontiere_recherchee;
80  int nb_liste_trouvee=liste_trouvee.get_nb();
81  for (int i=0;i<nb_liste_trouvee;i++)
82  {
83  MG_SEGMENT* segment=liste_trouvee.get(i);
84  MG_NOEUD* noeud1=segment->get_noeud1();
85  MG_NOEUD* noeud2=segment->get_noeud2();
86  double u1=decalage->decalage_parametre_u(noeud1->get_u(),du);
87  double v1=decalage->decalage_parametre_v(noeud1->get_v(),dv);
88  double u2=decalage->decalage_parametre_u(noeud2->get_u(),du);
89  double v2=decalage->decalage_parametre_v(noeud2->get_v(),dv);
90  double px=(u2-u1)*(u-u1)+(v2-v1)*(v-v1);
91  double py=(u1-u2)*(u-u2)+(v1-v2)*(v-v2);
92  double eps=0.0001*(u1-u2)*(u1-u2)+0.0001*(v1-v2)*(v1-v2);
93  double distance;
94  if ((px>(-eps)) && (py>(-eps)))
95  {
96  double det=(u1-u2)*(u1-u2)+(v1-v2)*(v1-v2);
97  double ui=(u1*(v2-v1)*(v2-v1)+(u1-u2)*(v2-v1)*(v1-v)+u*(u1-u2)*(u1-u2))/det;
98  double vi=(v1*(u1-u2)*(u1-u2)+(u1-u2)*(v1-v2)*(u-u1)+v*(v1-v2)*(v1-v2))/det;
99  distance=calcule_distance(u,v,ui,vi,du,dv);
100  }
101  else distance=0.5*(calcule_distance(u,v,u1,v1,du,dv)+calcule_distance(u,v,u2,v2,du,dv));
102  std::pair<const double,MG_SEGMENT*> tmp(distance,segment);
103  frontiere_recherchee.insert(tmp);
104  }
105  int nombre=0;
106  double numo=0.,deno=0.;
107  double dismin;
108  for (FRONTIERE_INFLUENTE::iterator j=frontiere_recherchee.begin();j!=frontiere_recherchee.end();j++)
109  {
110  double dens;
111  if (((*j).first<dist_reference) && (nombre<4))
112  {
113  nombre++;
114  MG_SEGMENT* segment=(*j).second;
115  MG_NOEUD* noeud1=segment->get_noeud1();
116  MG_NOEUD* noeud2=segment->get_noeud2();
117  double dens1,dens2;
118  for (int k1=0;k1<noeud1->get_lien_segment()->get_nb();k1++)
119  {
120  if (k1==0) dens1=noeud1->get_lien_segment()->get(k1)->get_longueur();
121  else dens1=std::min(dens1,noeud1->get_lien_segment()->get(k1)->get_longueur());
122  }
123  for (int k2=0;k2<noeud2->get_lien_segment()->get_nb();k2++)
124  {
125  if (k2==0) dens2=noeud2->get_lien_segment()->get(k2)->get_longueur();
126  else dens1=std::min(dens2,noeud2->get_lien_segment()->get(k2)->get_longueur());
127  }
128  dens=0.5*(dens1+dens2);
129  if (nombre==1)
130  {
131  dismin=(*j).first;
132  }
133 
134  numo=numo+(4*distance_maximale-(*j).first)*dens;
135  deno=deno+4*distance_maximale-(*j).first;
136  }
137  }
138  if (nombre!=0)
139  {
140  numo=numo+dismin*distance_maximale;
141  deno=deno+dismin;
142  }
143  else return distance_maximale;
144  return (numo/deno);
145 }
146 
147 
148 double FCT_TAILLE_FACE::calcule_distance(double u1,double v1,double u2,double v2,double du,double dv)
149 {
150  double longueur_calculee=0.;
151 
152  double dt=0.03125;
153  double ti;
154  double tii=0;
155  double ui=u1;
156  double vi=v1;
157  double uii;
158  double vii;
159  double dui;
160  double dvi;
161 
162  while (tii<1.)
163  {
164  double param_ti[2]={ui-du,vi-dv};
165  double Ei,Fi,Gi;
166  face->get_EFG(param_ti,Ei,Fi,Gi);
167  ti=tii;
168  tii=ti+dt;
169  uii=u1+tii*(u2-u1);
170  vii=v1+tii*(v2-v1);
171  dui=uii-ui;
172  dvi=vii-vi;
173  double t=0.7886751345*ti+0.2113248654*tii;
174  double u=u1+t*(u2-u1);
175  double v=v1+t*(v2-v1);
176  double param_integration1[2]={u-du,v-dv};
177  double E,F,G;
178  face->get_EFG(param_integration1,E,F,G);
179  longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(E*dui*dui+2*F*dui*dvi+G*dvi*dvi);
180  t=0.7886751345*tii+0.2113248654*ti;
181  u=u1+t*(u2-u1);
182  v=v1+t*(v2-v1);
183  double param_integration2[2]={u-du,v-dv};
184  face->get_EFG(param_integration2,E,F,G);
185  longueur_calculee=longueur_calculee+0.5*(tii-ti)*sqrt(E*dui*dui+2*F*dui*dvi+G*dvi*dvi);
186  ui=uii;
187  vi=vii;
188  }
189  return longueur_calculee;
190 }
191 
192 void FCT_TAILLE_FACE::deriver(double *param,double *resultat,int num_param)
193 {
194  double uv[2];
195  uv[0]=param[0];
196  uv[1]=param[1];
197  uv[num_param]=uv[num_param]+1e-6;
198  double taille[9],taille_eps[9];
199  evaluer(param,taille);
200  evaluer(uv,taille_eps);
201  resultat[0]=(taille_eps[0]-taille[0])/1e-6;
202  resultat[1]=(taille_eps[1]-taille[1])/1e-6;
203  resultat[2]=(taille_eps[2]-taille[2])/1e-6;
204  resultat[3]=(taille_eps[3]-taille[3])/1e-6;
205  resultat[4]=(taille_eps[4]-taille[4])/1e-6;
206  resultat[5]=(taille_eps[5]-taille[5])/1e-6;
207  resultat[6]=(taille_eps[6]-taille[6])/1e-6;
208  resultat[7]=(taille_eps[7]-taille[7])/1e-6;
209  resultat[8]=(taille_eps[8]-taille[8])/1e-6;
210 }
211 
212 void FCT_TAILLE_FACE::evaluer_decompose(double *metrique_depart,double *metrique_decompose)
213 {
214  const double precision = 1e-13;
215  double v1[2];
216  double v2[2];
217  double lambda1,lambda2;
218  // ( a11 a12 ) ( a b ) ( m(1) m(3) )
219  // ( ) = ( ) = ( )
220  // ( a21 a22 ) ( c d ) ( m(2) m(4) )
221 
222  // Puisque tenseur est un RM_TENSEUR2X2_SYM, b et c sont egaux.
223  double a = metrique_depart[0];
224  double b = metrique_depart[1];
225  double c = metrique_depart[2];
226  double d = metrique_depart[3];
227 
228  double coef1 = (a + d) * (a + d);
229  double coef2 = 4.0 * (a*d - b*c);
230  double discriminant = coef1 - coef2;
231  // NOTE: une matrice 2v2[0] est dite positive quand discriminant est positif!
232 
233  //
234  // CAS 1
235  //
236  // Si disc est resolument positif (plus que la valeur de troncature
237  // prec), ce qui sera presque toujours le cas, alors la matrice a
238  // deux valeurs propres reelles distinctes. A chacune de ces valeurs
239  // propres correspond un vecteur propre non-nul. Une valeur propre
240  // peut etre nulle (si a*d - b*c = 0, si det(m) = 0) mais dans ce
241  // cas-ci, on s'en fout, on obient toujours deux vecteurs propres
242  // distincts et non-nuls.
243  //
244  if ( discriminant > precision * ( fabs(coef1) + fabs(coef2) ) )
245  {
246  discriminant = sqrt ( discriminant );
247  lambda1 = ( a + d - discriminant ) * 0.5;
248  lambda2 = ( a + d + discriminant ) * 0.5;
249  v1[0] = b;
250  v1[1] = lambda1 - a;
251  if ( fabs(v1[1]) <= precision * ( fabs(lambda1) + fabs(a) ) )
252  {
253  v1[0] = lambda1 - d;
254  v1[1] = c;
255  }
256  double normV1 = 1.0 / sqrt ( v1[0]*v1[0] + v1[1]*v1[1] );
257  v1[0] = v1[0] * normV1;
258  v1[1] = v1[1] * normV1;
259  v2[0] = b;
260  v2[1] = lambda2 - a;
261  if ( fabs(v2[1]) <= precision * ( fabs(lambda2) + fabs(a) ) )
262  {
263  v2[0] = lambda2 - d;
264  v2[1] = c;
265  }
266  double normV2 = 1.0 / sqrt ( v2[0]*v2[0] + v2[1]*v2[1] );
267  v2[0] = v2[0] * normV2;
268  v2[1] = v2[1] * normV2;
269  }
270  else if ( fabs(discriminant) <= precision*( fabs(coef1) + fabs(coef2) ) )
271  {
272  if ( fabs(b) + fabs(c) > precision * ( fabs(a) + fabs(d) ) )
273  {
274  lambda1 = ( a + d ) * 0.5;
275  lambda2 = lambda1;
276  if ( fabs(b) > fabs(c) )
277  {
278  v1[0] = 1;
279  v1[1] = - ( a - d ) * v1[0] / ( 2.0 * b );
280  }
281  else
282  {
283  v1[1] = 1;
284  v1[0] = ( a - d ) * v1[1] / ( 2.0 * c );
285  }
286  double norm = 1.0 / sqrt ( v1[0]*v1[0] + v1[1]*v1[1] );
287  v1[0] = v1[0] * norm;
288  v1[1] = v1[1] * norm;
289  v2[0] = -v1[1];
290  v2[1] = v1[0];
291  }
292  else
293  {
294  if ( a > d )
295  {
296  lambda1 = a;
297  v1[0] = 1;
298  v1[1] = 0;
299  lambda2 = d;
300  v2[0] = 0;
301  v2[1] = 1;
302  }
303  else
304  {
305  lambda1 = d;
306  v1[0] = 0;
307  v1[1] = 1;
308  lambda2 = a;
309  v2[0] = 1;
310  v2[1] = 0;
311  }
312  }
313  }
314  else
315  {
316  if ( fabs(b) > fabs(c) )
317  {
318  lambda1 = b;
319  lambda2 = b;
320  }
321  else
322  {
323  lambda1 = c;
324  lambda2 = c;
325  }
326  v1[0] = 1;
327  v1[1] = 0;
328  v2[0] = 0;
329  v2[1] = 1;
330  }
331 
332  metrique_decompose[0]=lambda1;
333  metrique_decompose[1]=v1[0];
334  metrique_decompose[2]=v1[1];
335  metrique_decompose[3]=lambda2;
336  metrique_decompose[4]=v2[0];
337  metrique_decompose[5]=v2[1];
338 }
339 
341 {
342  return 1;
343 }
344 
345 
347 {
348  return distance_maximale;
349 }
350 
FCT_TAILLE_FACE::distance_maximale
double distance_maximale
Definition: fct_taille_face.h:56
FCT_TAILLE_FACE::get_valeur_maximale
virtual double get_valeur_maximale(int num)
Definition: fct_taille_face.cpp:346
TPL_QUADTREE::rechercher
virtual void rechercher(BOITE_2D &boite, TPL_MAP_ENTITE< A > &liste_entite_trouve, TPL_CELLULE_QUADTREE< A, CONDITION > *cellule)
Definition: tpl_quadtree.h:202
FCT_TAILLE_FACE::evaluer_decompose
virtual void evaluer_decompose(double *metrique_depart, double *metrique_decompose)
Definition: fct_taille_face.cpp:212
MG_SEGMENT
Definition: mg_segment.h:38
gestionversion.h
MG_SURFACE::get_periode_u
virtual double get_periode_u(void)=0
TPL_MAP_ENTITE< MG_SEGMENT * >
MG_SEGMENT::get_noeud2
virtual MG_NOEUD * get_noeud2(void)
Definition: mg_segment.cpp:113
robustPredicates::epsilon
static REAL epsilon
Definition: robustpredicates.cc:371
a
#define a(i, j)
FCT_TAILLE_FACE::calcule_distance
double calcule_distance(double u1, double v1, double u2, double v2, double du=0, double dv=0)
Definition: fct_taille_face.cpp:148
FCT_TAILLE_FACE::FCT_TAILLE_FACE
FCT_TAILLE_FACE(double eps, double dist, MG_FACE *mgface, LISTE_FRONTIERE *segment_frontiere)
Definition: fct_taille_face.cpp:33
FCT_TAILLE_FACE::valide_parametre
virtual int valide_parametre(double *param)
Definition: fct_taille_face.cpp:340
FRONTIERE_INFLUENTE
std::multimap< double, MG_SEGMENT *, std::less< double > > FRONTIERE_INFLUENTE
Definition: fct_taille_face.h:36
FCT_TAILLE_FACE::face
MG_FACE * face
Definition: fct_taille_face.h:57
MG_NOEUD::get_u
virtual double get_u(void)
Definition: mg_noeud.cpp:108
FCT_TAILLE_FACE::evaluer_facteur_distance_maximale
double evaluer_facteur_distance_maximale(double *param)
Definition: fct_taille_face.cpp:68
FCT_TAILLE_FACE::~FCT_TAILLE_FACE
~FCT_TAILLE_FACE()
Definition: fct_taille_face.cpp:41
FCT_TAILLE_FACE::evaluer
virtual void evaluer(double *param, double *resultat)
Definition: fct_taille_face.cpp:46
MG_SEGMENT::get_noeud1
virtual MG_NOEUD * get_noeud1(void)
Definition: mg_segment.cpp:108
MG_NOEUD::get_lien_segment
TPL_LISTE_ENTITE< class MG_SEGMENT * > * get_lien_segment(void)
Definition: mg_noeud.cpp:141
OPERATEUR::egal
static int egal(double a, double b, double eps)
Definition: ot_mathematique.cpp:1629
TPL_MAP_ENTITE::get_nb
virtual int get_nb(void)
Definition: tpl_map_entite.h:83
MG_NOEUD
Definition: mg_noeud.h:41
FCT_TAILLE_FACE::decalage
OT_DECALAGE_PARAMETRE * decalage
Definition: fct_taille_face.h:54
FCT_TAILLE_FACE::epsilon
double epsilon
Definition: fct_taille_face.h:55
MG_FACE::get_M
virtual void get_M(double *uv, double &M1, double &M2, double &M3)
Definition: mg_face.cpp:274
TPL_LISTE_ENTITE::get
virtual X get(int num)
Definition: tpl_liste_entite.h:72
ot_mathematique.h
OT_DECALAGE_PARAMETRE::decalage_parametre_u
double decalage_parametre_u(double par, double dpar)
Definition: ot_decalage_parametre.cpp:51
MG_NOEUD::get_v
virtual double get_v(void)
Definition: mg_noeud.cpp:113
sqrt
double2 sqrt(double2 &val)
Definition: ot_doubleprecision.cpp:345
OT_DECALAGE_PARAMETRE::calcul_decalage_parametre_v
double calcul_decalage_parametre_v(double par)
Definition: ot_decalage_parametre.cpp:43
MG_SURFACE::get_periode_v
virtual double get_periode_v(void)=0
FCT_TAILLE_FACE::frontiere
LISTE_FRONTIERE * frontiere
Definition: fct_taille_face.h:58
TPL_MAP_ENTITE::get
virtual X get(int num)
Definition: tpl_map_entite.h:89
OT_DECALAGE_PARAMETRE::calcul_decalage_parametre_u
double calcul_decalage_parametre_u(double par)
Definition: ot_decalage_parametre.cpp:35
MG_SEGMENT::get_longueur
virtual double get_longueur(void)
Definition: mg_segment.cpp:125
OT_DECALAGE_PARAMETRE::decalage_parametre_v
double decalage_parametre_v(double par, double dpar)
Definition: ot_decalage_parametre.cpp:75
TPL_QUADTREE
Definition: tpl_quadtree.h:77
MG_FACE
Definition: mg_face.h:34
FCT_TAILLE_METRIQUE
Definition: fct_taille_metrique.h:29
OT_DECALAGE_PARAMETRE
Definition: ot_decalage_parametre.h:28
MG_FACE::get_EFG
virtual void get_EFG(double *uv, double &E, double &F, double &G)
Definition: mg_face.cpp:264
FCT_TAILLE_FACE::deriver
virtual void deriver(double *param, double *resultat, int num_param=0)
Definition: fct_taille_face.cpp:192
MG_FACE::get_surface
virtual MG_SURFACE * get_surface(void)
Definition: mg_face.cpp:109
fct_taille_face.h