/*************************************************************************************************************************************/ /* */ /* 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