/*************************************************************************************************************************************/
/* */
/* P A S S A G E D ' U N R E F E R E N T I E L C A R T E S I E N */
/* A U N R E F E R E N T I E L E U L E R I E N : */
/* */
/* */
/* Definition : */
/* */
/* Ce programme recoit comme arguments une */
/* liste de couples de vecteurs {V1,V2} (sous */
/* forme de 2x3 fichiers). Chaque couple, sauf */
/* cas degeneres, defini un plan repere par */
/* rapport a un referentiel absolu {OX1,OY1,OZ1}. */
/* A chacun de ces plans {V1,V2} est associe un */
/* referentiel relatif {OX2,OY2,OZ2} defini */
/* comme suit : */
/* */
/* V1 -0-> OX2 */
/* V1 /\ V2 -0-> OZ2 */
/* */
/* puis : */
/* */
/* OZ2 /\ OX2 -0-> OY2 */
/* */
/* Enfin, sont calcules les angles d'Euler */
/* {theta,psi,phi} permettant de passer de */
/* {OX1,OY1,OZ1} a {OX2,OY2,OZ2} et inversement... */
/* */
/* */
/* Author of '$xrv/Car_Euler.01$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 20030623103425). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_BASE
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* V A L E U R S I M P L I C I T E S D E S P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define UTILISER_LA_MATRICE_DE_ROTATION_DIRECTE \
VRAI \
/* Faut-il la matrice de rotation directe passant de {OX1,OY1,OZ1} a {OX2,OY2,OZ2} */ \
/* ("VRAI") ou inverse ("FAUX") ? */
#define EDITER_LES_VECTEURS_DIRECTEURS \
FAUX \
/* Faut-il editer les vecteurs directeurs ('VRAI') ou pas ('FAUX') ? Cela a ete introduit le */ \
/* 20051107151658 apres l'observation d'anomales dans 'v $xiirk/.NCOR.f1.1.11.$U' lors */ \
/* de l'utilisation de 'v $xrr/N_spheres.11$K' et de 'v $xrr/N_ellipso.11$K' avec des */ \
/* corps dont les trajectoires sont a priori coplanaires et qui n'apparaissent pas ainsi */ \
/* dans les images... */
#define PONDERATION_THETA_IMPLICITE \
FZERO
#define PONDERATION_PSI__IMPLICITE \
FZERO
#define PONDERATION_PHI__IMPLICITE \
FZERO
/* Ponderation de selection des angles d'Euler. */
/* */
/* Le 20030703104654, le parametre 'PONDERATION_THETA_IMPLICITE' est passe de la valeur */
/* 'FU' a 'FZERO' par symetrie avec les autres programmes... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S F I C H I E R S : */
/* */
/*************************************************************************************************************************************/
#include xrv/ARITHMET.1d.I"
/* Passage a l'allocation dynamique le 20060214135000... */
#include xrv/ARITHMET.21.I"
#include xrv/champs_5.41.I"
#define V1X_IMPLICITE \
FU
#define V1Y_IMPLICITE \
FZERO
#define V1Z_IMPLICITE \
FZERO
gGENERATION_D_UN_FICHIER(fichier_LISTE_V1X,liste_initiale_des_V1X);
gGENERATION_D_UN_FICHIER(fichier_LISTE_V1Y,liste_initiale_des_V1Y);
gGENERATION_D_UN_FICHIER(fichier_LISTE_V1Z,liste_initiale_des_V1Z);
/* Definition en memoire des fichiers definissant le vecteur 'V1'. Le passage de l'etat */
/* implicite (0,0,0) a (1,0,0) a eu lieu le 20030624093712. */
#define ELEMENT_DU_FICHIER_LISTE_V1X(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V1X,index)
#define ELEMENT_DU_FICHIER_LISTE_V1Y(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V1Y,index)
#define ELEMENT_DU_FICHIER_LISTE_V1Z(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V1Z,index)
/* Acces a un element courant des fichiers definissant le vecteur 'V1'. */
#define V2X_IMPLICITE \
FZERO
#define V2Y_IMPLICITE \
FU
#define V2Z_IMPLICITE \
FZERO
gGENERATION_D_UN_FICHIER(fichier_LISTE_V2X,liste_initiale_des_V2X);
gGENERATION_D_UN_FICHIER(fichier_LISTE_V2Y,liste_initiale_des_V2Y);
gGENERATION_D_UN_FICHIER(fichier_LISTE_V2Z,liste_initiale_des_V2Z);
/* Definition en memoire des fichiers definissant le vecteur 'V2'. Le passage de l'etat */
/* implicite (0,0,0) a (0,1,0) a eu lieu le 20030624093712. */
#define ELEMENT_DU_FICHIER_LISTE_V2X(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V2X,index)
#define ELEMENT_DU_FICHIER_LISTE_V2Y(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V2Y,index)
#define ELEMENT_DU_FICHIER_LISTE_V2Z(index) \
gELEMENT_DU_FICHIER(liste_initiale_des_V2Z,index)
/* Acces a un element courant des fichiers definissant le vecteur 'V2'. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E S T I O N D E S M A T R I C E S : */
/* */
/*************************************************************************************************************************************/
#define ACCES_A_UNE_MATRICE_DE_ROTATION(ligne,colonne) \
ASD2(COND(IL_FAUT(utiliser_la_matrice_de_rotation_directe) \
,matrice_de_rotation_directe \
,matrice_de_rotation_inverse \
) \
,ligne \
,colonne \
) \
/* Acces a l'un des elements de l'une des deux matrices de rotation. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* V E R I F I C A T I O N D E S V E C T E U R S : */
/* */
/*************************************************************************************************************************************/
#define VERIFICATION_D_UN_VECTEUR(vecteur_a_verifier,message) \
Bblock \
Test(IZEQ(longF3D(vecteur_a_verifier))) \
Bblock \
EGAL(un_vecteur_nul_a_ete_rencontre,VRAI); \
/* Ceci a ete introduit le 20030702104911 afin de renvoyer alors : {theta,psi,phi}={0,0,0}. */ \
PRINT_ATTENTION("un vecteur est nul"); \
CAL1(Prer2("il s'agit d'un vecteur de type '%s' et d'index %d\n",message,index)); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
Eblock \
/* Verification d'un vecteur... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A S S A G E D ' U N R E F E R E N T I E L C A R T E S I E N */
/* A U N R E F E R E N T I E L E U L E R I E N : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
#include xrv/ARITHMET.22.I"
#include xci/valeurs.03.I"
DEFV(Logical,INIT(utiliser_la_matrice_de_rotation_directe,UTILISER_LA_MATRICE_DE_ROTATION_DIRECTE));
/* Faut-il la matrice de rotation directe passant de {OX1,OY1,OZ1} a {OX2,OY2,OZ2} */
/* ("VRAI") ou inverse ("FAUX") ? */
DEFV(Logical,INIT(editer_les_vecteurs_directeurs,EDITER_LES_VECTEURS_DIRECTEURS));
/* Faut-il editer les vecteurs directeurs ('VRAI') ou pas ('FAUX') ? Cela a ete introduit le */
/* 20051107151658 apres l'observation d'anomales dans 'v $xiirk/.NCOR.f1.1.11.$U' lors */
/* de l'utilisation de 'v $xrr/N_spheres.11$K' et de 'v $xrr/N_ellipso.11$K' avec des */
/* corps dont les trajectoires sont a priori coplanaires et qui n'apparaissent pas ainsi */
/* dans les images... */
DEFV(Float,INIT(ponderation_THETA,PONDERATION_THETA_IMPLICITE));
DEFV(Float,INIT(ponderation_PSI_,PONDERATION_PSI__IMPLICITE));
DEFV(Float,INIT(ponderation_PHI_,PONDERATION_PHI__IMPLICITE));
/* Ponderation de selection des angles d'Euler. */
/*..............................................................................................................................*/
#include xrv/champs_5.1A.I"
/* Ceci fut introduit le 20070103170631... */
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(PROCESS_ARGUMENT_I("nombre_elements=""ne=",nombre_d_elements
,BLOC(VIDE;)
,BLOC(Bblock
PRINT_AVERTISSEMENT("'ne=' doit etre defini avant toute entree de fichiers");
Eblock
)
);
PROCESS_ARGUMENTS_DE_DEFINITION_DES_FICHIERS_01;
PROKESF_ARGUMENT_FICHIER("LISTE_V1X="
,fichier_LISTE_V1X
,liste_initiale_des_V1X
,V1X_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_V1Y="
,fichier_LISTE_V1Y
,liste_initiale_des_V1Y
,V1Y_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_V1Z="
,fichier_LISTE_V1Z
,liste_initiale_des_V1Z
,V1Z_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_V2X="
,fichier_LISTE_V2X
,liste_initiale_des_V2X
,V2X_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_V2Y="
,fichier_LISTE_V2Y
,liste_initiale_des_V2Y
,V2Y_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
PROKESF_ARGUMENT_FICHIER("LISTE_V2Z="
,fichier_LISTE_V2Z
,liste_initiale_des_V2Z
,V2Z_IMPLICITE
,lTRANSFORMAT_0d
,iGENERATION_D_UN_FICHIER
);
GET_ARGUMENT_L("directe=",utiliser_la_matrice_de_rotation_directe);
GET_ARGUMENT_N("inverse=",utiliser_la_matrice_de_rotation_directe);
GET_ARGUMENT_L("vecteurs_directeurs=""vd=",editer_les_vecteurs_directeurs);
GET_ARGUMENT_F("pTHETA=""Pond1=",ponderation_THETA);
GET_ARGUMENT_F("pPSI=""Pond2=",ponderation_PSI_);
GET_ARGUMENT_F("pPHI=""Pond3=",ponderation_PHI_);
PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_3;
/* Cette procedure fut introduite le 20070103170631... */
PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_1;
/* Cette procedure fut introduite le 20061226193054... */
PROCESS_ARGUMENTS_DE_PARAMETRAGE_DE_LA_GENERATION_DE_SUITE_DE_VALEURS_5;
/* Cette procedure fut introduite le 20211005104138... */
)
);
gOPERATION_SUR_LES_FICHIERS(BLOC(
DEFV(Logical,INIT(un_vecteur_nul_a_ete_rencontre,FAUX));
/* Ceci a ete introduit le 20030702104911 afin de renvoyer alors : {theta,psi,phi}={0,0,0}. */
DEFV(Float,INIT(coordonnee_V1X,ELEMENT_DU_FICHIER_LISTE_V1X(index)));
DEFV(Float,INIT(coordonnee_V1Y,ELEMENT_DU_FICHIER_LISTE_V1Y(index)));
DEFV(Float,INIT(coordonnee_V1Z,ELEMENT_DU_FICHIER_LISTE_V1Z(index)));
/* Recuperation des coordonnees {X,Y,Z} courantes dans les fichiers du vecteur 'V1'. */
DEFV(Float,INIT(coordonnee_V2X,ELEMENT_DU_FICHIER_LISTE_V2X(index)));
DEFV(Float,INIT(coordonnee_V2Y,ELEMENT_DU_FICHIER_LISTE_V2Y(index)));
DEFV(Float,INIT(coordonnee_V2Z,ELEMENT_DU_FICHIER_LISTE_V2Z(index)));
/* Recuperation des coordonnees {X,Y,Z} courantes dans les fichiers du vecteur 'V2'. */
DEFV(deltaF_3D,vecteur_directeur_OX2);
DEFV(deltaF_3D,vecteur_directeur_OY2_non_orthogonal_a_OX2);
DEFV(deltaF_3D,vecteur_directeur_OY2);
DEFV(deltaF_3D,vecteur_directeur_OZ2);
/* Definition du referentiel {OX2,OY2,OZ2} avec un axe "intermediaire" 'OY2' non encore */
/* orthogonal a 'OX2'. */
DEFV(matrixF_3D,matrice_de_rotation_directe);
DEFV(matrixF_3D,matrice_de_rotation_inverse);
/* Definition de la matrice de passage {OX1,OY1,OZ1} --> {OX2,OY2,OZ2} et inverse. */
DEFV(matrixF_3D,matrice_de_rotation_directe_inverse);
/* Afin de verifier que le produit directe*inverse est bien l'unite (cette validation a ete */
/* introduite le 20051107144743). */
DEFV(Float,INIT(angle_theta,FZERO));
DEFV(Float,INIT(angle__psi,FZERO));
DEFV(Float,INIT(angle__phi,FZERO));
/* Definition des angles d'Euler. Le 20030702104911, suite a l'introduction de l'indicateur */
/* 'un_vecteur_nul_a_ete_rencontre', la valeur initiale 'FLOT__UNDEF' a ete remplacee par */
/* 'FZERO', afin de renvoyer {theta,psi,phi}={0,0,0} en cas de defaut... */
DEFV(Float,INIT(cosinus_de_l_angle__phi,FLOT__UNDEF));
DEFV(Float,INIT(__sinus_de_l_angle__phi,FLOT__UNDEF));
/* Et lignes trigonometriques de l'angle 'phi'... */
INITIALISATION_ACCROISSEMENT_3D(vecteur_directeur_OX2
,coordonnee_V1X
,coordonnee_V1Y
,coordonnee_V1Z
);
NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OX2);
VERIFICATION_D_UN_VECTEUR(vecteur_directeur_OX2
,"vecteur directeur OX2"
);
/* Definition de l'axe 'OX2'. */
INITIALISATION_ACCROISSEMENT_3D(vecteur_directeur_OY2_non_orthogonal_a_OX2
,coordonnee_V2X
,coordonnee_V2Y
,coordonnee_V2Z
);
NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OY2_non_orthogonal_a_OX2);
VERIFICATION_D_UN_VECTEUR(vecteur_directeur_OY2_non_orthogonal_a_OX2
,"vecteur directeur OY2 non orthogonal a OX2"
);
/* Definition d'un axe 'OY2' non encore orthogonal a 'OX2'. */
PRODUIT_VECTORIEL_ACCROISSEMENT_3D(vecteur_directeur_OZ2
,vecteur_directeur_OX2
,vecteur_directeur_OY2_non_orthogonal_a_OX2
);
NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OZ2);
VERIFICATION_D_UN_VECTEUR(vecteur_directeur_OZ2
,"vecteur directeur OZ2"
);
/* Definition de l'axe 'OZ2'. */
PRODUIT_VECTORIEL_ACCROISSEMENT_3D(vecteur_directeur_OY2
,vecteur_directeur_OZ2
,vecteur_directeur_OX2
);
NORMALISATION_ACCROISSEMENT_3D(vecteur_directeur_OY2);
VERIFICATION_D_UN_VECTEUR(vecteur_directeur_OY2
,"vecteur directeur OY2"
);
/* Definition de l'axe 'OY2' orthogonal a 'OX2'... */
Test(EST_FAUX(un_vecteur_nul_a_ete_rencontre))
Bblock
Test(IL_FAUT(editer_les_vecteurs_directeurs))
Bblock
CAL3(Prme3("vecteur directeur OX2={%f,%f,%f}\n"
,ASD1(vecteur_directeur_OX2,dx)
,ASD1(vecteur_directeur_OX2,dy)
,ASD1(vecteur_directeur_OX2,dz)
)
);
CAL3(Prme3("vecteur directeur OY2={%f,%f,%f}\n"
,ASD1(vecteur_directeur_OY2,dx)
,ASD1(vecteur_directeur_OY2,dy)
,ASD1(vecteur_directeur_OY2,dz)
)
);
CAL3(Prme3("vecteur directeur OZ2={%f,%f,%f}\n"
,ASD1(vecteur_directeur_OZ2,dx)
,ASD1(vecteur_directeur_OZ2,dy)
,ASD1(vecteur_directeur_OZ2,dz)
)
);
Eblock
ATes
Bblock
Eblock
ETes
INITIALISATION_MATRICE_3D(matrice_de_rotation_directe
,ASD1(vecteur_directeur_OX2,dx)
,ASD1(vecteur_directeur_OX2,dy)
,ASD1(vecteur_directeur_OX2,dz)
,ASD1(vecteur_directeur_OY2,dx)
,ASD1(vecteur_directeur_OY2,dy)
,ASD1(vecteur_directeur_OY2,dz)
,ASD1(vecteur_directeur_OZ2,dx)
,ASD1(vecteur_directeur_OZ2,dy)
,ASD1(vecteur_directeur_OZ2,dz)
);
INITIALISATION_MATRICE_3D(matrice_de_rotation_inverse
,ASD1(vecteur_directeur_OX2,dx)
,ASD1(vecteur_directeur_OY2,dx)
,ASD1(vecteur_directeur_OZ2,dx)
,ASD1(vecteur_directeur_OX2,dy)
,ASD1(vecteur_directeur_OY2,dy)
,ASD1(vecteur_directeur_OZ2,dy)
,ASD1(vecteur_directeur_OX2,dz)
,ASD1(vecteur_directeur_OY2,dz)
,ASD1(vecteur_directeur_OZ2,dz)
);
/* Calcul de la matrice de rotation permettant de passer du referentiel {OX1,OY1,OZ1} au */
/* referentiel {OX2,OY2,OZ2} et de son inverse. */
PRODUIT_MATRICE_MATRICE_3D(matrice_de_rotation_directe_inverse
,matrice_de_rotation_directe
,matrice_de_rotation_inverse
);
Test(IFNE_a_peu_pres_absolu(mDET3(matrice_de_rotation_directe_inverse)
,FU
,GRAND_EPSILON
)
)
/* Afin de verifier que le produit directe*inverse est bien l'unite (cette validation a ete */
/* introduite le 20051107144743). Evidemment, ce test ne teste pas individuellement les 3x3 */
/* elements de la matrice 'matrice_de_rotation_directe_inverse' et cette derniere pourrait */
/* tres bien ne pas etre la matrice unite tout en ayant un determinant egal a 1... Mais la */
/* programmation utilisee ci-dessus est tres simple... */
Bblock
PRINT_ERREUR("il semble que le produit 'directe*inverse' n'est pas egal a l'unite");
Eblock
ATes
Bblock
Eblock
ETes
EGAL(angle__phi
,ATAN(NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cz,cx))
,NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cz,cy))
)
);
EGAL(cosinus_de_l_angle__phi,COSX(angle__phi));
EGAL(__sinus_de_l_angle__phi,SINX(angle__phi));
/* Angle 'phi' et ses lignes trigonometriques... */
EGAL(angle__psi
,ATAN(NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cx,cz))
,NEGA(ACCES_A_UNE_MATRICE_DE_ROTATION(cy,cz))
)
);
/* Angle 'psi'. */
EGAL(angle_theta
,ATAN(COND(IZNE(__sinus_de_l_angle__phi)
,DIVI(NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cz,cx)),__sinus_de_l_angle__phi)
,DIVI(NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cz,cy)),cosinus_de_l_angle__phi)
)
,NEUT(ACCES_A_UNE_MATRICE_DE_ROTATION(cz,cz))
)
);
/* Angle 'theta'. */
/* */
/* Voir 'v $ximD/definit.1$DEF INITIALISATION_D_UNE_MATRICE_DE_ROTATION_D_EULER' afin de */
/* justifier les formules precedentes... */
Eblock
ATes
Bblock
/* Dans ce cas, les valeurs initiales {theta,psi,phi}={0,0,0} sont renvoyees, ce qui */
/* correspond alors a la transformation unite... */
Eblock
ETes
)
,LIZ3(ponderation_THETA,angle_theta
,ponderation_PSI_,angle__psi
,ponderation_PHI_,angle__phi
)
,EDITER_LA_VALEUR_RESULTANTE_DANS_gOPERATION_SUR_LES_FICHIERS
,nombre_d_exemplaires_du_resultat_de_l_operation_sur_les_valeurs_courantes
);
/* Conversion cartesienne-Eulerienne. */
lGENERATION_D_UN_FICHIER(liste_initiale_des_V2Z,V2Z_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_V2Y,V2Y_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_V2X,V2X_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_V1Z,V1Z_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_V1Y,V1Y_IMPLICITE);
lGENERATION_D_UN_FICHIER(liste_initiale_des_V1X,V1X_IMPLICITE);
RETU_Commande;
Eblock
ECommande