/*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N Q U E L C O N Q U E : */ /* */ /* */ /* Author of '$xrs/HyperCube.11$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20230303181852). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 DIMENSION_DE_L_HYPER_CUBE \ TRI_DIMENSIONNEL \ /* Dimension de l'hypercube. */ #define EDITER_LE_SEPARATEUR_DES_SOMMETS \ FAUX \ /* Doit-on editer le separateur "--o-->" ('VRAI') ou pas ('FAUX') ? */ #define PROJETER_LES_SOMMETS \ FAUX #define FAIRE_DE_L_HYPER_PROJECTION_PARALLELE \ VRAI /* Doit-on projeter les sommets ('VRAI') ou pas ('FAUX') ? Et si 'VRAI' faut-il qu'elle */ /* soit parallele ('VRAI') ou perspective ('FAUX'), ceci ayant introduit le 20230307164837 ? */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #define BASE \ BASE2 \ /* Base de definition... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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" #include xrv/ARITHMET.21.I" #include xrv/champs_5.41.I" #define PX_IMPLICITE \ FZERO #define PY_IMPLICITE \ FZERO #define PZ_IMPLICITE \ FZERO gGENERATION_D_UN_FICHIER(fichier_LISTE_PX,liste_initiale_des_PX); gGENERATION_D_UN_FICHIER(fichier_LISTE_PY,liste_initiale_des_PY); gGENERATION_D_UN_FICHIER(fichier_LISTE_PZ,liste_initiale_des_PZ); #define HP_IMPLICITE \ FZERO #define HO_IMPLICITE \ FZERO gGENERATION_D_UN_FICHIER(fichier_LISTE_HP,liste_initiale_des_HP); gGENERATION_D_UN_FICHIER(fichier_LISTE_HO,liste_initiale_des_HO); /* Definition en memoire des fichiers definissant la Projection. */ /* */ /* Les listes {PX,PY,PZ} definissent les Ponderations de Projection, quant aux listes */ /* 'HP' et 'HO' elles definissent respectivement l'Hyper-Plan et l'Hyper-Observateur'... */ #define INDEX_EFFECTIF(index) \ MIN2(index,LSTX(premier_element_d_un_fichier,NombreDeSommets)) #define ELEMENT_DU_FICHIER_LISTE_PX(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_PX,INDEX_EFFECTIF(index)) #define ELEMENT_DU_FICHIER_LISTE_PY(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_PY,INDEX_EFFECTIF(index)) #define ELEMENT_DU_FICHIER_LISTE_PZ(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_PZ,INDEX_EFFECTIF(index)) #define ELEMENT_DU_FICHIER_LISTE_HP(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_HP,INDEX_EFFECTIF(index)) #define ELEMENT_DU_FICHIER_LISTE_HO(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_HO,INDEX_EFFECTIF(index)) /* Acces a un element courant des fichiers definissant la Projection. */ /* */ /* On notera le 20230310142834 que le fichier 'LISTE_HP' a autant d'elements que les autres */ /* (et en particulier 'LISTE_HO') et ce a cause de 'PROKESF_ARGUMENT_FICHIER(...)' qui */ /* demande que tous les fichiers aient la meme taille. Par contre, cela n'est pas vrai */ /* dans 'v $ximd/operator.1$FON COEFFICIENT_DE_PROJECTION_PERSPECTIVE_01_4D_3D_R' ou la */ /* definition du plan de projection 'plan_de_projection_perspective_01_4D' a cinq elements */ /* alors que les autres listes en ont quatre (c'est-a-dire la dimension de l'espace...). */ /* Mais cela n'est pas grave... */ /*===================================================================================================================================*/ /* :Debut_listMN_HYPER_CUBE_DE_DIMENSION_N: */ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N ' N ' : */ /* */ /* */ /* Definition ('v $xtc/hyper_cube.02$c') : */ /* */ /* Un cube peut etre defini par ses aretes et donc */ /* par des couples de sommets adjacents. Chacun d'entre-eux */ /* sera identifie par 'XYZ' ou 'X', 'Y' et 'Z' sont ses */ /* coordonnees que l'on suppose valoir 0 ou 1. Elles */ /* peuvent alors etre aussi considerees comme des bits */ /* et donc ces 3 bits 'XYZ' seront un numero des sommets */ /* entre 0 et 7... */ /* */ /* */ /* 011 ----------------------------- 111 */ /* /. /| */ /* / . / | */ /* / . / | */ /* / . / | */ /* / . / | */ /* / . / | */ /* / . / | */ /* / . / | */ /* / . / | */ /* 010 ----------------------------- 110 | */ /* | . | | */ /* | . | | */ /* | . | | */ /* | . | | */ /* | . | | */ /* | . | | */ /* | . | | */ /* | 001. . . . . . . . . . | . . . . | 101 */ /* | . | / */ /* | . | / */ /* | . | / */ /* Y^ | . | / */ /* | | . | / */ /* | Z | . | / */ /* | / | . | / */ /* | / | . | / */ /* |/ |. |/ */ /* O--------> 000 ----------------------------- 100 */ /* X */ /* */ /* */ /* On note alors que les deux sommets {n1,n2} */ /* definissant une arete sont codes par les memes */ /* bits sauf un. Le "ou exclusif" de leurs numeros */ /* ne contiendra donc qu'un seul bit 1, tous les autres */ /* etant nuls. Il correspondra a une puissance de 2, */ /* ce qui implique que son logarithme en base 2 */ /* sera un nombre entier. */ /* */ /* C'est donc ainsi que sera defini un hypercube */ /* de dimension N. Voici donc la procedure : */ /* */ /* 1-Generer la liste L1 des entiers 'n' dans [0,(2^N)-1]. */ /* */ /* 2-Generer la liste L2 des couples differents {n1,n2} */ /* 'n1' et n2' appartenant a L1 et l'ordre etant indifferent. */ /* */ /* 3-Calculer pour tout couple {n1,n2} : */ /* */ /* A = log (n1.EOR.n2) */ /* 2 */ /* */ /* ('.EOR.' etant l'operateur "ou exclusif"). */ /* */ /* Si 'A' est un nombre entier, alors le couple {n1,n2} */ /* defini une arete de l'hypercube de dimension N. */ /* */ /* */ /* A titre d'exemple, voici la generation de */ /* l'hypercube de dimension 3 (c'est-a-dire le */ /* cube "standard") donnee par 'v $xtc/hyper_cube.12$c' : */ /* */ /* */ /* Generation de la liste des entiers de 0 a 7 (liste 'L1') : */ /* */ /* n */ /* */ /* 000 */ /* 001 */ /* 010 */ /* 011 */ /* 100 */ /* 101 */ /* 110 */ /* 111 */ /* */ /* */ /* Generation des aretes (liste 'L2') : */ /* */ /* n1 n2 */ /* */ /* EOR(000,001)=001 log2=0 arete={000,001} */ /* */ /* EOR(000,010)=010 log2=1 arete={000,010} */ /* EOR(001,010)=011 log2=1.584963 */ /* */ /* EOR(000,011)=011 log2=1.584963 */ /* EOR(001,011)=010 log2=1 arete={001,011} */ /* EOR(010,011)=001 log2=0 arete={010,011} */ /* */ /* EOR(000,100)=100 log2=2 arete={000,100} */ /* EOR(001,100)=101 log2=2.321928 */ /* EOR(010,100)=110 log2=2.584963 */ /* EOR(011,100)=111 log2=2.807355 */ /* */ /* EOR(000,101)=101 log2=2.321928 */ /* EOR(001,101)=100 log2=2 arete={001,101} */ /* EOR(010,101)=111 log2=2.807355 */ /* EOR(011,101)=110 log2=2.584963 */ /* EOR(100,101)=001 log2=0 arete={100,101} */ /* */ /* EOR(000,110)=110 log2=2.584963 */ /* EOR(001,110)=111 log2=2.807355 */ /* EOR(010,110)=100 log2=2 arete={010,110} */ /* EOR(011,110)=101 log2=2.321928 */ /* EOR(100,110)=010 log2=1 arete={100,110} */ /* EOR(101,110)=011 log2=1.584963 */ /* */ /* EOR(000,111)=111 log2=2.807355 */ /* EOR(001,111)=110 log2=2.584963 */ /* EOR(010,111)=101 log2=2.321928 */ /* EOR(011,111)=100 log2=2 arete={011,111} */ /* EOR(100,111)=011 log2=1.584963 */ /* EOR(101,111)=010 log2=1 arete={101,111} */ /* EOR(110,111)=001 log2=0 arete={110,111} */ /* */ /* */ /*************************************************************************************************************************************/ /* :Fin_listMN_HYPER_CUBE_DE_DIMENSION_N: */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N V E R S I O N B I N A I R E : */ /* */ /*************************************************************************************************************************************/ DEFV(Local,DEFV(Int,INIT(NombreDeSommets,UNDEF))); DEFV(Local,DEFV(Logical,INIT(projeter_les_sommets,PROJETER_LES_SOMMETS))); DEFV(Local,DEFV(Logical,INIT(faire_de_l_hyper_projection_parallele,FAIRE_DE_L_HYPER_PROJECTION_PARALLELE))); /* Doit-on projeter les sommets ('VRAI') ou pas ('FAUX') ? Et si 'VRAI' faut-il qu'elle */ /* soit parallele ('VRAI') ou perspective ('FAUX'), ceci ayant introduit le 20230307164837 ? */ BFonctionV DEFV(FonctionV,ConversionBase(NombreAConvertir,BaseDeNumeration,ExposantMaximaldeLaBase)) DEFV(Argument,DEFV(Int,NombreAConvertir)); DEFV(Argument,DEFV(Int,BaseDeNumeration)); DEFV(Argument,DEFV(Int,ExposantMaximaldeLaBase)); /* Definition des arguments... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Int,INIT(diviseur,INTE(PUIX(FLOT(BaseDeNumeration),FLOT(PRED(ExposantMaximaldeLaBase)))))); DEFV(Int,INIT(NombreCourant,NombreAConvertir)); DEFV(Int,INIT(IndexDeProjection,UNDEF)); gGENERATION_D_UN_FICHIER_liste(liste_des_COORDONNEES); #define ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(index) \ gELEMENT_DU_FICHIER(liste_des_COORDONNEES,index) DEFV(Float,INIT(coordonnee_X,FZERO)); DEFV(Float,INIT(coordonnee_Y,FZERO)); DEFV(Float,INIT(coordonnee_Z,FZERO)); /*..............................................................................................................................*/ iGENERATION_D_UN_FICHIER(liste_des_COORDONNEES,FLOT__UNDEF); EGAL(IndexDeProjection,premier_element_d_un_fichier); Repe(ExposantMaximaldeLaBase) Bblock DEFV(Int,INIT(quotient,UNDEF)); DEFV(Int,INIT(reste___,UNDEF)); EGAL(quotient,DIVI(NombreCourant,diviseur)); EGAL(reste___,REST(NombreCourant,diviseur)); /* Division euclidienne "progressive"... */ Test(IFEXfo(quotient,ZERO,BASE)) Bblock PRINT_ERREUR("Quotient hors limite"); CAL1(Prer3("Il vaut %d alors qu'il devrait etre dans [%d,%d[.\n" ,quotient ,ZERO ,BASE ) ); Eblock ATes Bblock Eblock ETes EGAL(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection),FLOT(quotient)); /* Le "quotient" est le chiffre courant du nombre a convertir suivant la base et c'est */ /* aussi une des coordonnees du sommet courant... */ EGAL(NombreCourant,reste___); EGAL(diviseur,DIVI(diviseur,BASE)); INCR(IndexDeProjection,I); Eblock ERep Test(IL_FAUT(projeter_les_sommets)) Bblock Test(IL_FAUT(faire_de_l_hyper_projection_parallele)) Bblock Eblock ATes Bblock DEFV(Float,INIT(numerateur___R,FZERO)); DEFV(Float,INIT(denominateur_R,FZERO)); EGAL(IndexDeProjection,premier_element_d_un_fichier); Repe(ExposantMaximaldeLaBase) Bblock INCR(numerateur___R ,MUL2(ELEMENT_DU_FICHIER_LISTE_HP(IndexDeProjection) ,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection) ) ); /* On notera que 'numerateur___R' possede a la fin de tous les 'Repe(...)'s la meme */ /* valeur, mais c'est plus simple de le recalculer systematiquement... */ INCR(denominateur_R ,MUL2(ELEMENT_DU_FICHIER_LISTE_HP(IndexDeProjection) ,SOUS(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection) ,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection) ) ) ); /* Voir 'v $ximd/operator.1$FON PROJECTION_PLANE_QUELCONQUE' pour plus d'informations... */ INCR(IndexDeProjection,I); Eblock ERep EGAL(IndexDeProjection,premier_element_d_un_fichier); Repe(ExposantMaximaldeLaBase) Bblock EGAL(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection) ,SOUS(ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection) ,MUL2(DIVI(numerateur___R,denominateur_R) ,SOUS(ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection) ,ELEMENT_DU_FICHIER_LISTE_HO(IndexDeProjection) ) ) ) ); /* Voir 'v $ximd/operator.1$FON PROJECTION_PLANE_QUELCONQUE' pour plus d'informations... */ INCR(IndexDeProjection,I); Eblock ERep Eblock ETes Eblock ATes Bblock Eblock ETes EGAL(IndexDeProjection,premier_element_d_un_fichier); Repe(ExposantMaximaldeLaBase) Bblock DEFV(Float,INIT(CoordonneeCourante,ELEMENT_DU_FICHIER_LISTE_DES_COORDONNEES(IndexDeProjection))); Test(IL_FAUT(projeter_les_sommets)) Bblock INCR(coordonnee_X,MUL2(ELEMENT_DU_FICHIER_LISTE_PX(IndexDeProjection),CoordonneeCourante)); INCR(coordonnee_Y,MUL2(ELEMENT_DU_FICHIER_LISTE_PY(IndexDeProjection),CoordonneeCourante)); INCR(coordonnee_Z,MUL2(ELEMENT_DU_FICHIER_LISTE_PZ(IndexDeProjection),CoordonneeCourante)); Eblock ATes Bblock CAL2(Prin1("%d ",INTE(CoordonneeCourante))); Eblock ETes INCR(IndexDeProjection,I); Eblock ERep Test(IL_FAUT(projeter_les_sommets)) Bblock CAL2(Prin3("%+.^^^ %+.^^^ %+.^^^ ",coordonnee_X,coordonnee_Y,coordonnee_Z)); Eblock ATes Bblock Eblock ETes lGENERATION_D_UN_FICHIER(liste_des_COORDONNEES,FLOT__UNDEF); RETU_VIDE; Eblock EFonctionV /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D ' U N H Y P E R C U B E D E D I M E N S I O N Q U E L C O N Q U E : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock #include xrv/ARITHMET.22.I" DEFV(Int,INIT(dimension_de_l_hyper_cube,DIMENSION_DE_L_HYPER_CUBE)); /* Dimension de l'hypercube. */ DEFV(Logical,INIT(editer_le_separateur_des_sommets,EDITER_LE_SEPARATEUR_DES_SOMMETS)); /* Doit-on editer le separateur "--o-->" ('VRAI') ou pas ('FAUX') ? */ /*..............................................................................................................................*/ GET_ARGUMENTSi(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_PX=" ,fichier_LISTE_PX ,liste_initiale_des_PX ,PX_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_PY=" ,fichier_LISTE_PY ,liste_initiale_des_PY ,PY_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_PZ=" ,fichier_LISTE_PZ ,liste_initiale_des_PZ ,PZ_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_HP=" ,fichier_LISTE_HP ,liste_initiale_des_HP ,HP_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); PROKESF_ARGUMENT_FICHIER("LISTE_HO=" ,fichier_LISTE_HO ,liste_initiale_des_HO ,HO_IMPLICITE ,lTRANSFORMAT_0d ,iGENERATION_D_UN_FICHIER ); GET_ARGUMENT_I("dimension=""d=",dimension_de_l_hyper_cube); GET_ARGUMENT_L("separateur_sommets=""separateur=""sep=",editer_le_separateur_des_sommets); GET_ARGUMENT_L("projeter=""proj=",projeter_les_sommets); GET_ARGUMENT_L("ProjectionParallele=""pparallele=""ppar=",faire_de_l_hyper_projection_parallele); GET_ARGUMENT_N("ProjectionPerspective=""pperspective=""pper=",faire_de_l_hyper_projection_parallele); ) ); EGAL(NombreDeSommets,INTE(PUIX(FLOT(BASE),FLOT(dimension_de_l_hyper_cube)))); Test(IFET(IFEQ(dimension_de_l_hyper_cube,DIMENSION_DE_L_HYPER_CUBE) ,IL_NE_FAUT_PAS(faire_de_l_hyper_projection_parallele) ) ) Bblock PRINT_ERREUR("L'hyper-projection perspective en dimension 3 est inhibee puisqu'elle cree un objet plat."); /* Cela s'et vu le 20230308153642 avec 'v $xiirs/HYPC.21.3' en faisant une rotation */ /* autour de l'axe 'OY' d'environ '$pis2'... */ EGAL(faire_de_l_hyper_projection_parallele,VRAI); Eblock ATes Bblock Eblock ETes Test(IL_FAUT(projeter_les_sommets)) Bblock Test(IFNE(nombre_d_elements,dimension_de_l_hyper_cube)) Bblock PRINT_ERREUR("Les fichiers n'ont pas une taille compatible avec la dimension de l'hypercube"); CAL1(Prer2("La taille vaut %d alors qu'elle devrait valoir %d.\n" ,nombre_d_elements ,dimension_de_l_hyper_cube ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes begin_nouveau_block Bblock DEFV(Int,INIT(nombre1,UNDEF)); DEFV(Int,INIT(nombre2,UNDEF)); DoIn(nombre1,ZERO,PRED(NombreDeSommets),I) /* Generation de la liste de toutes les configurations de "0" et de "1" entre zero et deux */ /* a la puissance 'dimension' moins 1... Il suffit pour cela d'enumerer tous les entiers... */ Bblock DoIn(nombre2,ZERO,PRED(nombre1),I) Bblock DEFV(Float,INIT(logarithme,LObX(FLOT(OUEX(nombre1,nombre2)),FLOT(BASE)))); /* Une arete de l'hypercube est defini par deux entiers 'nombre1' et 'nombre2' qui ne */ /* different que d'un seul bit. Pour verifier cela il suffit de calculer le ou "exclusif" */ /* de ces deux nombres. S'il ne contient qu'un bit a 1, c'est une puissance de 2 et alors */ /* son logarithme en base 2 est un nombre entier... */ Test(EST_ENTIER(logarithme)) /* Cas ou on a trouve une artede l'hypercube : */ Bblock ConversionBase(MIN2(nombre1,nombre2),BASE,dimension_de_l_hyper_cube); Test(IL_FAUT(editer_le_separateur_des_sommets)) Bblock CAL2(Prin0(" --o--> ")); Eblock ATes Bblock Eblock ETes ConversionBase(MAX2(nombre1,nombre2),BASE,dimension_de_l_hyper_cube); CALS(Fsauts_de_lignes(UN)); Eblock ATes Bblock Eblock ETes Eblock EDoI Eblock EDoI Eblock end_nouveau_block RETU_Commande; Eblock ECommande