1 #ifndef COORDONNEES_BARYCENTRIQUES_HPP
2 #define COORDONNEES_BARYCENTRIQUES_HPP
4 #define _TEMPLATE_SPE_ template <class NUAGEMAILLE, class NUAGENOEUD, class NOEUD>
5 #define _COORDBARYC_ Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,DIMENSION>
6 #define _COORDBARY_2D_ Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,2>
7 #define _COORDBARY_3D_ Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,3>
9 //////////////////////////////////////////////////////////////////
13 //////////////////////////////////////////////////////////////////
15 /*********************************************************/
17 /* Classe Coordonnees_Barycentriques */
19 /*********************************************************/
21 // C'est la définition de la classe générique template qui n'est utilisée qu'à travers ses spécialisations
22 // vu que le nombre de spécialisations a faire est petit (nombre de dimensions utilisée, 3 pour MED)
23 // et vu que l'acces a ces classes doit etre rapide, car ce sont des classes de calcul
24 // la technique de spécialisation, plus lourde, mais plus rapide, a été préférée aux techniques d'héritage
26 template <class NUAGEMAILLE, class NUAGENOEUD, class NOEUD, int DIMENSION> class Coordonnees_Barycentriques
28 // TEMPLATE GENERIQUE VIDE OBLIGE DE PASSER PAR UNE SPECIALISATION
31 /*********************************************************/
33 /* Spécialisation 2D */
35 /*********************************************************/
37 _TEMPLATE_SPE_ class _COORDBARY_2D_
40 NUAGEMAILLE * mailles;
43 vector<int> etat_coord_baryc;
44 vector< vector< vector<double> > > coord_baryc;
48 Coordonnees_Barycentriques():mailles(NULL),sommets(NULL) {}
49 Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n);
50 ~Coordonnees_Barycentriques() {}
51 // donne les pseudos coordonnées barycentriques de M dans ma maille de numéro global num_maille dans mailles
52 // la pseudo coordonnées barycentrique par rapport a une face est la distance normalisée a cette face,
53 // dans le cas d'une face triangulaire, c'est la coordonnées ba
54 vector<double> Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M);
55 vector<double> Calcule_Base_Coord_Baryc(const vector<int> &simplexe_base);
56 vector<double> Calcule_Coord_Baryc(int num_maille, const NOEUD & M);
59 /*********************************************************/
61 /* Spécialisation 3D */
63 /*********************************************************/
66 _TEMPLATE_SPE_ class _COORDBARY_3D_
69 NUAGEMAILLE * mailles;
72 vector<int> etat_coord_baryc;
73 vector< vector< vector<double> > > coord_baryc;
77 Coordonnees_Barycentriques():mailles(NULL),sommets(NULL) {}
78 Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n);
79 ~Coordonnees_Barycentriques() {}
80 vector<double> Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M);
81 vector<double> Calcule_Base_Coord_Baryc(const vector<int> &simplexe_base);
82 vector<double> Calcule_Coord_Baryc(int num_maille, const NOEUD & M);
85 //////////////////////////////////////////////////////////////////
89 //////////////////////////////////////////////////////////////////
91 _TEMPLATE_SPE_ _COORDBARY_2D_::Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n):mailles(m),sommets(n)
93 cout<<"Creation des Coordonnées Barycentriques : "<<flush;
94 int nbr_mailles=mailles->SIZE();
95 etat_coord_baryc=vector<int>(nbr_mailles,FAUX);
96 coord_baryc=vector< vector< vector<double> > >(nbr_mailles);
100 _TEMPLATE_SPE_ vector<double> _COORDBARY_2D_::Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M)
103 if (etat_coord_baryc[num_maille]==FAUX)
105 nbr_faces=(*mailles).DONNE_NBR_FACES();
107 coord_baryc[num_maille]=vector< vector<double> >(nbr_faces);
109 for (i=0;i<nbr_faces;i++)
111 vector<int> simplexe_base=(*mailles).DONNE_SIMPLEXE_BASE(i);
112 coord_baryc[num_maille][i]=Calcule_Base_Coord_Baryc(simplexe_base);
113 etat_coord_baryc[num_maille]=VRAI;
116 return Calcule_Coord_Baryc(num_maille,M);
119 _TEMPLATE_SPE_ vector<double> _COORDBARY_2D_::Calcule_Base_Coord_Baryc(const vector<int> &simplexe_base)
121 const vector<int> &ref=simplexe_base;
122 vector<double> retour(3);
125 double x0=(*sommets)[ref[0]][0];
126 double y0=(*sommets)[ref[0]][1];
127 double x1=(*sommets)[ref[1]][0];
128 double y1=(*sommets)[ref[1]][1];
129 double x2=(*sommets)[ref[2]][0];
130 double y2=(*sommets)[ref[2]][1];
132 double delta=(x1*y2-x2*y1)+(x2*y0-x0*y2)+(x0*y1-x1*y0);
134 retour[0]=(y1-y2)/delta;
135 retour[1]=(x2-x1)/delta;
136 retour[2]=(x1*y2-x2*y1)/delta;
141 _TEMPLATE_SPE_ vector<double> _COORDBARY_2D_::Calcule_Coord_Baryc(int num_maille, const NOEUD & M)
144 vector<double> coord_baryc_M(3,0);
147 for (j=0;j<2;j++) coord_baryc_M[i]+=coord_baryc[num_maille][i][j]*M[j];
148 coord_baryc_M[i]+=coord_baryc[num_maille][i][2];
150 return coord_baryc_M;
153 _TEMPLATE_SPE_ _COORDBARY_3D_::Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n):mailles(m),sommets(n)
155 cout<<"Creation des Coordonnées Barycentriques : "<<flush;
156 int nbr_mailles=mailles->SIZE();
157 etat_coord_baryc=vector<int>(nbr_mailles,FAUX);
158 coord_baryc=vector< vector< vector<double> > >(nbr_mailles);
162 _TEMPLATE_SPE_ vector<double> _COORDBARY_3D_::Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M)
165 if (etat_coord_baryc[num_maille]==FAUX)
167 nbr_faces=(*mailles)[num_maille].DONNE_NBR_FACES();
169 coord_baryc[num_maille]=vector< vector<double> >(nbr_faces);
171 type_retour simplexe_base;
173 for (i=0;i<nbr_faces;i++)
175 (*mailles)[num_maille].DONNE_SIMPLEXE_BASE(i,simplexe_base);
176 coord_baryc[num_maille][i]=Calcule_Base_Coord_Baryc(vector<int>(&simplexe_base.quoi[0],&simplexe_base.quoi[simplexe_base.combien]));
177 etat_coord_baryc[num_maille]=VRAI;
180 return Calcule_Coord_Baryc(num_maille,M);
184 _TEMPLATE_SPE_ vector<double> _COORDBARY_3D_::Calcule_Base_Coord_Baryc(const vector<int> &simplexe_base)
186 const vector<int> &ref=simplexe_base;
187 vector<double> retour(4);
190 double x0=(*sommets)[ref[0]][0];
191 double y0=(*sommets)[ref[0]][1];
192 double z0=(*sommets)[ref[0]][2];
193 double x1=(*sommets)[ref[1]][0];
194 double y1=(*sommets)[ref[1]][1];
195 double z1=(*sommets)[ref[1]][2];
196 double x2=(*sommets)[ref[2]][0];
197 double y2=(*sommets)[ref[2]][1];
198 double z2=(*sommets)[ref[2]][2];
199 double x3=(*sommets)[ref[3]][0];
200 double y3=(*sommets)[ref[3]][1];
201 double z3=(*sommets)[ref[3]][2];
203 double delta1=((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1));
204 double delta2=((x3-x1)*(z2-z1)-(x2-x1)*(z3-z1));
205 double delta3=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1));
207 double delta=delta1*(x0-x1)+delta2*(y0-y1)+delta3*(z0-z1);
209 retour[0]=delta1/delta;
210 retour[1]=delta2/delta;
211 retour[2]=delta3/delta;
212 retour[3]=-(delta1*x1+delta2*y1+delta3*z1)/delta;
217 _TEMPLATE_SPE_ vector<double> _COORDBARY_3D_::Calcule_Coord_Baryc(int num_maille, const NOEUD & M)
220 int nbr_faces=coord_baryc[num_maille].size();
221 vector<double> coord_baryc_M(nbr_faces,0);
222 for (i=0;i<nbr_faces;i++)
224 for (j=0;j<3;j++) coord_baryc_M[i]+=coord_baryc[num_maille][i][j]*M[j];
225 coord_baryc_M[i]+=coord_baryc[num_maille][i][3];
227 return coord_baryc_M;
232 #undef _TEMPLATE_SPE_
233 // template <class NUAGEMAILLE, class NUAGENOEUD, class NOEUD, int DIMENSION>
235 // Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,DIMENSION>
236 #undef _COORDBARY_2D_
237 // Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,2>
238 #undef _COORDBARY_3D_
239 // Coordonnees_Barycentriques<NUAGEMAILLE,NUAGENOEUD,NOEUD,3>