/*************************************************************************************************************************************/ /* */ /* C O N S T R U C T I O N D E L ' E P O N G E D E M E N G E R : */ /* */ /* */ /* Author of '$xrf/EpongeDeMenger.01$I' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20140909133215). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T I O N R E C U R S I V E D E L ' E P O N G E D E M E N G E R : */ /* */ /*************************************************************************************************************************************/ DEFV(Local,DEFV(Logical,INIT(compatibilite_20240617,COMPATIBILITE_20240617))); /* Permet de proceder a des calculs compatibles a ceux qui furent effectues anterieurement */ /* au 20240617093456. */ /* */ /* Le 20240618075356, a cause des images du type 'v $xiirf/SIER.61.2' ou les bords sont */ /* marques, je suis passe par defaut au mode compatibilite... */ DEFV(Local,DEFV(Logical,INIT(compatibilite_20240917,COMPATIBILITE_20240917))); /* Permet de proceder a des calculs compatibles a ceux qui furent effectues anterieurement */ /* au 20240917095113. */ #define Translation_Optionnelle_MaximumDoIn \ COND(IL_FAUT(compatibilite_20240617),ZERO,UN) #define Cube_cDENORMALISE_OX(coordonneeX) \ OPC1(IL_FAUT(utiliser_la_super_echelle) \ ,SUPER_cDENORMALISE_OX \ ,_cDENORMALISE_OX \ ,coordonneeX \ ) #define XCubeMinimum \ Cube_cDENORMALISE_OX(NEUT(ASI1(origine_du_cube,x))) #define XCubeMaximum \ Cube_cDENORMALISE_OX(ADD2(ASI1(origine_du_cube,x),ASI1(cote_du_cube,dx))) #define XCubeMinimumDoIn \ XCubeMinimum #define XCubeMaximumDoIn \ nPREX(XCubeMaximum,Translation_Optionnelle_MaximumDoIn) #define Cube_cDENORMALISE_OY(coordonneeY) \ OPC1(IL_FAUT(utiliser_la_super_echelle) \ ,SUPER_cDENORMALISE_OY \ ,_cDENORMALISE_OY \ ,coordonneeY \ ) #define YCubeMinimum \ Cube_cDENORMALISE_OY(NEUT(ASI1(origine_du_cube,y))) #define YCubeMaximum \ Cube_cDENORMALISE_OY(ADD2(ASI1(origine_du_cube,y),ASI1(cote_du_cube,dy))) #define YCubeMinimumDoIn \ YCubeMinimum #define YCubeMaximumDoIn \ nPREY(YCubeMaximum,Translation_Optionnelle_MaximumDoIn) #define Cube_cDENORMALISE_OZ(coordonneeZ) \ OPC1(IL_FAUT(utiliser_la_super_echelle) \ ,SUPER_cDENORMALISE_OZ \ ,_cDENORMALISE_OZ \ ,coordonneeZ \ ) #define ZCubeMinimum \ Cube_cDENORMALISE_OZ(NEUT(ASI1(origine_du_cube,z))) #define ZCubeMaximum \ Cube_cDENORMALISE_OZ(ADD2(ASI1(origine_du_cube,z),ASI1(cote_du_cube,dz))) #define ZCubeMinimumDoIn \ ZCubeMinimum #define ZCubeMaximumDoIn \ COND(IFEQ(ZCubeMinimum,ZCubeMaximum) \ ,ZCubeMaximum \ ,nPREZ(ZCubeMaximum,Translation_Optionnelle_MaximumDoIn) \ ) /* Definition du "cube" courant dont les cotes, apres denormalisations, ne sont pas */ /* necessairement egaux (et ce a cause des definitions des axes 'OX', 'OY' et 'OZ' qui sont */ /* a priori et en toute generalite differentes). Ceci a ete introduit le 20140923160150. */ /* */ /* Le 20240617093723 je note (suite a la modification du 20240617080311 qui permet de */ /* colorier differemment les carres et les cubes...) qu'il y a un recouvrement sur les */ /* cotes correspondant aux maxima... */ /* */ /* La definition particuliere de 'ZCubeMaximumDoIn' est due au fait que l'on genere aussi */ /* des tapis de Sierpinski qui n'ont donc pas d'epaisseur 'Z'... */ #define TRACER(compteur,tabulation,sequence) \ Bblock \ Test(IL_FAUT(tracer_les_differentes_operations)) \ Bblock \ CAL3(Prme4("NumeroTrace=%04d%*s fonction=%s" \ ,compteur \ ,COND(IFEQ(tabulation,UNDEF),GRO10(profondeur_courante),tabulation) \ ,C_VIDE \ ,NomDeLaFonctionCourante \ ) \ ); \ \ BLOC(sequence); \ \ INCR(compteur,I); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Procedure introduite le 20240618150653... */ DEFV(Local,DEFV(Float,INIT(increment_courant_de__niveau_de_marquage_de_l_eponge,ZERO))); DEFV(Local,DEFV(Float,INIT(increment_de__increment_courant_de__niveau_de_marquage_de_l_eponge,ZERO))); /* Afin de pouvoir faire varier 'niveau_de_marquage_de_l_eponge' au cours du temps. Ceci */ /* fut introduit le 20240617080311... */ /* */ /* Le 20240621093645 il y a eu passage de 'Int' a 'Float' afin de permettre de gerer de */ /* tres longues sequences d'incrementation sans problemes de "debordement"... */ BFonctionI DEFV(LoF,DEFV(FonctionI,GenerationDunCube(ARGUMENT_POINTERs(origine_du_cube) ,ARGUMENT_POINTERs(cote_du_cube) ,album_d_imagesR ,niveau_de_marquage_de_l_eponge ,marquer_le_bord_X_de_l_eponge ,marquer_le_bord_Y_de_l_eponge ,marquer_le_bord_Z_de_l_eponge ,niveau_de_marquage_du_bord_de_l_eponge ,ARGUMENT_POINTERs(rapport_d_homothetie_cumule) ,profondeur_courante ) ) ) /* La mise de cette fonction dans un '$I' est due aux operateurs 'OPC1(...)' qu'elle */ /* utilise un peu plus loin. Cette fonction a ete introduite le 20140916105025... */ DEFV(Argument,DEFV(pointF_3D,POINTERs(origine_du_cube))); DEFV(Argument,DEFV(deltaF_3D,POINTERs(cote_du_cube))); /* Definition du cube Argument. */ DEFV(Argument,DEFV(album,album_d_imagesR)); DEFV(Argument,DEFV(genere_p,niveau_de_marquage_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_X_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_Y_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_Z_de_l_eponge)); DEFV(Argument,DEFV(genere_p,niveau_de_marquage_du_bord_de_l_eponge)); /* La possibilite de marquer le bord differemment a ete introduite le 20150326151832... */ DEFV(Argument,DEFV(coeffI_3D,POINTERs(rapport_d_homothetie_cumule))); /* Introduit le 20171117174022... */ DEFV(Argument,DEFV(Int,profondeur_courante)); /* Definition du niveau de recursivite (ne sert que pour 'TRACER(...)'). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ TRACER(compteur_de_trace_1 ,UNDEF ,BLOC( Bblock CAL3(Prme6(".......... : OrigineCube={%04d,%04d,%04d} ExtremiteCube={%04d,%04d,%04d}\n" ,Cube_cDENORMALISE_OX(NEUT(ASI1(origine_du_cube,x))) ,Cube_cDENORMALISE_OY(NEUT(ASI1(origine_du_cube,y))) ,Cube_cDENORMALISE_OZ(NEUT(ASI1(origine_du_cube,z))) ,Cube_cDENORMALISE_OX(ADD2(ASI1(origine_du_cube,x),ASI1(cote_du_cube,dx))) ,Cube_cDENORMALISE_OY(ADD2(ASI1(origine_du_cube,y),ASI1(cote_du_cube,dy))) ,Cube_cDENORMALISE_OZ(ADD2(ASI1(origine_du_cube,z),ASI1(cote_du_cube,dz))) ) ); Eblock ) ); begin_albumQ(DoIn,ZCubeMinimumDoIn,ZCubeMaximumDoIn,PasZ ,DoIn,YCubeMinimumDoIn,YCubeMaximumDoIn,PasY ,DoIn,XCubeMinimumDoIn,XCubeMaximumDoIn,PasX ) Bblock DEFV(Logical,INIT(marquer_le_point_courant,VRAI)); DEFV(genere_p,INIT(niveau_de_marquage ,COND(I3OU(IFET(IL_FAUT(marquer_le_bord_X_de_l_eponge) ,IFOU(IFEQ(X,XCubeMinimum),IFEQ(X,XCubeMaximumDoIn)) ) ,IFET(IL_FAUT(marquer_le_bord_Y_de_l_eponge) ,IFOU(IFEQ(Y,YCubeMinimum),IFEQ(Y,YCubeMaximumDoIn)) ) ,IFET(IL_FAUT(marquer_le_bord_Z_de_l_eponge) ,IFOU(IFEQ(Z,ZCubeMinimum),IFEQ(Z,XCubeMaximumDoIn)) ) ) ,niveau_de_marquage_du_bord_de_l_eponge ,ADD2(niveau_de_marquage_de_l_eponge,INTE(increment_courant_de__niveau_de_marquage_de_l_eponge)) ) ) ); Test(IL_FAUT(generaliser_les_cubes)) Bblock DEFV(Float,INIT(XCubeCentre,ADD2(ASI1(origine_du_cube,x),MOIT(ASI1(cote_du_cube,dx))))); DEFV(Float,INIT(YCubeCentre,ADD2(ASI1(origine_du_cube,y),MOIT(ASI1(cote_du_cube,dy))))); DEFV(Float,INIT(ZCubeCentre,ADD2(ASI1(origine_du_cube,z),MOIT(ASI1(cote_du_cube,dz))))); /* Introduits le 20171117160410... */ DEFV(Float,INIT(XCubeCourant,FLOT__UNDEF)); DEFV(Float,INIT(YCubeCourant,FLOT__UNDEF)); DEFV(Float,INIT(ZCubeCourant,FLOT__UNDEF)); DEFV(Float,INIT(equation_locale,FLOT__UNDEF)); EGAL(XCubeCourant ,MUL2(ASI1(rapport_d_homothetie_cumule,cx) ,SOUS(Cube_cDENORMALISE_OX(X),XCubeCentre) ) ); EGAL(YCubeCourant ,MUL2(ASI1(rapport_d_homothetie_cumule,cy) ,SOUS(Cube_cDENORMALISE_OY(Y),YCubeCentre) ) ); EGAL(ZCubeCourant ,MUL2(ASI1(rapport_d_homothetie_cumule,cz) ,SOUS(Cube_cDENORMALISE_OZ(Z),ZCubeCentre) ) ); EGAL(equation_locale,HORNER_3_03__COUPE_QUELCONQUE_ALBUM(XCubeCourant,YCubeCourant,ZCubeCourant)); /* Calcul d'un polynome au point {X,Y,Z}, l'origine des coordonnees etant le centre du cube. */ /* */ /* On rappelle les correspondances suivantes : */ /* */ /* a001 --> x */ /* a010 --> y */ /* a100 --> z */ /* (...) */ /* */ /* Ainsi, par exemple, pour calculer : */ /* */ /* x-y */ /* */ /* on fera : */ /* */ /* a???=0 */ /* */ /* a001=+1 +1.x */ /* a010=-1 -1.y */ /* a100=0 +0.z */ /* a000=0 +0 */ /* */ Test(OPC1(IL_FAUT(generaliser_les_cubes_____faire_un_IZLE) ,IZLE ,IZGT ,equation_locale ) ) Bblock /* Cas : */ /* */ /* HORNER_3_03(X,Y,Z) <= 0 */ /* */ /* (test par defaut...). */ Eblock ATes Bblock EGAL(marquer_le_point_courant,FAUX); /* Cas : */ /* */ /* HORNER_3_03(X,Y,Z) > 0 */ /* */ Eblock ETes Eblock ATes Bblock Eblock ETes Test(IL_FAUT(marquer_le_point_courant)) Bblock Astore_point_valide(niveau_de_marquage ,album_d_imagesR ,X,Y,Z ); /* On utilise 'Astore_point_valide(...)' (et non pas 'Astore_point(...)' car, en effet, les */ /* denormalisations peuvent induire des debordements... */ /* */ /* Le 20240617080311 a ete introduite une eventuelle dynamique de 'niveau_de_marquage'... */ Eblock ATes Bblock Eblock ETes Eblock end_albumQ(EDoI,EDoI,EDoI) Test(IL_FAUT(compatibilite_20240917)) Bblock Eblock ATes Bblock INCR(increment_courant_de__niveau_de_marquage_de_l_eponge ,increment_de__increment_courant_de__niveau_de_marquage_de_l_eponge ); /* Introduit le 20240917095113. En effet, il est assez logique que l'on puisse modifier */ /* le niveau de marquage qu'il y ait ou pas un processus aleatoire... */ Eblock ETes RETU_ERROR; Eblock EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T E U R A L E A T O I R E : */ /* */ /*************************************************************************************************************************************/ #include xrv/ARITHMET.1d.I" #include xrv/ARITHMET.21.I" #include xrv/champs_5.41.I" DEFV(Static,DEFV(Positive,INIT(nombre_de_tirages_aleatoires,ZERO))); /* Introduit le 20240619093414 et utile surtout dans le cas ou sera utilise un generateur */ /* pre-calcule ('IL_FAUT(utiliser_un_generateur_aleatoire_pre_calcule)')... */ DEFV(Static,DEFV(Int,INIT(nombre_d_elements,NOMBRE_D_ELEMENTS))); /* On notera que l'on ne peut pas utiliser ici : */ /* */ /* #include xrv/ARITHMET.22$I" */ /* */ /* pour definir 'nombre_d_elements' (obligatoire a cause de 'DERNIER_ELEMENT_D_UN_FICHIER' */ /* qui suit...) a cause de l'absence du 'DEFV(Static,' dans cet include... */ #define VALEURS_ALEATOIRES_PRE_CALCULEES_IMPLICITE \ FLOT__BLANC DEFV(Local,DEFV(Int,INIT(index_des_valeurs_aleatoires_pre_calculees,PREMIER_ELEMENT_D_UN_FICHIER))); gGENERATION_D_UN_FICHIER(fichier_LISTE_VALEURS_ALEATOIRES_PRE_CALCULEES,liste_initiale_des_VALEURS_ALEATOIRES_PRE_CALCULEES); #define ELEMENT_DU_FICHIER_LISTE_VALEURS_ALEATOIRES_PRE_CALCULEES(index) \ gELEMENT_DU_FICHIER(liste_initiale_des_VALEURS_ALEATOIRES_PRE_CALCULEES,index) /* Acces a un element courant des fichiers de coordonnees et de niveaux. */ #define PSEUDO_CODE_ALEATOIRE \ NEUF \ /* Introduit le 20240920095025 afin de designer une valeur qui devra etre aleatoire */ \ /* dans 'ELEMENT_DU_FICHIER_LISTE_VALEURS_ALEATOIRES_PRE_CALCULEES(...)'... */ #define GENERATION_D_UNE_VALEUR_ALEATOIRE(valeur_aleatoire_flottante) \ Bblock \ Test(IL_NE_FAUT_PAS(utiliser_le_generateur_a_periodicite_parametrable)) \ Bblock \ EGAL(valeur_aleatoire_flottante \ ,COND(IL_NE_FAUT_PAS(utiliser_un_espace_de_parametrage_tridimensionnel) \ ,rdnI2D(ADRESSE(point_courant_de_l_espace_de_parametrage_2D) \ ,graine \ ,RDN_INIT_AND_GENERE \ ,FLOT(FAUX),FLOT(VRAI) \ ) \ ,rdnI3D(ADRESSE(point_courant_de_l_espace_de_parametrage_3D) \ ,graine \ ,RDN_INIT_AND_GENERE \ ,FLOT(FAUX),FLOT(VRAI) \ ) \ ) \ ); \ /* Generation d'une valeur aleatoire dans [FAUX,VRAI] et parametree par le point courant */ \ /* de l'espace de parametrage : */ \ \ SPIRALE_INITIALISATION; \ /* Initialisation dynamique de 'spirale_nombre_de_points_a_traiter'. */ \ SPIRALE_DEPLACEMENT(ASD1(point_courant_de_l_espace_de_parametrage_2D,x) \ ,ASD1(point_courant_de_l_espace_de_parametrage_2D,y) \ ); \ SPIRALE_DEPLACEMENT(ASD1(point_courant_de_l_espace_de_parametrage_3D,x) \ ,ASD1(point_courant_de_l_espace_de_parametrage_3D,y) \ ); \ /* Deplacement du point courant de la spirale de l'espace de parametrage, et ce en restant */ \ /* dans un plan Z=constante (Zmin)... */ \ SPIRALE_PARCOURS; \ /* Parcours de la spirale avec rotation eventuelle de PI/2 du bras courant... */ \ Eblock \ ATes \ Bblock \ EGAL(valeur_aleatoire_flottante \ ,rdn_iteratif_cercle() \ ); \ EGAL(valeur_aleatoire_flottante \ ,DENO(valeur_aleatoire_flottante,FLOT(FAUX),FLOT(VRAI)) \ ); \ /* Generation d'une valeur aleatoire dans [FAUX,VRAI] non parametree par le point courant */ \ /* de l'espace de parametrage. */ \ /* */ \ /* ATTENTION : on notera que cela est tres different de l'usage de la regle "A" dans */ \ /* la liste 'liste_des_cubes_a_subdiviser_avec_d_eventuels_espaces'. En effet, cette */ \ /* liste n'est utilisee qu'une seule fois a l'initialisation du processus de generation */ \ /* de la structure, alors que 'utiliser_un_generateur_aleatoire_pre_calcule' est appele pour */ \ /* chaque cube. Et ainisi, deux cubes differents n'auront pas a priori le meme decoupage... */ \ Eblock \ ETes \ Eblock \ /* Introduit le 20240920095025 afin de pouvoir etre utilise meme dans le cas ou c'est */ \ /* 'ELEMENT_DU_FICHIER_LISTE_VALEURS_ALEATOIRES_PRE_CALCULEES(...)' qui l'est... */ #define FIN_DE_L_INDECISION(valeur_aleatoire_logique) \ Bblock \ DEFV(Float,INIT(valeur_aleatoire_flottante,FLOT__UNDEF)); \ \ Test(IL_NE_FAUT_PAS(utiliser_un_generateur_aleatoire_pre_calcule)) \ /* Test introduit le 20240617131119... */ \ Bblock \ GENERATION_D_UNE_VALEUR_ALEATOIRE(valeur_aleatoire_flottante); \ Eblock \ ATes \ Bblock \ EGAL(valeur_aleatoire_flottante \ ,ELEMENT_DU_FICHIER_LISTE_VALEURS_ALEATOIRES_PRE_CALCULEES(index_des_valeurs_aleatoires_pre_calculees) \ ); \ \ Test(IFEQ(valeur_aleatoire_flottante,PSEUDO_CODE_ALEATOIRE)) \ Bblock \ GENERATION_D_UNE_VALEUR_ALEATOIRE(valeur_aleatoire_flottante); \ /* Generation aleatoire introduite le 20240920095025... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(valeur_aleatoire_flottante,TRON(valeur_aleatoire_flottante,PROBABILITE_NULLE,PROBABILITE_UNITE)); \ /* Generation d'une valeur aleatoire dans [FAUX,VRAI] non parametree par le point courant */ \ /* de l'espace de parametrage. */ \ \ INCR(index_des_valeurs_aleatoires_pre_calculees,I); \ \ Test(IFGT(index_des_valeurs_aleatoires_pre_calculees,DERNIER_ELEMENT_D_UN_FICHIER)); \ Bblock \ EGAL(index_des_valeurs_aleatoires_pre_calculees,PREMIER_ELEMENT_D_UN_FICHIER); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IL_FAUT(compatibilite_20240917)) \ Bblock \ INCR(increment_courant_de__niveau_de_marquage_de_l_eponge \ ,increment_de__increment_courant_de__niveau_de_marquage_de_l_eponge \ ); \ /* Introduit le 20240617080311 et mis ici le 20240622084330 (et non plus apres le */ \ /* 'end_albumQ(...)') afin que le niveau de marquage puisse evoluer apres le marquage */ \ /* de chaque point... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ \ EGAL(valeur_aleatoire_logique \ ,COND(IFLE(valeur_aleatoire_flottante \ ,HORNER_1_01(DIVI(FLOT(profondeur_courante),FLOT(nombre_d_iterations)) \ ,A_seuil_d_indecision_entre_FAUX_et_VRAI \ ,B_seuil_d_indecision_entre_FAUX_et_VRAI \ ) \ ) \ ,FAUX \ ,VRAI \ ) \ ); \ /* On notera le choix 'IFLE(...)' comme dans 'v $xiii/aleat.1$FON Test.IFLE.rdnI2D'... */ \ /* */ \ /* Le 20240926165103, le seuil d'indecision est devenu un polynome du premier degre */ \ /* fonction de 'profondeur_courante' renormalisee (P) : */ \ /* */ \ /* 1 0 */ \ /* seuil = A.P + B.P P E [0,1] */ \ /* */ \ /* tel que par defaut (A>=0) au debut du processus (les grands cubes), le seuil est faible */ \ /* et donc on elimine peu de cubes. Alors qu'a la fin (les petits cubes), le seuil est */ \ /* eleve et on elimine donc plus de cubes. En choisissant 'A' negatif, ce fonctionnement */ \ /* est inverse... */ \ /* */ \ /* On notera le 20240927100709 que : */ \ /* */ \ /* A=0 (valeur par defaut) */ \ /* B<0 (par exemple -0.1) */ \ /* */ \ /* provoque l'absence de toute subdivision... */ \ /* */ \ /* Le 20240927111123, en utilisant par exemple : */ \ /* */ \ /* A=-1.001 */ \ /* B=+1.000 */ \ /* */ \ /* tous les gros cubes seront conserves et les petits cubes tres subdivises. On notera */ \ /* les valeurs suivantes : */ \ /* */ \ /* pc ni P=pc/ni seuil nombre d'occurences */ \ /* */ \ /* 5 5 1.000000 -0.001000 27 */ \ /* 4 5 0.800000 +0.199200 729 */ \ /* 3 5 0.600000 +0.399400 15714 */ \ /* 2 5 0.400000 +0.599600 251046 */ \ /* 1 5 0.200000 +0.799800 2693628 */ \ /* */ \ /* 'pc' et 'ni' designant respectivement 'profondeur_courante' et 'nombre_d_iterations'. */ \ \ INCR(nombre_de_tirages_aleatoires,I); \ /* Comptage introduit le 20240619093414... */ \ \ Test(IL_FAUT(editer_les_nombres_aleatoires)) \ /* Test introduit le 20240706100146... */ \ Bblock \ CAL3(Prme3("ValeurAleatoire(%d)=%+.^^^ --> %s\n" \ ,nombre_de_tirages_aleatoires \ ,valeur_aleatoire_flottante \ ,ETAT_LOGIQUE(valeur_aleatoire_logique) \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T I O N R E C U R S I V E D E L ' E P O N G E D E M E N G E R : */ /* */ /*************************************************************************************************************************************/ #define OPTIMISER(borne_optimisee,borne_non_optimisee) \ COND(IL_FAUT(parcours_optimise_de_la_hierarchie_des_cubes),borne_optimisee,borne_non_optimisee) \ /* Introduit le 20180101085704... */ #define PREMIERE_ITERATION_ \ UN #define DERNIERE_ITERATION_ \ nombre_d_iterations #define NOMBRE_EFFECTIF_D_ITERATIONS \ MAX2(UN,NBRE(PREMIERE_ITERATION_,DERNIERE_ITERATION_)) /* Le 'MAX2(UN,...)' a ete introduit le 20191204134246 afin de permettre de faire un */ /* nombre d'iterations nul ce qui permet d'avoir les ensembles entiers (sans trous...). */ #define PREMIER_CUBE_REDUIT_X \ UN #define DERNIER_CUBE_REDUIT_X \ ASD1(rapport_d_homothetie,cx) #define PREMIER_CUBE_REDUIT_Y \ UN #define DERNIER_CUBE_REDUIT_Y \ ASD1(rapport_d_homothetie,cy) #define PREMIER_CUBE_REDUIT_Z \ UN #define DERNIER_CUBE_REDUIT_Z \ ASD1(rapport_d_homothetie,cz) #define CUBE_REDUIT_CENTRAL_X \ MOYE(PREMIER_CUBE_REDUIT_X,DERNIER_CUBE_REDUIT_X) #define CUBE_REDUIT_CENTRAL_Y \ MOYE(PREMIER_CUBE_REDUIT_Y,DERNIER_CUBE_REDUIT_Y) #define CUBE_REDUIT_CENTRAL_Z \ MOYE(PREMIER_CUBE_REDUIT_Z,DERNIER_CUBE_REDUIT_Z) #define NOMBRE_LINEAIRE_DE_CUBES_X \ NBRE(PREMIER_CUBE_REDUIT_X,DERNIER_CUBE_REDUIT_X) #define NOMBRE_LINEAIRE_DE_CUBES_Y \ NBRE(PREMIER_CUBE_REDUIT_Y,DERNIER_CUBE_REDUIT_Y) #define NOMBRE_LINEAIRE_DE_CUBES_Z \ NBRE(PREMIER_CUBE_REDUIT_Z,DERNIER_CUBE_REDUIT_Z) #define NOMBRE_VOLUMIQUE_DE_CUBES \ MUL3(NOMBRE_LINEAIRE_DE_CUBES_X,NOMBRE_LINEAIRE_DE_CUBES_Y,NOMBRE_LINEAIRE_DE_CUBES_Z) BFonctionI #define index_X_des_cubes_reduits \ X #define index_Y_des_cubes_reduits \ Y #define index_Z_des_cubes_reduits \ Z /* Index des 3x3x3=27 cubes reduits (27 par defaut) introduit le 20171215143439 sous cette */ /* forme afin d'utiliser 'begin_albumQ(...)' ci -apres... */ #define SUBDIVISER_UN_CUBE(index_X_des_cubes_reduits,index_Y_des_cubes_reduits,index_Z_des_cubes_reduits,profondeur_courante) \ IdTb4(selecteur_des_cubes_a_subdiviser \ ,INDX(profondeur_courante,PREMIERE_ITERATION_),NOMBRE_EFFECTIF_D_ITERATIONS \ ,INDX(index_X_des_cubes_reduits,PREMIER_CUBE_REDUIT_X),NOMBRE_LINEAIRE_DE_CUBES_X \ ,INDX(index_Y_des_cubes_reduits,PREMIER_CUBE_REDUIT_Y),NOMBRE_LINEAIRE_DE_CUBES_Y \ ,INDX(index_Z_des_cubes_reduits,PREMIER_CUBE_REDUIT_Z),NOMBRE_LINEAIRE_DE_CUBES_Z \ ) DEFV(Local,DEFV(Int,DdTb4(POINTERi ,selecteur_des_cubes_a_subdiviser ,NOMBRE_EFFECTIF_D_ITERATIONS ,NOMBRE_LINEAIRE_DE_CUBES_Z ,NOMBRE_LINEAIRE_DE_CUBES_Y ,NOMBRE_LINEAIRE_DE_CUBES_X ,ADRESSE_NON_ENCORE_DEFINIE ) ) ); /* On notera que 'NOMBRE_LINEAIRE_DE_CUBES' depend de 'rapport_d_homothetie' et que */ /* celui-ci peut etre redefini via 'v $xrf/EpongeDeMenger.01$K .rh...rapport_d_homothetie'. */ /* Mais cela n'est pas grave car, en effte, 'NOMBRE_LINEAIRE_DE_CUBES' n'est pas exploite */ /* par 'DdTb3(...)'. */ /* */ /* Le 20180110093215 le type de 'selecteur_des_cubes_a_subdiviser' est passe de 'Logical' */ /* a 'Int' depuis que des valeurs autres que 'FAUX' et 'VRAI' (en particulier 'INDECIS') */ /* ont ete introduites le 20180107174041... */ #define REDUCTION_D_UN_CUBE \ DEFV(pointF_3D,origine_du_cube_reduit); \ DEFV(coeffI_3D,prochain_rapport_d_homothetie_cumule); \ \ INITIALISATION_POINT_3D(origine_du_cube_reduit \ ,ADD2(ASI1(origine_du_cube,x) \ ,MUL2(SOUS(index_X_des_cubes_reduits,PREMIER_CUBE_REDUIT_X) \ ,ASD1(cote_du_cube_reduit,dx) \ ) \ ) \ ,ADD2(ASI1(origine_du_cube,y) \ ,MUL2(SOUS(index_Y_des_cubes_reduits,PREMIER_CUBE_REDUIT_Y) \ ,ASD1(cote_du_cube_reduit,dy) \ ) \ ) \ ,ADD2(ASI1(origine_du_cube,z) \ ,MUL2(SOUS(index_Z_des_cubes_reduits,PREMIER_CUBE_REDUIT_Z) \ ,ASD1(cote_du_cube_reduit,dz) \ ) \ ) \ ); \ /* Definition de l'un des vingt (par defaut) cubes reduits par homothetie de rapport 3 */ \ /* (par defaut) du cube Argument. */ \ \ INITIALISATION_COEFFICIENT_3D(prochain_rapport_d_homothetie_cumule \ ,MUL2(ASD1(rapport_d_homothetie,cx),ASI1(rapport_d_homothetie_cumule,cx)) \ ,MUL2(ASD1(rapport_d_homothetie,cy),ASI1(rapport_d_homothetie_cumule,cy)) \ ,MUL2(ASD1(rapport_d_homothetie,cz),ASI1(rapport_d_homothetie_cumule,cz)) \ ); \ /* Introduit le 20180116101706 pour la nouvelle option 'STOPPER_LA_SUBDIVISION_D_UN_CUBE'... */ \ /* */ \ /* ATTENTION, il ne faut pas de : */ \ /* */ \ /* Bblock */ \ /* (...) */ \ /* Eblock */ \ /* */ \ /* dans cette definition, etant donne qu'on y definit differentes donnees utilisees par */ \ /* la suite... */ #define GENERATION_DUN_CUBE(origine_du_cube,cote_du_cube,rapport_d_homothetie_cumule) \ Bblock \ CALS(GenerationDunCube(origine_du_cube \ ,cote_du_cube \ ,album_d_imagesR \ ,niveau_de_marquage_de_l_eponge \ ,marquer_le_bord_X_de_l_eponge \ ,marquer_le_bord_Y_de_l_eponge \ ,marquer_le_bord_Z_de_l_eponge \ ,niveau_de_marquage_du_bord_de_l_eponge \ ,rapport_d_homothetie_cumule \ ,profondeur_courante \ ) \ ); \ Eblock \ /* Introduit le 20180116101706 pour la nouvelle option 'STOPPER_LA_SUBDIVISION_D_UN_CUBE'... */ DEFV(Local,DEFV(Logical,INIT(tabuler_apres_une_C_PD,FAUX))); DEFV(Local,DEFV(Logical,INIT(eliminer_les_K_LF_redondants,VRAI))); /* L'elimination des 'K_LF's pourrait etre inhibee si besoin etait... */ DEFV(Local,DEFV(CHAR,INIT(caractere_precedent,K_LF))); #define EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(caractere) \ Bblock \ DEFV(CHAR,INIT(caractere_courant,caractere)); \ Test(IFET(IL_FAUT(eliminer_les_K_LF_redondants) \ ,IFET(IFEQ(caractere_courant,K_LF),IFEQ(caractere_precedent,K_LF)) \ ) \ ) \ Bblock \ Eblock \ ATes \ Bblock \ CAL3(Prme1("%c" \ ,caractere_courant \ ) \ ); \ Eblock \ ETes \ \ EGAL(caractere_precedent,caractere_courant); \ /* Dispositif introduit le 20240918182033 afin d'eviter des lignes vides en emettant */ \ /* plusieurs 'K_LF' a la suite... */ \ Eblock #define FACTEUR_DE_TABULATION_DES_REGLES \ DIX #define TABULATION(amplitude) \ Bblock \ CAL3(Prme2("%*s" \ ,MUL2(amplitude,FACTEUR_DE_TABULATION_DES_REGLES) \ ,C_VIDE \ ) \ ); \ Eblock #define NUMERO_D_ITERATION_COURANTE \ SOUS(nombre_d_iterations,profondeur_courante) #define NOMBRE_DE_CARACTERES_DU_NUMERO_D_ITERATION_COURANTE \ DEUX DEFV(Local,DEFV(FonctionI,GenerationDeLEpongeDeMenger(ARGUMENT_POINTERs(origine_du_cube) ,ARGUMENT_POINTERs(cote_du_cube) ,profondeur_courante ,album_d_imagesR ,niveau_de_marquage_de_l_eponge ,marquer_le_bord_X_de_l_eponge ,marquer_le_bord_Y_de_l_eponge ,marquer_le_bord_Z_de_l_eponge ,niveau_de_marquage_du_bord_de_l_eponge ,c_est_le_premier_cube_de_la_profondeur_courante ,ARGUMENT_POINTERs(rapport_d_homothetie_cumule) ) ) ) /* La mise de cette fonction dans un '$I' est due aux operateurs 'OPC1(...)' qu'elle */ /* utilise un peu plus loin... */ DEFV(Argument,DEFV(pointF_3D,POINTERs(origine_du_cube))); DEFV(Argument,DEFV(deltaF_3D,POINTERs(cote_du_cube))); /* Definition du cube Argument. */ DEFV(Argument,DEFV(Int,profondeur_courante)); /* Definition du niveau de recursivite. */ DEFV(Argument,DEFV(album,album_d_imagesR)); DEFV(Argument,DEFV(genere_p,niveau_de_marquage_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_X_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_Y_de_l_eponge)); DEFV(Argument,DEFV(Logical,marquer_le_bord_Z_de_l_eponge)); DEFV(Argument,DEFV(genere_p,niveau_de_marquage_du_bord_de_l_eponge)); /* La possibilite de marquer le bord differement a ete introduite le 20150326151832... */ DEFV(Argument,DEFV(Logical,c_est_le_premier_cube_de_la_profondeur_courante)); /* Argument introduit le 20140922164132 dans le but de faire des verifications des */ /* differents cotes des cubes au cours du processus de reduction recursive... */ DEFV(Argument,DEFV(coeffI_3D,POINTERs(rapport_d_homothetie_cumule))); /* Introduit le 20171117174022... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ TRACER(compteur_de_trace_2 ,UNDEF ,BLOC( Bblock CAL3(Prme6(" : OrigineCube={%04d,%04d,%04d} ExtremiteCube={%04d,%04d,%04d}\n" ,Cube_cDENORMALISE_OX(NEUT(ASI1(origine_du_cube,x))) ,Cube_cDENORMALISE_OY(NEUT(ASI1(origine_du_cube,y))) ,Cube_cDENORMALISE_OZ(NEUT(ASI1(origine_du_cube,z))) ,Cube_cDENORMALISE_OX(ADD2(ASI1(origine_du_cube,x),ASI1(cote_du_cube,dx))) ,Cube_cDENORMALISE_OY(ADD2(ASI1(origine_du_cube,y),ASI1(cote_du_cube,dy))) ,Cube_cDENORMALISE_OZ(ADD2(ASI1(origine_du_cube,z),ASI1(cote_du_cube,dz))) ) ); Eblock ) ); Test(EST_VRAI(c_est_le_premier_cube_de_la_profondeur_courante)) Bblock /* Rien a faire a la date du 20140922165323 et d'ailleurs que faire pour bien verifier */ /* la divisibilite par 3 des trois cotes de base denormalises des cubes (qui ne sont pas */ /* necessairement egaux, puisque les trois dimensions en {X,Y,Z} ne sont pas forcement */ /* egales...) ? En attendant, le 20140923161553, j'introduis les editions suivantes... */ Test(IL_FAUT(editer_la_hierarchie_des_cubes)) /* Test introduit le 20140923161553... */ Bblock CAL3(Prme1("Cube(%d)=",NUMERO_D_ITERATION_COURANTE)); CAL3(Prme2("%0*d",TRPU(NOMBRE_DE_CHIFFRES_DECIMAUX(dimX)),DIMENSION(XCubeMinimum,XCubeMaximum))); CALS(FPrme0("x")); CAL3(Prme2("%0*d",TRPU(NOMBRE_DE_CHIFFRES_DECIMAUX(dimY)),DIMENSION(YCubeMinimum,YCubeMaximum))); CALS(FPrme0("x")); CAL3(Prme2("%0*d",TRPU(NOMBRE_DE_CHIFFRES_DECIMAUX(dimZ)),DIMENSION(ZCubeMinimum,ZCubeMaximum))); CALS(FPrme0(" : ")); CAL3(Prme1("%d",ASD1(rapport_d_homothetie,cx))); CALS(FPrme0("x")); CAL3(Prme1("%d",ASD1(rapport_d_homothetie,cy))); CALS(FPrme0("x")); CAL3(Prme1("%d",ASD1(rapport_d_homothetie,cz))); CALS(FPrme0("-Divisibilite=")); CAL3(Prme1("%d",REST(DIMENSION(XCubeMinimum,XCubeMaximum),ASD1(rapport_d_homothetie,cx)))); CALS(FPrme0("x")); CAL3(Prme1("%d",REST(DIMENSION(YCubeMinimum,YCubeMaximum),ASD1(rapport_d_homothetie,cy)))); CALS(FPrme0("x")); CAL3(Prme1("%d",REST(DIMENSION(ZCubeMinimum,ZCubeMaximum),ASD1(rapport_d_homothetie,cz)))); CALS(Fsauts_de_lignes(UN)); /* On notera les 'TRPU(...)'s au cas ou une ou plusieurs dimensions du cube seraient un */ /* peu superieures a celles des axes 'OX', 'OY' et 'OZ' ('v $xiirf/.SIER.51.1.$U')... */ /* */ /* Le 20140924111212, je note que ces editions peuvent faciliter le choix des */ /* dimensions des axes 'OX', 'OY' et 'OZ' dans le but d'obtenir des cubes qui aient */ /* tous des cotes multiples de 3. Ainsi, par exemple, soit : */ /* */ /* nombre_d_iterations=4 (valeur par defaut) ---------------------------- */ /* | */ /* Si l'on veut que le plus petit cube ait les cotes 9x9x9, il suffit de fixer : | */ /* X Y Z | */ /* | | | | */ /* XYmaxNe 0 727 0 727 | | | | */ /* Zmin=0 Zmax=727 | | | | */ /* | | | | */ /* car, en effet : ------------------------------ | */ /* | | */ /* | | */ /* \|/ | */ /* . 4 <---------------------------------------------------------- */ /* 727 = 9x3 - 2 */ /* | */ /* | */ /* ---------> Rapport d'homothetie... */ /* */ /* On obtient alors les sorties suivantes : */ /* */ /* Cube(0)=0729x0729x0729 : 3-Divisibilite=0x0x0 */ /* Cube(1)=0243x0243x0243 : 3-Divisibilite=0x0x0 */ /* Cube(2)=0081x0081x0081 : 3-Divisibilite=0x0x0 */ /* Cube(3)=0027x0027x0027 : 3-Divisibilite=0x0x0 */ /* Cube(4)=0009x0009x0009 : 3-Divisibilite=0x0x0 */ /* */ /* Le 20171215114928 je rappelle que '3' est la valeur par defaut de 'rapport_d_homothetie'. */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Test(IZGT(profondeur_courante)) Bblock /* Cas ou il faut iterer la subdivision : */ DEFV(Logical,INIT(c_est_le_premier_cube_a_editer_1,VRAI)); DEFV(Logical,INIT(c_est_le_premier_cube_a_editer_2,LUNDEF)); /* Il va s'agir du premier cube de la subdivision courante... */ DEFV(Int,INIT(nouvelle_profondeur,PRED(profondeur_courante))); DEFV(deltaF_3D,cote_du_cube_reduit); INITIALISATION_ACCROISSEMENT_3D(cote_du_cube_reduit ,DIVI(ASI1(cote_du_cube,dx),ASD1(rapport_d_homothetie,cx)) ,DIVI(ASI1(cote_du_cube,dy),ASD1(rapport_d_homothetie,cy)) ,DIVI(ASI1(cote_du_cube,dz),ASD1(rapport_d_homothetie,cz)) ); /* Par definition de l'eponge de Menger, on divise par 3 (par defaut)... */ begin_hyper_albumQ(DoDe ,OPTIMISER(profondeur_courante,PREMIERE_ITERATION_) ,OPTIMISER(profondeur_courante,DERNIERE_ITERATION_) ,I ,DoIn,PREMIER_CUBE_REDUIT_Z,DERNIER_CUBE_REDUIT_Z,I ,DoIn,PREMIER_CUBE_REDUIT_Y,DERNIER_CUBE_REDUIT_Y,I ,DoIn,PREMIER_CUBE_REDUIT_X,DERNIER_CUBE_REDUIT_X,I ) /* Introduit le 20171215143439 sous cette forme... */ /* */ /* ATTENTION : jusqu'au 20171231142417 il y avait par erreur ci-dessus : */ /* */ /* begin_hyper_albumQ(DoDe,PREMIERE_ITERATION_,DERNIERE_ITERATION_,I */ /* */ /* ce qui avait pour effet d'allonger considerablement les calculs (l'arborescence etant */ /* reexploree en totalite a chaque niveau), mais en donnant evidemment des resultats */ /* corrects... */ Bblock DEFV(Logical,INIT(subdiviser_le_cube ,SUBDIVISER_UN_CUBE(index_X_des_cubes_reduits ,index_Y_des_cubes_reduits ,index_Z_des_cubes_reduits ,profondeur_courante ) ) ); Test(EST_INDECIS(subdiviser_le_cube)) Bblock FIN_DE_L_INDECISION(subdiviser_le_cube); /* Dans le cas d'une indecision, on fait un tirage aleatoire (introduit le 20180107183041). */ Eblock ATes Bblock Eblock ETes Test(IL_FAUT(editer_les_choix_de_subdivision_suppression)) /* Test introduit le 20240917115816 afin de le rendre l'edition des choix possible... */ Bblock INCR(compteur_de_trace_3,I); Test(IL_FAUT(editer_les_choix_de_subdivision_suppression__version_simplifiee)) /* Test introduit le 20240918170544... */ Bblock EGAL(c_est_le_premier_cube_a_editer_2,c_est_le_premier_cube_a_editer_1); Test(EST_VRAI(c_est_le_premier_cube_a_editer_1)) Bblock EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_LF); Test(IL_FAUT(editer_les_choix_de_subdivision_suppression__version_simplifiee_avec_parenthesage)) /* Test introduit le 20240921103547... */ Bblock TABULATION(NUMERO_D_ITERATION_COURANTE); EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_PG); CAL3(Prme2("[%0*d]" ,NOMBRE_DE_CARACTERES_DU_NUMERO_D_ITERATION_COURANTE ,NUMERO_D_ITERATION_COURANTE ) ); /* On notera le "%02d" qui permet de maintenir les tabulations quels que soient le numero */ /* d'iteration (inferieur a 100...). */ EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_LF); TABULATION(NUMERO_D_ITERATION_COURANTE); Eblock ATes Bblock Eblock ETes EGAL(c_est_le_premier_cube_a_editer_1,FAUX); Eblock ATes Bblock Eblock ETes Test(IL_FAUT(editer_les_choix_de_subdivision_suppression__version_simplifiee_avec_parenthesage)) /* Test introduit le 20240921103547... */ Bblock Test(IL_FAUT(tabuler_apres_une_C_PD)) Bblock EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_LF); TABULATION(SUCC(NUMERO_D_ITERATION_COURANTE)); EGAL(tabuler_apres_une_C_PD,FAUX); Eblock ATes Bblock Eblock ETes TABULATION(COND(EST_VRAI(c_est_le_premier_cube_a_editer_2),UN,ZERO)); Eblock ATes Bblock Eblock ETes EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(COND(EST_FAUX(subdiviser_le_cube) ,K_0 ,COND(EST_VRAI(subdiviser_le_cube) ,K_1 ,K_UNDEF ) ) ); /* Le 20240918102326, pour information, je note les sorties suivantes (en rappelant les */ /* convention de codage 'FAUX=0' et 'VRAI=1') : */ /* */ /* Eponge de Menger, iteration 1 : */ /* */ /* 111 101 111 101 000 101 111 101 111 */ /* */ /* */ /* Eponge de Menger, iteration 2 : */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 0 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 0 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* 0 */ /* 0 */ /* 0 */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 0 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 0 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* 1 111 101 111 101 000 101 111 101 111 */ /* */ /* */ /* Eponge de Menger, iteration 3 : */ /* */ /* $xrf/EpongeDeMenger.01.z 3 */ /* */ /* */ /* Eponge de Menger, iteration 4 : */ /* */ /* $xrf/EpongeDeMenger.01.z 4 */ /* */ /* */ /* etc... */ /* */ Eblock ATes Bblock CAL3(Prme2("Subdivision(%d)=%s\n",compteur_de_trace_3,ETAT_LOGIQUE(subdiviser_le_cube))); Eblock ETes Eblock ATes Bblock Eblock ETes Test(IL_FAUT(subdiviser_le_cube)) /* Test introduit le 20171215152010... */ Bblock REDUCTION_D_UN_CUBE; /* Introduit le 20180116113103 sous cette forme... */ CALS(GenerationDeLEpongeDeMenger(ADRESSE(origine_du_cube_reduit) ,ADRESSE(cote_du_cube_reduit) ,nouvelle_profondeur ,album_d_imagesR ,niveau_de_marquage_de_l_eponge ,marquer_le_bord_X_de_l_eponge ,marquer_le_bord_Y_de_l_eponge ,marquer_le_bord_Z_de_l_eponge ,niveau_de_marquage_du_bord_de_l_eponge ,IFET(EST_VRAI(c_est_le_premier_cube_de_la_profondeur_courante) ,I3ET(IFEQ(index_X_des_cubes_reduits,PREMIER_CUBE_REDUIT_X) ,IFEQ(index_Y_des_cubes_reduits,PREMIER_CUBE_REDUIT_Y) ,IFEQ(index_Z_des_cubes_reduits,PREMIER_CUBE_REDUIT_Z) ) ) ,ADRESSE(prochain_rapport_d_homothetie_cumule) ) ); /* Les cubes reduits non centraux sont traites recursivement... */ Eblock ATes Bblock Test(IFEQ(subdiviser_le_cube,STOPPER_LA_SUBDIVISION_D_UN_CUBE)) /* Test introduit le 20180116101706... */ Bblock REDUCTION_D_UN_CUBE; GENERATION_DUN_CUBE(ADRESSE(origine_du_cube_reduit) ,ADRESSE(cote_du_cube_reduit) ,ADRESSE(prochain_rapport_d_homothetie_cumule) ); /* Generation d'un cube "non terminal" (introduit le 20180116101706...). */ Eblock ATes Bblock Eblock ETes Eblock ETes Eblock end_hyper_albumQ(EDoD,EDoI,EDoI,EDoI) Test(IL_FAUT(editer_les_choix_de_subdivision_suppression)) /* Test introduit le 20240918172007... */ Bblock Test(IL_FAUT(editer_les_choix_de_subdivision_suppression__version_simplifiee)) /* Test introduit le 20240918172007... */ Bblock Test(IL_FAUT(editer_les_choix_de_subdivision_suppression__version_simplifiee_avec_parenthesage)) /* Test introduit le 20240921103547... */ Bblock EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_LF); TABULATION(NUMERO_D_ITERATION_COURANTE); EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_PD); EGAL(tabuler_apres_une_C_PD,VRAI); Eblock ATes Bblock Eblock ETes EMETTRE_UN_CARACTERE_EN_SUPPRIMANT_LES_K_LF_REDONDANTS(K_LF); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock ATes Bblock /* Cas ou la subdivision est terminee, il faut marquer les points des cubes de ce niveau... */ GENERATION_DUN_CUBE(origine_du_cube,cote_du_cube,rapport_d_homothetie_cumule); /* Generation du cube courant... */ Eblock ETes RETU_ERROR; Eblock EFonctionI #undef REDUCTION_D_UN_CUBE #undef GENERATION_DUN_CUBE #undef index_X_des_cubes_reduits #undef index_Y_des_cubes_reduits #undef index_Z_des_cubes_reduits #undef ZCubeMaximum #undef ZCubeMinimum #undef YCubeMaximum #undef YCubeMinimum #undef XCubeMaximum #undef XCubeMinimum