598 lines
26 KiB
C++
598 lines
26 KiB
C++
|
// This file is part of the Herezh++ application.
|
||
|
//
|
||
|
// The finite element software Herezh++ is dedicated to the field
|
||
|
// of mechanics for large transformations of solid structures.
|
||
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
||
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
||
|
//
|
||
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
||
|
//
|
||
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
||
|
// AUTHOR : Gérard Rio
|
||
|
// E-MAIL : gerardrio56@free.fr
|
||
|
//
|
||
|
// This program is free software: you can redistribute it and/or modify
|
||
|
// it under the terms of the GNU General Public License as published by
|
||
|
// the Free Software Foundation, either version 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
// See the GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
//
|
||
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
||
|
|
||
|
#include "MvtSolide.h"
|
||
|
|
||
|
#include "ParaGlob.h"
|
||
|
#include <list>
|
||
|
#include "MathUtil.h"
|
||
|
#include "CharUtil.h"
|
||
|
|
||
|
// par défaut
|
||
|
MvtSolide::MvtSolide() :
|
||
|
tab_tcr(), tab_indic(),lis_centre_noeud()
|
||
|
{};
|
||
|
// de copie
|
||
|
MvtSolide::MvtSolide (const MvtSolide& mvt):
|
||
|
tab_tcr(mvt.tab_tcr), tab_indic(mvt.tab_indic)
|
||
|
,lis_centre_noeud(mvt.lis_centre_noeud)
|
||
|
{};
|
||
|
// DESTRUCTEUR :
|
||
|
MvtSolide::~MvtSolide ()
|
||
|
{};
|
||
|
|
||
|
// Affiche les donnees
|
||
|
void MvtSolide::Affiche () const
|
||
|
{ cout << " mouvement_solide_ ";
|
||
|
int taille = tab_tcr.Taille();
|
||
|
list <String_et_entier>::const_iterator il = lis_centre_noeud.begin();
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ switch (tab_indic(it))
|
||
|
{ case 1: // cas d'une translation
|
||
|
{ cout << " translation_= " << tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 2: // cas d'une nouvelle définition du centre
|
||
|
{ cout << " centre_= " << tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 3: // cas d'une rotation
|
||
|
{ cout << " rotation_= " << tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 4: // cas d'une rotation
|
||
|
{ cout << " centre_a_un_noeud=_nom_maille " << (*il).nom
|
||
|
<< " numnoeud= " << (*il).n;
|
||
|
il++;
|
||
|
break;
|
||
|
}
|
||
|
case 5: // cas d'une homothétie
|
||
|
{ cout << " homothetie_= " << tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
}; // fin du switch: switch (tab_indic)
|
||
|
};
|
||
|
cout << " ";
|
||
|
};
|
||
|
|
||
|
|
||
|
// Realise l'egalite
|
||
|
MvtSolide& MvtSolide::operator= (const MvtSolide& mvt)
|
||
|
{ tab_tcr = mvt.tab_tcr;
|
||
|
tab_indic = mvt.tab_indic;
|
||
|
lis_centre_noeud = mvt.lis_centre_noeud;
|
||
|
return *this;
|
||
|
};
|
||
|
|
||
|
//Surcharge d'operateur logique
|
||
|
bool MvtSolide::operator == (const MvtSolide& mvt) const
|
||
|
{ return ((tab_tcr == mvt.tab_tcr) && (tab_indic == mvt.tab_indic)
|
||
|
&& (lis_centre_noeud == mvt.lis_centre_noeud));
|
||
|
};
|
||
|
|
||
|
// lecture des mouvements solides si nécessaire
|
||
|
void MvtSolide::Lecture_mouvements_solides(UtilLecture * entreePrinc)
|
||
|
{ if (strstr(entreePrinc->tablcar,MotCleMvtSolide().c_str())!=NULL)
|
||
|
// si on change le mot clé ne pas oublier de changer la fonction MotCleMvtSolide()
|
||
|
{ if (ParaGlob::NiveauImpression() >= 6)
|
||
|
cout << " lecture des mouvements solides " << endl ;
|
||
|
entreePrinc->NouvelleDonnee();
|
||
|
string nom;
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
|
||
|
list <Coordonnee> list_tcr; // liste des translations, centres et rotation
|
||
|
list <int> list_indic; // indic le type de transformation lue: 1 pour translation
|
||
|
// 2 pour centre et 3 pour rotation
|
||
|
while (strstr(entreePrinc->tablcar,"fin_mouvement_solide_")==NULL)
|
||
|
{*(entreePrinc->entree) >> nom;
|
||
|
if (nom == "translation_=")
|
||
|
{ Coordonnee trans(dima);
|
||
|
trans.Lecture(*entreePrinc);
|
||
|
list_tcr.push_back(trans);
|
||
|
list_indic.push_back(1);
|
||
|
};
|
||
|
if (nom == "centre_=")
|
||
|
{ Coordonnee centre(dima);
|
||
|
centre.Lecture(*entreePrinc);
|
||
|
list_tcr.push_back(centre);
|
||
|
list_indic.push_back(2);
|
||
|
};
|
||
|
if (nom == "rotation_=")
|
||
|
{ Coordonnee rot(3); // le vecteur rotation est systématiquement en 3D
|
||
|
rot.Lecture(*entreePrinc);
|
||
|
if (strstr(entreePrinc->tablcar,"en_degre_")!=0)
|
||
|
// on transforme en radian
|
||
|
{ rot *= ConstMath::Pi / 180.;};
|
||
|
list_tcr.push_back(rot);
|
||
|
list_indic.push_back(3);
|
||
|
// on regarde s'il s'agit de degré éventuellement
|
||
|
};//-- fin du cas de la rotation
|
||
|
if (nom == "centre_noeud_=")
|
||
|
{ // cas d'un centre donné par un numero de noeud
|
||
|
String_et_entier nu;
|
||
|
string nom_mail;
|
||
|
*(entreePrinc->entree) >> nom_mail;
|
||
|
if (nom_mail == "nom_mail=")
|
||
|
{ // cas où il y a un nom de maillage
|
||
|
*(entreePrinc->entree) >> nu.nom; // lecture du nom
|
||
|
*(entreePrinc->entree) >> nu.n; // lecture du numero de noeud
|
||
|
}
|
||
|
else
|
||
|
{ // sinon cela veut dire que l'on vient de lire un numéro de noeud du premier maillage
|
||
|
nu.nom = "";
|
||
|
nu.n = ChangeEntier(nom_mail);
|
||
|
};
|
||
|
lis_centre_noeud.push_back(nu);
|
||
|
list_tcr.push_back(Coordonnee()); // un centre par défaut
|
||
|
list_indic.push_back(4);
|
||
|
};
|
||
|
if (nom == "homothetie_=")
|
||
|
{ Coordonnee homothetie(3); // le vecteur homothetie est systématiquement en 3D
|
||
|
// ainsi on peut avoir une dilatation différentielle suivant les 3 axes
|
||
|
homothetie.Lecture(*entreePrinc);
|
||
|
list_tcr.push_back(homothetie);
|
||
|
list_indic.push_back(5);
|
||
|
};//-- fin du cas d'une homothetie
|
||
|
entreePrinc->NouvelleDonnee();
|
||
|
}; //-- fin du while
|
||
|
// on passe le mot clé de fin
|
||
|
*(entreePrinc->entree) >> nom;
|
||
|
// entreePrinc->NouvelleDonnee();
|
||
|
// enregistrement des mouvements solides
|
||
|
int taille = list_tcr.size();
|
||
|
tab_tcr.Change_taille(taille);
|
||
|
tab_indic.Change_taille(taille);
|
||
|
list <Coordonnee>::iterator il,ilfin=list_tcr.end();
|
||
|
list <int>::iterator ii,iifin=list_indic.end();
|
||
|
int i =1; ii=list_indic.begin(); // init pour la boucle qui suit
|
||
|
|
||
|
for (il=list_tcr.begin();il != ilfin; il++,i++,ii++)
|
||
|
{tab_tcr(i)=(*il);
|
||
|
tab_indic(i)=(*ii);
|
||
|
};
|
||
|
}; //-- fin du if indiquant le cas ou il y a des mouvements solides
|
||
|
|
||
|
};
|
||
|
|
||
|
// retour de la première rotation: en fait l'axe de rotation
|
||
|
const Coordonnee& MvtSolide::Premiere_rotation()const
|
||
|
{ Coordonnee axe; // le vecteur de retour
|
||
|
int taille = tab_tcr.Taille();
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ switch (tab_indic(it))
|
||
|
{ case 3: // cas d'une rotation
|
||
|
{ switch (dima)
|
||
|
{case 1:
|
||
|
{cout << "\n erreur : pas de rotation en 1D !! "
|
||
|
<< "\n MvtSolide::Premiere_rotation(..";
|
||
|
Sortie(1); break;
|
||
|
}
|
||
|
case 2 : case 3: return tab_tcr(it);
|
||
|
}
|
||
|
break;
|
||
|
} // fin du cas 3
|
||
|
}; // fin du switch: switch (tab_indic)
|
||
|
}; // fin de la boucle sur tab_indic : for (int it=1; it<= taille; it++)
|
||
|
// normalement on ne passe pas ici sauf s'il n'y a pas d'axe
|
||
|
return tab_tcr(1); // pour faire taire le compilateur
|
||
|
};
|
||
|
// indique s'il existe seulement une seule rotation
|
||
|
bool MvtSolide::ExisteUneSeuleRotation()const
|
||
|
{ int nb_rot=0;
|
||
|
int taille = tab_tcr.Taille();
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ switch (tab_indic(it))
|
||
|
{ case 3: // cas d'une rotation
|
||
|
{ switch (dima)
|
||
|
{case 1: break; // on ne fait rien
|
||
|
case 2 : case 3: nb_rot++;
|
||
|
}
|
||
|
break;
|
||
|
} // fin du cas 3
|
||
|
}; // fin du switch: switch (tab_indic)
|
||
|
}; // fin de la boucle sur tab_indic : for (int it=1; it<= taille; it++)
|
||
|
// retour
|
||
|
return (nb_rot == 1);
|
||
|
};
|
||
|
|
||
|
// application des mouvements solides aux points transmis et retour du point
|
||
|
// transformé
|
||
|
Coordonnee & MvtSolide::AppliqueMvtSolide (Coordonnee & M) const
|
||
|
{ // on passe en revue l'ensemble des transformations
|
||
|
int taille = tab_tcr.Taille();
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (list_coor_centre_noeud.size() != lis_centre_noeud.size())
|
||
|
{ cout << "\n erreur : le nombre de centre noeud disponible "
|
||
|
<< list_coor_centre_noeud.size() << " est inferieur au nombre defini par la condition"
|
||
|
<< " lineaire qui est " << lis_centre_noeud.size() << endl;
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
list <Coordonnee>::const_iterator icoor_centre = list_coor_centre_noeud.begin();
|
||
|
Coordonnee centre(dima); // par défaut le centre
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ switch (tab_indic(it))
|
||
|
{ case 1: // cas d'une translation
|
||
|
{ M += tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 2: // cas d'une nouvelle définition du centre
|
||
|
{ centre += tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 3: // cas d'une rotation
|
||
|
{ switch (dima)
|
||
|
{case 1: break; // on ne fait rien
|
||
|
case 2: // on tourne autour de z
|
||
|
{ double theta = tab_tcr(it)(3);
|
||
|
double costheta = cos(theta);
|
||
|
double sintheta = sin(theta);
|
||
|
// le point initial : M , le centre de rotation C
|
||
|
// le point final : Mnew = rotation de CM + les coordonnées du centre
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
M(1)=CM(1)*costheta + CM(2)*sintheta + centre(1);
|
||
|
M(2)=-CM(1)*sintheta + CM(2)*costheta + centre(2);
|
||
|
break;
|
||
|
}
|
||
|
case 3: // on a trois rotation qui sont successivement suivant x puis y puis z
|
||
|
{ Coordonnee& rot = tab_tcr(it); // pour simplifier
|
||
|
// le point initial : M , le centre de rotation C
|
||
|
// le point final : Mnew = rotation de CM + les coordonnées du centre
|
||
|
for (int i=1;i<=3;i++) // on boucle sur les trois directions
|
||
|
// une rotation autour de xi si l'angle est non nulle
|
||
|
if (!(Dabs(rot(i)) <= ConstMath::trespetit))
|
||
|
{ // on définit 3 index fonctions du i
|
||
|
int ix=1; int iy=2; int iz=3;
|
||
|
switch (i) // uniquement pour 2 et 3, le cas 1 étant celui de l'initialisation
|
||
|
// précédente
|
||
|
{ case 2: ix = 2; iy = 1; iz = 3; break;
|
||
|
case 3: ix = 3; iy = 1; iz = 2; break;
|
||
|
};
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
double theta = rot(i);
|
||
|
double costheta = cos(theta);
|
||
|
double sintheta = sin(theta);
|
||
|
// transformation
|
||
|
M(iy)=CM(iy)*costheta + CM(iz)*sintheta + centre(iy);
|
||
|
M(iz)=-CM(iy)*sintheta + CM(iz)*costheta + centre(iz);
|
||
|
M(ix)=CM(ix) + centre(ix);
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
}; //-- fin du case sur la dimension: switch (dima)
|
||
|
break;
|
||
|
} // fin du cas 3
|
||
|
case 4: // cas d'un centre définie par une position de noeud
|
||
|
{ centre = (*icoor_centre);
|
||
|
break;
|
||
|
}
|
||
|
case 5: // on fait une homothétie
|
||
|
{ // on se sert du centre pour le centre de l'homothétie
|
||
|
Coordonnee& scale = tab_tcr(it); // pour simplifier
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
switch (dima)
|
||
|
{case 3: M(3) = centre(3) + CM(3) * scale(3);
|
||
|
case 2: M(2) = centre(2) + CM(2) * scale(2);
|
||
|
case 1: M(1) = centre(1) + CM(1) * scale(1);
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
}; // fin du switch: switch (tab_indic)
|
||
|
}; // fin de la boucle sur tab_indic : for (int it=1; it<= taille; it++)
|
||
|
// retour du point transformé
|
||
|
return M;
|
||
|
};
|
||
|
|
||
|
// idem que précédemment, mais avec un coefficient d'intensité
|
||
|
// dans le cas d'une translation, celle-ci est multiplié par le coef
|
||
|
// dans le cas d'un nouveau centre, sa position n'est pas affectée par le coef
|
||
|
// dans le cas d'une rotation, celle-ci est multiplié par le coef
|
||
|
// dans le cas d'une homothétie: celle-ci est multiplié par le coef
|
||
|
Coordonnee & MvtSolide::AppliqueMvtSolide (Coordonnee & M, const double& coef) const
|
||
|
{ // on passe en revue l'ensemble des transformations
|
||
|
int taille = tab_tcr.Taille();
|
||
|
int dima = ParaGlob::Dimension();
|
||
|
#ifdef MISE_AU_POINT
|
||
|
if (list_coor_centre_noeud.size() != lis_centre_noeud.size())
|
||
|
{ cout << "\n erreur : le nombre de centre noeud disponible "
|
||
|
<< list_coor_centre_noeud.size() << " est inferieur au nombre defini par la condition"
|
||
|
<< " lineaire qui est " << lis_centre_noeud.size() << endl;
|
||
|
Sortie(1);
|
||
|
};
|
||
|
#endif
|
||
|
list <Coordonnee>::const_iterator icoor_centre = list_coor_centre_noeud.begin();
|
||
|
Coordonnee centre(dima); // par défaut le centre
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ switch (tab_indic(it))
|
||
|
{ case 1: // cas d'une translation
|
||
|
{ M += coef * tab_tcr(it) ;
|
||
|
break;
|
||
|
}
|
||
|
case 2: // cas d'une nouvelle définition du centre
|
||
|
{ centre += tab_tcr(it);
|
||
|
break;
|
||
|
}
|
||
|
case 3: // cas d'une rotation
|
||
|
{ switch (dima)
|
||
|
{case 1: break; // on ne fait rien
|
||
|
case 2: // on tourne autour de z
|
||
|
{ double theta = coef * tab_tcr(it)(3);
|
||
|
double costheta = cos(theta);
|
||
|
double sintheta = sin(theta);
|
||
|
// le point initial : M , le centre de rotation C
|
||
|
// le point final : Mnew = rotation de CM + les coordonnées du centre
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
M(1)=CM(1)*costheta + CM(2)*sintheta + centre(1);
|
||
|
M(2)=-CM(1)*sintheta + CM(2)*costheta + centre(2);
|
||
|
break;
|
||
|
}
|
||
|
case 3: // on a trois rotation qui sont successivement suivant x puis y puis z
|
||
|
{ Coordonnee rot = coef * tab_tcr(it); // pour simplifier
|
||
|
// le point initial : M , le centre de rotation C
|
||
|
// le point final : Mnew = rotation de CM + les coordonnées du centre
|
||
|
for (int i=1;i<=3;i++) // on boucle sur les trois directions
|
||
|
// une rotation autour de xi si l'angle est non nulle
|
||
|
if (!(Dabs(rot(i)) <= ConstMath::trespetit))
|
||
|
{ // on définit 3 index fonctions du i
|
||
|
int ix=1; int iy=2; int iz=3;
|
||
|
switch (i) // uniquement pour 2 et 3, le cas 1 étant celui de l'initialisation
|
||
|
// précédente
|
||
|
{ case 2: ix = 2; iy = 1; iz = 3; break;
|
||
|
case 3: ix = 3; iy = 1; iz = 2; break;
|
||
|
};
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
// double rayon0 = CM.Norme();
|
||
|
double theta = rot(i);
|
||
|
double costheta = cos(theta);
|
||
|
double sintheta = sin(theta);
|
||
|
// transformation
|
||
|
M(iy)=CM(iy)*costheta + CM(iz)*sintheta + centre(iy);
|
||
|
M(iz)=-CM(iy)*sintheta + CM(iz)*costheta + centre(iz);
|
||
|
M(ix)=CM(ix) + centre(ix);
|
||
|
// CM = M-centre;
|
||
|
// double rayon1 = CM.Norme();
|
||
|
// if (Dabs(rayon1-rayon0)>= ConstMath::pasmalpetit)
|
||
|
// cout << "\n rayon1= " << rayon1 << " rayon0= " << rayon0;
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
}; //-- fin du case sur la dimension: switch (dima)
|
||
|
break;
|
||
|
} // fin du cas 3
|
||
|
case 4: // cas d'un centre définie par une position de noeud
|
||
|
{ centre = (*icoor_centre);
|
||
|
break;
|
||
|
}
|
||
|
case 5: // on fait une homothétie
|
||
|
{ // on se sert du centre pour le centre de l'homothétie
|
||
|
Coordonnee scale = coef * tab_tcr(it); // pour simplifier
|
||
|
Coordonnee CM(M-centre); // création de CM
|
||
|
switch (dima)
|
||
|
{case 3: M(3) = centre(3) + CM(3) * scale(3);
|
||
|
case 2: M(2) = centre(2) + CM(2) * scale(2);
|
||
|
case 1: M(1) = centre(1) + CM(1) * scale(1);
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}; // fin du switch: switch (tab_indic)
|
||
|
}; // fin de la boucle sur tab_indic : for (int it=1; it<= taille; it++)
|
||
|
// retour du point transformé
|
||
|
return M;
|
||
|
};
|
||
|
|
||
|
// affichage et definition interactive des commandes
|
||
|
void MvtSolide::Info_commande_MvtSolide(ostream & sort)
|
||
|
{ // ---------- définition de rotations et translation solide ----------
|
||
|
|
||
|
//On va proposer un menu
|
||
|
string rep=" ";
|
||
|
sort << " mouvement_solide_ ";
|
||
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
cout
|
||
|
<< "\n (0 ou f) (fin) "
|
||
|
<< "\n (1) translation "
|
||
|
<< "\n (2) rotation "
|
||
|
<< "\n (3) nouveau centre absolu "
|
||
|
<< "\n (4) centre avec un noeud "
|
||
|
<< "\n (5) homothetie "
|
||
|
<< "\n (6 ou ? ) informations "
|
||
|
<< "\n ";
|
||
|
rep = lect_return_defaut(false,"f");
|
||
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie directe
|
||
|
break;
|
||
|
int num = ChangeEntier(rep);
|
||
|
if (Minuscules(rep) == "?")
|
||
|
num = 6;
|
||
|
bool choix_valide=false;
|
||
|
if ((num >= 0)&&(num<=6))
|
||
|
{ choix_valide=true; }
|
||
|
else { cout << "\n Erreur on attendait un entier entre 0 et 6 !!, "
|
||
|
<< "\n redonnez une bonne valeur"
|
||
|
<< "\n ou taper f ou 0 pour arreter le programme";
|
||
|
choix_valide=false;
|
||
|
}
|
||
|
switch (num)
|
||
|
{ case 0: // sortie
|
||
|
{ break;} // normalement cela a déjà été filtré avant
|
||
|
case 1: // translation
|
||
|
{ int dim = ParaGlob::Dimension();
|
||
|
Coordonnee trans(dim);
|
||
|
cout << "\n lecture du vecteur deplacement ("<<dim<<" reels) ? ";
|
||
|
trans.Lecture();
|
||
|
sort << "\n translation_= ";
|
||
|
trans.Affiche(sort,dim);
|
||
|
break;
|
||
|
}
|
||
|
case 2: // rotation
|
||
|
{ int dim = 3; // la dimension est systématiquement 3 ParaGlob::Dimension();
|
||
|
Coordonnee trans(dim);
|
||
|
cout << "\n rotation en radian par defaut, \n voulez vous des degres (rep o ou n) ";
|
||
|
string rop = lect_return_defaut(true,"n");
|
||
|
bool deg = false;
|
||
|
if (rop == "o") deg = true;
|
||
|
// on sépare en fonction de la dimension de l'espace
|
||
|
switch (ParaGlob::Dimension())
|
||
|
{ case 1: {cout << "\n pas de rotation possible en dimension 1 ! "; break;}
|
||
|
case 2: // la rotation est uniquement autour de z
|
||
|
{ cout << "\n lecture de l'angle de rotation autour de z: 1 reels) ? ";
|
||
|
trans(3)=lect_double();
|
||
|
break;
|
||
|
}
|
||
|
case 3:
|
||
|
{cout << "\n lecture du vecteur rotation ("<<dim<<" reels) ? ";
|
||
|
trans.Lecture();
|
||
|
sort << "\n rotation_= ";
|
||
|
trans.Affiche(sort,dim);
|
||
|
break;
|
||
|
}
|
||
|
default: break; // a priori il n'y a pas d'autre cas
|
||
|
};
|
||
|
// affichage
|
||
|
sort << "\n rotation_= ";
|
||
|
trans.Affiche(sort,dim);
|
||
|
if (deg)
|
||
|
sort << " en_degre_ ";
|
||
|
break;
|
||
|
}
|
||
|
case 3: // nouveau centre absolu
|
||
|
{ int dim = ParaGlob::Dimension();
|
||
|
Coordonnee trans(dim);
|
||
|
cout << "\n lecture du nouveau centre absolu ("<<dim<<" reels) ? ";
|
||
|
trans.Lecture();
|
||
|
sort << "\n centre_= ";
|
||
|
trans.Affiche(sort,dim);
|
||
|
break;
|
||
|
}
|
||
|
case 4: // centre avec un noeud
|
||
|
{ cout << "\n lecture du nouveau noeud centre (un numero de noeud) ? ";
|
||
|
int num_noeud=0;
|
||
|
num_noeud=(int)lect_double();
|
||
|
cout << "\n un nom de maillage (si aucune rep: \"_\" ) ? ";
|
||
|
string nom_mail="_";
|
||
|
nom_mail=lect_chaine();
|
||
|
sort << "\n centre_noeud_= ";
|
||
|
if (nom_mail != "_")
|
||
|
sort << " nom_mail= "<< nom_mail<< " ";
|
||
|
sort << num_noeud << " ";
|
||
|
break;
|
||
|
}
|
||
|
case 5: // homothétie
|
||
|
{ int dim = ParaGlob::Dimension();
|
||
|
Coordonnee scale(dim);
|
||
|
cout << "\n lecture du vecteur homothetie ("<<dim<<" reels) ? ";
|
||
|
scale.Lecture();
|
||
|
sort << "\n homothetie_= ";
|
||
|
scale.Affiche(sort,dim);
|
||
|
break;
|
||
|
}
|
||
|
case 6: // information
|
||
|
{ cout << "\n informations sur les mouvements solides";
|
||
|
cout << "\n# --- definition optionnelle de mouvements sodides appliquees au solide ---"
|
||
|
<< "\n mouvement_solide_ # mot cle pour definir le debut des mouvements solides "
|
||
|
<< "\n translation_= 1. 0. 0. # exemple d'une translation sur x "
|
||
|
<< "\n rotation_= 0.1 0. 0.3 # rotation selon x de 0.1 radian, puis selon z (selon y nulle) "
|
||
|
<< "\n rotation_= 0.1 0. 0.3 en_degre_ # idem mais en degre "
|
||
|
<< "\n centre_= 0.1 0.1 0.2 # def d'un nouveau centre de rotation pour les rotations a suivre "
|
||
|
<< "\n centre_noeud_= 3 # idem mais ici le centre de rotation sera le noeud 3 "
|
||
|
<< "\n centre_noeud_= nom_mail= trap 3 # idem avec un nom de maillage (trap) "
|
||
|
<< "\n homothetie_= 0.8 1. 1.1 # dilatation -20% sur x, rien sur y, +10% en z "
|
||
|
<< "\n fin_mouvement_solide_ # mot de fin de mouvement solide \n\n"
|
||
|
<< "\n# -- il est possible d'enchainer plusieurs mouvements solides a suivre qui sont dans ce cas execute dans le"
|
||
|
<< "\n# le meme ordre que la declaration\n"
|
||
|
<< "\n# -- concernant les rotations: "
|
||
|
<< "\n# si l'espace est 1D ==> aucune modification du maillage "
|
||
|
<< "\n# si l'espace est 2D ==> la rotation prise en compte est uniquement autour de z "
|
||
|
<< "\n# si l'espace est 3D ==> rotation (si l'angle est non nulle) suivant x puis suivant y puis suivant z ";
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
||
|
};
|
||
|
}
|
||
|
catch (ErrSortieFinale)
|
||
|
// cas d'une direction voulue vers la sortie
|
||
|
// on relance l'interuption pour le niveau supérieur
|
||
|
{ ErrSortieFinale toto;
|
||
|
throw (toto);
|
||
|
}
|
||
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
||
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
||
|
<< "\n redonnez une bonne valeur"
|
||
|
<< "\n ou taper f ou 0 pour sortir ";
|
||
|
};
|
||
|
}; //-- fin du while
|
||
|
sort << "\n fin_mouvement_solide_ ";
|
||
|
|
||
|
};
|
||
|
|
||
|
// effacement du mouvement solide actuel
|
||
|
void MvtSolide::EffaceMvtSolide()
|
||
|
{ tab_tcr.Libere(); tab_indic.Libere();
|
||
|
lis_centre_noeud.erase(lis_centre_noeud.begin(),lis_centre_noeud.end());
|
||
|
list_coor_centre_noeud.erase(list_coor_centre_noeud.begin(),list_coor_centre_noeud.end());
|
||
|
};
|
||
|
|
||
|
|
||
|
// surcharge de l'operateur de lecture typée
|
||
|
istream & operator >> (istream & entree, MvtSolide & mvt)
|
||
|
{ // vérification du type
|
||
|
int taille = 0;
|
||
|
string type;
|
||
|
entree >> type;
|
||
|
if (type != "MvtSolide_")
|
||
|
{ cout << "\n erreur en lecture d'un mouvement solide, on a lue " << type
|
||
|
<< " au lieu de MvtSolide_ ";
|
||
|
Sortie(1);
|
||
|
};
|
||
|
// lecture de la taille, on se sert de type pour passer la chaine Taille:
|
||
|
entree >> type >> taille;
|
||
|
mvt.tab_tcr.Change_taille(taille);
|
||
|
mvt.tab_indic.Change_taille(taille);
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ entree >> mvt.tab_indic(it) >> mvt.tab_tcr(it);};
|
||
|
return entree;
|
||
|
};
|
||
|
|
||
|
// surcharge de l'operateur d'ecriture typée
|
||
|
ostream & operator << ( ostream & sort,const MvtSolide & mvt)
|
||
|
{ // tout d'abord un indicateur donnant le type
|
||
|
int taille = mvt.tab_tcr.Taille();
|
||
|
sort << " MvtSolide_ taille: " << taille ;
|
||
|
for (int it=1; it<= taille; it++)
|
||
|
{ sort << " " << mvt.tab_indic(it) << " " << mvt.tab_tcr(it) << " ";};
|
||
|
return sort;
|
||
|
};
|
||
|
|