/*************************************************************************************************************************************/ /* */ /* S U B D I V I S I O N R E C U R S I V E E T A L E A T O I R E D ' U N T R I A N G L E D ' O R : */ /* */ /* */ /* Author of '$xci/valeurs_TriangleOr$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 20120505110802). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 : */ /* */ /*************************************************************************************************************************************/ @define PRAGMA_CB_____OPTIONS__SYSTEME_APC_LinuxRedHat_GCC "-Wno-implicit-function-declaration" @define PRAGMA_CB_____OPTIONS__SYSTEME_APC_LinuxUlmint_GCC "-Wno-implicit-function-declaration" @define PRAGMA_CB_____OPTIONS__SYSTEME_APC_LinuxUbuntu_GCC "-Wno-implicit-function-declaration" /* Introduit le 20170127085833 pour la fonction 'GenerationDunTriangleMince(...)'. */ /* */ /* Pour la meme raison, 'SYSTEME_APC_LinuxUbuntu_GCC' fut introduit le 20210907104530... */ /* */ /* Pour la meme raison, 'SYSTEME_APC_LinuxRedHat_GCC' fut introduit le 20220511172854... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F I C H I E R S D ' I N C L U D E S : */ /* */ /*************************************************************************************************************************************/ #include INCLUDES_BASE /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A R A M E T R E S : */ /* */ /*************************************************************************************************************************************/ #define PARTIR_D_UN_TRIANGLE_QUELCONQUE \ FAUX #define PARTIR_D_UN_TRIANGLE_PLAT_ \ VRAI /* Choix du triangle de depart... */ #define TAILLE_DES_TRIANGLES \ FU \ /* Taille des deux cotes egaux des triangles isoceles "plat" et "mince"... */ #define TRIANGLE_PLAT__SOMMET_B_X \ FXmin #define TRIANGLE_PLAT__SOMMET_B_Y \ FYmin /* Point 'B' d'un triangle "plat". */ #define TRIANGLE_PLAT__SOMMET_A_X \ ADD2(TRIANGLE_PLAT__SOMMET_B_X,MOIT(NOMBRE_D_OR)) #define TRIANGLE_PLAT__SOMMET_A_Y \ ADD2(TRIANGLE_PLAT__SOMMET_B_Y,RACX(SOUS(TAILLE_DES_TRIANGLES,EXP2(MOIT(NOMBRE_D_OR))))) /* Point 'A' d'un triangle "plat". On notera que : */ /* ___________ */ /* \ / 2 */ /* pi \/ 1 - mPhi */ /* tan(----) = ----------------- */ /* 5 mPhi */ /* */ /* avec : */ /* */ /* Phi */ /* mPhi = ----- */ /* 2 */ /* */ /* Je remplace donc : */ /* */ /* MUL2(MOIT(NOMBRE_D_OR),TANX(GRO1(FRA5(PI)))) */ /* */ /* par l'expression plus simple et plus logique : */ /* */ /* RACX(SOUS(TAILLE_DES_TRIANGLES,EXP2(MOIT(NOMBRE_D_OR)))) */ /* */ /* qui traduit donc le theoreme de Pythagore dans le triangle rectangle BHA. */ #define TRIANGLE_PLAT__SOMMET_C_X \ ADD2(TRIANGLE_PLAT__SOMMET_B_X,NOMBRE_D_OR) #define TRIANGLE_PLAT__SOMMET_C_Y \ TRIANGLE_PLAT__SOMMET_B_Y /* Point 'C' d'un triangle "plat". */ #define TRIANGLE_MINCE_SOMMET_B_X \ TRIANGLE_PLAT__SOMMET_B_X #define TRIANGLE_MINCE_SOMMET_B_Y \ TRIANGLE_PLAT__SOMMET_B_Y /* Point 'B' d'un triangle "mince". */ #define TRIANGLE_MINCE_SOMMET_A_X \ ADD2(TRIANGLE_MINCE_SOMMET_B_X,MOIT(INVERSE_DU_NOMBRE_D_OR)) #define TRIANGLE_MINCE_SOMMET_A_Y \ ADD2(TRIANGLE_MINCE_SOMMET_B_Y,RACX(SOUS(TAILLE_DES_TRIANGLES,EXP2(MOIT(INVERSE_DU_NOMBRE_D_OR))))) /* Point 'A' d'un triangle "mince". On notera que : */ /* ____________ */ /* \ / 2 */ /* pi \/ 1 - umPhi */ /* tan(----) = ------------------ */ /* 5 umPhi */ /* */ /* avec : */ /* */ /* 1 1 */ /* umPhi = ---.----- */ /* 2 Phi */ /* */ /* Je remplace donc : */ /* */ /* MUL2(MOIT(INVERSE_DU_NOMBRE_D_OR),TANX(GRO2(FRA5(PI)))) */ /* */ /* par l'expression plus simple et plus logique : */ /* */ /* RACX(SOUS(TAILLE_DES_TRIANGLES,EXP2(MOIT(INVERSE_DU_NOMBRE_D_OR)))) */ /* */ /* qui traduit donc le theoreme de Pythagore dans le triangle rectangle BHA. */ #define TRIANGLE_MINCE_SOMMET_C_X \ ADD2(TRIANGLE_MINCE_SOMMET_B_X,INVERSE_DU_NOMBRE_D_OR) #define TRIANGLE_MINCE_SOMMET_C_Y \ TRIANGLE_MINCE_SOMMET_B_Y /* Point 'C' d'un triangle "mince". */ /* On notera que l'on ne met pas ici : */ /* */ /* #include xci/valeurs.01.I" */ /* */ /* parce que l'on ne peut inclure '$xci/valeurs.02$I' ci-apres... */ #define CENTRER_LA_STRUCTURE \ VRAI \ /* Faut-il centrer la structure ('VRAI') ou pas ('FAUX') ? */ #define FAIRE_DE_PLUS_LE_TRIANGLE_SYMETRIQUE_LORSQUE_LA_STRUCTURE_N_EST_PAS_CENTREE \ FAUX \ /* Lorsque la structure n'est pas centree, faut-il de plus faire le triangle symetrique */ \ /* par rapport a sa base (('VRAI') ou pas ('FAUX') ? Ceci fut introduit le 20120510111448. */ #define EDITER_LES_REGLES_UTILISEES \ FAUX \ /* Faut-il editer les regles utilisees ('VRAI') ou pas ('FAUX') ? */ #define EDITER_LES_COORDONNEES_DES_POINTS \ VRAI #define EDITER_LES_POINTS_SOUS_LA_FORME_DE_SEGMENTS \ VRAI #define EDITER_LES_POINTS_A_TOUS_LES_NIVEAUX \ FAUX /* Controle de l'edition des points : editer ('VRAI') ou pas ('FAUX'), editer sous forme */ /* de segments (('VRAI') ou de points "isoles" ('FAUX'), editera tous les niveaux de */ /* recursvite ('VRAI') ou uniquement au le niveau le plus bas ('FAUX') ? */ #define ETIQUETTE_DES_TRIANGLES_PLATS_ \ "P" #define ETIQUETTE_DES_TRIANGLES_MINCES \ "M" /* Etiquettes a utiliser pour distinguer les deux types de triangle lors de l'edition des */ /* points sous forme de segments (introduit le 20120510080356). Ceci permet de faciliter */ /* l'utilisation de 'v $xrv/permute.11$K' par exemple... */ #define INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_1 \ UN #define INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_2 \ ZERO #define INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_3 \ UN /* Increments des etiquettes destinees a distinguer les trois cotes d'un meme triangle */ /* (ceci fut introduit le 20120514095338). Les valeurs par defaut font que les cotes '1' */ /* et '3' (les deux cotes egaux) auront a priori tous une etiquette differente et ne */ /* pourront donc pas etre apparies, alors que les cotes '2' (les bases) auront a priori */ /* la meme etiquette et pourront donc etre apparies... */ #define PROFONDEUR \ QUATRE \ /* Profondeur de la generation... */ #define GENERATION_PSEUDO_PERIODIQUE \ FAUX #define SYMETRISER \ VRAI #define NE_PAS_SYMETRISER \ NOTL(SYMETRISER) #define SYMETRISER_INITIALEMENT_DANS_LE_CAS_DE_LA_GENERATION_PSEUDO_PERIODIQUE \ NE_PAS_SYMETRISER /* La generation sera-t-elle pseudo-periodique ('VRAI') ou pas ('FAUX') c'est-a-dire alors */ /* conditionnee par des choix definis par les parametres suivants (cette possibilite fut */ /* introduite le 20120508100131 ? */ #define UTILISER_LA_GENERATION_ALEATOIRE_POUR_LES_TRIANGLES_PLATS_ \ VRAI #define FORCER_LA_PREMIERE_BRANCHE_POUR_LES_TRIANGLES_PLATS_ \ VRAI /* Conditionnement de la generation des triangles "plat"s... */ #define UTILISER_LA_GENERATION_ALEATOIRE_POUR_LES_TRIANGLES_MINCES \ VRAI #define FORCER_LA_PREMIERE_BRANCHE_POUR_LES_TRIANGLES_MINCES \ VRAI /* Conditionnement de la generation des triangles "mince"s... */ #define GRAINE_DU_GENERATEUR_ALEATOIRE \ PARE(1789) #define BORNE_INFERIEURE_DU_GENERATEUR_ALEATOIRE \ COORDONNEE_BARYCENTRIQUE_MINIMALE #define BORNE_SUPERIEURE_DU_GENERATEUR_ALEATOIRE \ COORDONNEE_BARYCENTRIQUE_MAXIMALE #define SEUIL_DU_GENERATEUR_ALEATOIRE \ COORDONNEE_BARYCENTRIQUE_CENTRALE /* Parametrage du generateur de nombres aleatoires. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ /* On notera que l'on ne peut pas mettre ici : */ /* */ /* #include xci/valeurs.02.I" */ /* */ /* a cause du message : */ /* */ /* error: initializer element is not constant */ /* */ /* provoque par la fonction 'Finitialisation_d_une_constante_chaine_de_caracteres(...)'. */ #define EDITION_D_UNE_REGLE(regle) \ Bblock \ Test(IL_FAUT(editer_les_regles_utilisees)) \ Bblock \ CAL2(Prin1("%s",regle)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Edition d'une regle... */ #define EDITION_DES_COORDONNEES_DES_POINTS(editer,format_coordonnees_normalisees,X,Y) \ Bblock \ Test(IL_FAUT(editer_les_coordonnees_des_points)) \ Bblock \ Test(IL_FAUT(editer)) \ Bblock \ CAL2(Prin2(format_coordonnees_normalisees \ ,X \ ,Y \ ) \ ); \ /* On notera que l'on ne peut utiliser 'NOMBRE_DE_DECIMALES_EFFECTIF(...)' ou encore */ \ /* 'valeurs_signees' et 'format_d_edition' tels qu'il sont definis d'une part dans */ \ /* 'v $xci/valeurs.02$I' et d'autre part dans '$xci/valeurs.03$I' pour des problemes */ \ /* de references en avant... */ \ CAL2(Prin0("\n")); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Edition des coordonnees des segments. */ #define TEST_D_UNDERFLOW_D_UNE_COORDONNEE(coordonnee) \ TROP_PETIT(coordonnee,gEPSILON) \ /* Ceci a ete introduit le 20120508141518 lors de la mise au point de 'v $xiirv/TROR.32' */ \ /* pour laquelle on trouvait des lignes de coordonnees de segments telles : */ \ /* */ \ /* xC=-3.05e-16 yC=-0.0572 xB=+0.191 yB=-0.196 P */ \ /* */ \ /* et : */ \ /* */ \ /* xC=+1.11e-16 yC=-0.0572 xB=+0.191 yB=-0.196 P */ \ /* */ \ /* (avec "ChiffresFlot=3") qui correspondent au meme point theoriquement, mais pas en */ \ /* pratique ! */ DEFV(Local,DEFV(Logical,INIT(c_est_la_subdivision_directe,VRAI))); /* Introduit le 20120510162802, mais sans utilite a cette date... */ #define EDITION_DES_COORDONNEES_DES_SEGMENTS(editer,format_coordonnees_normalisees,X1,Y1,X2,Y2,etiquette_triangle,etiquette_cote) \ /* L'argument 'etiquette_triangle' a ete introdouit le 20120508124402 afin de pouvoir faire */ \ /* la difference entre les segments qui appartiennent a un triangle "Mince" et ceux qui */ \ /* appartiennent a un triangle "Plat" ('v $xiirv/.TROR.11.$U _____Simplifier')... */ \ /* */ \ /* L'argument 'etiquette_cote' a ete introdouit le 20120510143232 pour la meme raison et */ \ /* de facon a faire que l'on associe, lors de simplifications, que des cotes de meme nature */ \ /* d=(de meme numero...). */ \ Bblock \ Test(IL_FAUT(editer_les_coordonnees_des_points)) \ Bblock \ Test(IL_FAUT(editer)) \ Bblock \ DEFV(Float,INIT(X1_effectif,X1)); \ DEFV(Float,INIT(Y1_effectif,Y1)); \ DEFV(Float,INIT(X2_effectif,X2)); \ DEFV(Float,INIT(Y2_effectif,Y2)); \ \ Test(IFLT(X1,X2)) \ Bblock \ /* Dans le cas ou X1<X2, l'ordre {1,2} est conserve... */ \ Eblock \ ATes \ Bblock \ Test(IFGT(X1,X2)) \ Bblock \ EGAL(X1_effectif,X2); \ EGAL(Y1_effectif,Y2); \ EGAL(X2_effectif,X1); \ EGAL(Y2_effectif,Y1); \ /* Dans le cas ou X1>X2, l'ordre {1,2} est inverse... */ \ Eblock \ ATes \ Bblock \ Test(IFLT(Y1,Y2)) \ Bblock \ /* Dans le cas ou X1=X2 et Y1<Y2, l'ordre {1,2} est conserve... */ \ Eblock \ ATes \ Bblock \ Test(IFGT(Y1,Y2)) \ Bblock \ EGAL(X1_effectif,X2); \ EGAL(Y1_effectif,Y2); \ EGAL(X2_effectif,X1); \ EGAL(Y2_effectif,Y1); \ /* Dans le cas ou X1=X2 et Y1>Y2, l'ordre {1,2} est inverse... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ETes \ \ CAL2(Prin4(format_coordonnees_normalisees \ ,TEST_D_UNDERFLOW_D_UNE_COORDONNEE(X1_effectif) \ ,TEST_D_UNDERFLOW_D_UNE_COORDONNEE(Y1_effectif) \ ,TEST_D_UNDERFLOW_D_UNE_COORDONNEE(X2_effectif) \ ,TEST_D_UNDERFLOW_D_UNE_COORDONNEE(Y2_effectif) \ ) \ ); \ /* On notera que l'on ne peut utiliser 'NOMBRE_DE_DECIMALES_EFFECTIF(...)' ou encore */ \ /* 'valeurs_signees' et 'format_d_edition' tels qu'il sont definis d'une part dans */ \ /* 'v $xci/valeurs.02$I' et d'autre part dans '$xci/valeurs.03$I' pour des problemes */ \ /* de references en avant... */ \ CAL2(Prin1(" %s",etiquette_triangle)); \ CAL2(Prin1(" %d",etiquette_cote)); \ /* Edition de l'etiquette... */ \ CAL2(Prin0("\n")); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Edition des coordonnees des segments. */ DEFV(Local,DEFV(Int,INIT(increment_de_l_etiquette_des_cotes_des_triangles_1,INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_1))); DEFV(Local,DEFV(Int,INIT(increment_de_l_etiquette_des_cotes_des_triangles_2,INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_2))); DEFV(Local,DEFV(Int,INIT(increment_de_l_etiquette_des_cotes_des_triangles_3,INCREMENT_DE_L_ETIQUETTE_DES_COTES_DES_TRIANGLES_3))); /* Increments des etiquettes destinees a distinguer les trois cotes d'un meme triangle */ /* (ceci fut introduit le 20120514095338). Les valeurs par defaut font que les cotes '1' */ /* et '3' (les deux cotes egaux) auront a priori tous une etiquette differente et ne */ /* pourront donc pas etre apparies, alors que les cotes '2' (les bases) auront a priori */ /* la meme etiquette et pourront donc etre apparies... */ #define REGLE_EDITION_DES_COORDONNEES(pointB,pointA,pointC,etiquette_triangle) \ Bblock \ Test(IFOU(IL_FAUT(editer_les_points_a_tous_les_niveaux) \ ,IFET(IL_NE_FAUT_PAS(editer_les_points_a_tous_les_niveaux) \ ,IFEQ(profondeur,UN) \ ) \ ) \ ) \ Bblock \ Test(IL_FAUT(editer_les_points_sous_la_forme_de_segments)) \ Bblock \ Test(I3OU(IFEQ(etiquette_des_cotes_des_triangles_1,etiquette_des_cotes_des_triangles_2) \ ,IFEQ(etiquette_des_cotes_des_triangles_1,etiquette_des_cotes_des_triangles_3) \ ,IFEQ(etiquette_des_cotes_des_triangles_2,etiquette_des_cotes_des_triangles_3) \ ) \ ) \ Bblock \ PRINT_ERREUR("les etiquettes des cotes sont entrees en collision"); \ CAL1(Prer3("(etiquette1=%d etiquette2(bas)=%d etiquette3=%d)\n" \ ,etiquette_des_cotes_des_triangles_1 \ ,etiquette_des_cotes_des_triangles_2 \ ,etiquette_des_cotes_des_triangles_3 \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EDITION_DES_COORDONNEES_DES_SEGMENTS(VRAI \ ,"xB=%+.^^^ yB=%+.^^^ xA=%+.^^^ yA=%+.^^^" \ ,ASD1(pointB,x),ASD1(pointB,y) \ ,ASD1(pointA,x),ASD1(pointA,y) \ ,etiquette_triangle \ ,etiquette_des_cotes_des_triangles_1 \ ); \ INCR(etiquette_des_cotes_des_triangles_1,increment_de_l_etiquette_des_cotes_des_triangles_1); \ /* Les cotes differents des bases (cotes 'AB' et 'AC') doivent tous avoir des etiquettes */ \ /* differentes afin de ne pas etre apparies... */ \ \ EDITION_DES_COORDONNEES_DES_SEGMENTS(VRAI \ ,"xC=%+.^^^ yC=%+.^^^ xB=%+.^^^ yB=%+.^^^" \ ,ASD1(pointC,x),ASD1(pointC,y) \ ,ASD1(pointB,x),ASD1(pointB,y) \ ,etiquette_triangle \ ,etiquette_des_cotes_des_triangles_2 \ ); \ INCR(etiquette_des_cotes_des_triangles_2,increment_de_l_etiquette_des_cotes_des_triangles_2); \ /* Les bases (cotes 'BC') ne changent pas d'etiquettes afin de pouvoir etre appariees... */ \ \ EDITION_DES_COORDONNEES_DES_SEGMENTS(VRAI \ ,"xA=%+.^^^ yA=%+.^^^ xC=%+.^^^ yC=%+.^^^" \ ,ASD1(pointA,x),ASD1(pointA,y) \ ,ASD1(pointC,x),ASD1(pointC,y) \ ,etiquette_triangle \ ,etiquette_des_cotes_des_triangles_3 \ ); \ INCR(etiquette_des_cotes_des_triangles_3,increment_de_l_etiquette_des_cotes_des_triangles_3); \ /* Les cotes differents des bases (cotes 'AB' et 'AC') doivent tous avoir des etiquettes */ \ /* differentes afin de ne pas etre apparies... */ \ Eblock \ ATes \ Bblock \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xB=%+.^^^ yB=%+.^^^",ASD1(pointB,x),ASD1(pointB,y)); \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xA=%+.^^^ yA=%+.^^^",ASD1(pointA,x),ASD1(pointA,y)); \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xA=%+.^^^ yA=%+.^^^",ASD1(pointA,x),ASD1(pointA,y)); \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xC=%+.^^^ yC=%+.^^^",ASD1(pointC,x),ASD1(pointC,y)); \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xC=%+.^^^ yC=%+.^^^",ASD1(pointC,x),ASD1(pointC,y)); \ EDITION_DES_COORDONNEES_DES_POINTS(VRAI,"xB=%+.^^^ yB=%+.^^^",ASD1(pointB,x),ASD1(pointB,y)); \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock #define REGLE_TRIANGLE_PLAT_(pointB,pointA,pointC,symetriser) \ Bblock \ EDITION_D_UNE_REGLE(ETIQUETTE_DES_TRIANGLES_PLATS_); \ \ REGLE_EDITION_DES_COORDONNEES(pointB,pointA,pointC,etiquette_des_triangles_plats_); \ \ CALS(GenerationDunTrianglePlat_(PRED(profondeur),ADRESSE(pointB),ADRESSE(pointA),ADRESSE(pointC),symetriser)); \ Eblock \ /* Regle "P" ("generation d'un triangle Plat"). */ #define REGLE_TRIANGLE_MINCE(pointB,pointA,pointC,symetriser) \ Bblock \ EDITION_D_UNE_REGLE(ETIQUETTE_DES_TRIANGLES_MINCES); \ \ REGLE_EDITION_DES_COORDONNEES(pointB,pointA,pointC,etiquette_des_triangles_minces); \ \ CALS(GenerationDunTriangleMince(PRED(profondeur),ADRESSE(pointB),ADRESSE(pointA),ADRESSE(pointC),symetriser)); \ Eblock \ /* Regle "M" ("generation d'un triangle Mince"). */ #define SUBDIVISION_INITIALE_DU_TRIANGLE \ Bblock \ Test(IL_FAUT(partir_d_un_triangle_quelconque)) \ Bblock \ GENERATION_DE_LA_VALEUR_ALEATOIRE_COURANTE(valeur_aleatoire_courante); \ \ Test(IFLE(valeur_aleatoire_courante,seuil_du_generateur_aleatoire)) \ Bblock \ REGLE_TRIANGLE_PLAT_(pointB,pointA,pointC \ ,symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique \ ); \ /* Generation recursive du decoupage aleatoire et auto-similaire du triangle BAC plat */ \ /* centre qui fut choisi aleatoirement, mais il faut alors s'attendre a des resultats */ \ /* "folkroriques"... */ \ Eblock \ ATes \ Bblock \ REGLE_TRIANGLE_MINCE(pointB,pointA,pointC \ ,symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique \ ); \ /* Generation recursive du decoupage aleatoire et auto-similaire du triangle BAC mince */ \ /* centre qui fut choisi aleatoirement, mais il faut alors s'attendre a des resultats */ \ /* "folkroriques"... */ \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Test(IL_FAUT(partir_d_un_triangle_plat_)) \ Bblock \ REGLE_TRIANGLE_PLAT_(pointB,pointA,pointC \ ,symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique \ ); \ /* Generation recursive du decoupage aleatoire et auto-similaire du triangle BAC plat */ \ /* centre. */ \ Eblock \ ATes \ Bblock \ REGLE_TRIANGLE_MINCE(pointB,pointA,pointC \ ,symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique \ ); \ /* Generation recursive du decoupage aleatoire et auto-similaire du triangle BAC mince */ \ /* centre. */ \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* Subdivision initiale du triangle (introduite le 20120510111448). */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T E U R A L E A T O I R E : */ /* */ /*************************************************************************************************************************************/ DEFV(Local,DEFV(Int,INIT(graine_du_generateur_aleatoire,GRAINE_DU_GENERATEUR_ALEATOIRE))); DEFV(Local,DEFV(Float,INIT(borne_inferieure_du_generateur_aleatoire,BORNE_INFERIEURE_DU_GENERATEUR_ALEATOIRE))); DEFV(Local,DEFV(Float,INIT(borne_superieure_du_generateur_aleatoire,BORNE_SUPERIEURE_DU_GENERATEUR_ALEATOIRE))); DEFV(Local,DEFV(Float,INIT(seuil_du_generateur_aleatoire,SEUIL_DU_GENERATEUR_ALEATOIRE))); DEFV(Local,DEFV(pointI_2D,point_courant_de_l_espace_de_parametrage)); DEFV(Local,DEFV(Float,INIT(valeur_aleatoire_courante,FLOT__UNDEF))); /* Parametrage du generateur de nombres aleatoires. */ SPIRALE_DEFINITION_GENERALE(SPIRALE_DELTA_HORIZONTAL_GLOBAL,SPIRALE_DELTA_VERTICAL_GLOBAL); #define GENERATION_DE_LA_VALEUR_ALEATOIRE_COURANTE(valeur_aleatoire) \ Bblock \ EGAL(valeur_aleatoire \ ,rdnI2D(ADRESSE(point_courant_de_l_espace_de_parametrage) \ ,graine_du_generateur_aleatoire \ ,RDN_INIT_AND_GENERE \ ,borne_inferieure_du_generateur_aleatoire,borne_superieure_du_generateur_aleatoire \ ) \ ); \ /* Generation d'une valeur aleatoire dans [borne_inferieure,borne_superieure]... */ \ \ SPIRALE_INITIALISATION; \ SPIRALE_DEPLACEMENT(ASD1(point_courant_de_l_espace_de_parametrage,x) \ ,ASD1(point_courant_de_l_espace_de_parametrage,y) \ ); \ SPIRALE_PARCOURS; \ /* Parcours de la spirale avec rotation eventuelle de PI/2 du bras courant... */ \ Eblock /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N S R E C U R S I V E S D E S U B D I V I S I O N A L E A T O I R E */ /* D ' U N T R I A N G L E D ' O R : */ /* */ /*************************************************************************************************************************************/ /* On notera que l'on ne met pas ici : */ /* */ /* #include xci/valeurs.03.I" */ /* */ /* parce que l'on ne peut inclure '$xci/valeurs.02$I' ci-avant... */ #define DEFINITION_DES_TRIANGLES_B1A1C1_ET_B2A2C2 \ DEFV(complexe,zAB); \ DEFV(complexe,zBC); \ DEFV(complexe,zCA); \ DEFV(pointF_2D,pointA2); \ DEFV(pointF_2D,pointB2); \ DEFV(pointF_2D,pointC2); \ DEFV(Float,INIT(longueur_du_cote_AB,FLOT__UNDEF)); \ DEFV(Float,INIT(longueur_du_cote_BC,FLOT__UNDEF)); \ DEFV(Float,INIT(longueur_du_cote_CA,FLOT__UNDEF)); \ DEFV(Float,INIT(inclinaison_du_cote_AB,FLOT__UNDEF)); \ DEFV(Float,INIT(inclinaison_du_cote_BC,FLOT__UNDEF)); \ DEFV(Float,INIT(inclinaison_du_cote_CA,FLOT__UNDEF)); #define CALCUL_DES_TRIANGLES_B1A1C1_ET_B2A2C2 \ Bblock \ Cinitialisation(zAB \ ,SOUS(ASI1(pointB1,x),ASI1(pointA1,x)) \ ,SOUS(ASI1(pointB1,y),ASI1(pointA1,y)) \ ); \ Cinitialisation(zBC \ ,SOUS(ASI1(pointC1,x),ASI1(pointB1,x)) \ ,SOUS(ASI1(pointC1,y),ASI1(pointB1,y)) \ ); \ Cinitialisation(zCA \ ,SOUS(ASI1(pointA1,x),ASI1(pointC1,x)) \ ,SOUS(ASI1(pointA1,y),ASI1(pointC1,y)) \ ); \ \ EGAL(longueur_du_cote_AB,Cmodule(zAB)); \ EGAL(longueur_du_cote_BC,Cmodule(zBC)); \ EGAL(longueur_du_cote_CA,Cmodule(zCA)); \ \ EGAL(inclinaison_du_cote_AB,Cargument_2PI(zAB)); \ EGAL(inclinaison_du_cote_BC,Cargument_2PI(zBC)); \ EGAL(inclinaison_du_cote_CA,Cargument_2PI(zCA)); \ \ gTRANSFERT_POINT_2D(pointA2,pointA1,ASD1,ASI1); \ gTRANSFERT_POINT_2D(pointB2,pointB1,ASD1,ASI1); \ gTRANSFERT_POINT_2D(pointC2,pointC1,ASD1,ASI1); \ Eblock DEFV(Local,DEFV(Logical,INIT(editer_les_regles_utilisees,EDITER_LES_REGLES_UTILISEES))); /* Faut-il editer les regles utilisees ('VRAI') ou pas ('FAUX') ? */ DEFV(Local,DEFV(Logical,INIT(editer_les_coordonnees_des_points,EDITER_LES_COORDONNEES_DES_POINTS))); DEFV(Local,DEFV(Logical,INIT(editer_les_points_sous_la_forme_de_segments,EDITER_LES_POINTS_SOUS_LA_FORME_DE_SEGMENTS))); DEFV(Local,DEFV(Logical,INIT(editer_les_points_a_tous_les_niveaux,EDITER_LES_POINTS_A_TOUS_LES_NIVEAUX))); /* Controle de l'edition des points : editer ('VRAI') ou pas ('FAUX'), editer sous forme */ /* de segments (('VRAI') ou de points "isoles" ('FAUX'), editera tous les niveaux de */ /* recursvite ('VRAI') ou uniquement au le niveau le plus bas ('FAUX') ? */ DEFV(Local,DEFV(CHAR,INIT(POINTERc(etiquette_des_triangles_minces),CHAINE_UNDEF))); DEFV(Local,DEFV(CHAR,INIT(POINTERc(etiquette_des_triangles_plats_),CHAINE_UNDEF))); /* Etiquettes a utiliser pour distinguer les deux types de triangle lors de l'edition des */ /* points sous forme de segments (introduit le 20120510080356). Ceci permet de faciliter */ /* l'utilisation de 'v $xrv/permute.11$K' par exemple... */ /* */ /* On notera que l'on ne peut ecrire : */ /* */ /* DEFV(Local,DEFV(CHAR,INIC(POINTERc(etiquette_des_triangles_minces */ /* ,ETIQUETTE_DES_TRIANGLES_MINCES */ /* ) */ /* ) */ /* ) */ /* ); */ /* */ /* (par exemple) a cause du message : */ /* */ /* error: initializer element is not constant */ /* */ /* a cause de la fonction 'Finitialisation_d_une_constante_chaine_de_caracteres(...)' */ /* utilisee par 'INIC(...)'. */ DEFV(Local,DEFV(Int,INIT(etiquette_des_cotes_des_triangles_1,MILLION))); DEFV(Local,DEFV(Int,INIT(etiquette_des_cotes_des_triangles_2,UN))); DEFV(Local,DEFV(Int,INIT(etiquette_des_cotes_des_triangles_3,MILLIARD))); /* Etiquettes a utiliser pour distinguer les cotes des triangles lors de l'edition des */ /* points sous forme de segments (introduit le 20120510143232). Les valeurs ci-dessus */ /* sont choisies de facon que : */ /* */ /* etiquette2 < etiquette1 << etiquette3 */ /* */ /* et donc ainsi eviter les collsions avec les 'INCR(...)'s relatifs aux etiquettes 1 et 3. */ DEFV(Local,DEFV(Logical,INIT(generation_pseudo_periodique,GENERATION_PSEUDO_PERIODIQUE))); DEFV(Local,DEFV(Logical,INIT(symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique ,SYMETRISER_INITIALEMENT_DANS_LE_CAS_DE_LA_GENERATION_PSEUDO_PERIODIQUE ) ) ); /* La generation sera-t-elle pseudo-periodique ('VRAI') ou pas ('FAUX') c'est-a-dire alors */ /* conditionnee par des choix definis par les parametres suivants (cette possibilite fut */ /* introduite le 20120508100131 ? */ DEFV(Local,DEFV(Logical,INIT(utiliser_la_generation_aleatoire_pour_les_triangles_plats_ ,UTILISER_LA_GENERATION_ALEATOIRE_POUR_LES_TRIANGLES_PLATS_ ) ) ); DEFV(Local,DEFV(Logical,INIT(forcer_la_premiere_branche_pour_les_triangles_plats_ ,FORCER_LA_PREMIERE_BRANCHE_POUR_LES_TRIANGLES_PLATS_ ) ) ); /* Conditionnement de la generation des triangles "plat"s... */ BFonctionIB DEFV(LoF,DEFV(FonctionIB,GenerationDunTrianglePlat_(profondeur,pointB1,pointA1,pointC1,symetriser))) /* Le type 'FonctionIB' est mis par "symetrie" avec 'GenerationDunTriangleMince(...)'. */ DEFV(Argument,DEFV(Int,profondeur)); /* Profondeur de la generation courante... */ DEFV(Argument,DEFV(pointF_2D,POINTERs(pointB1))); DEFV(Argument,DEFV(pointF_2D,POINTERs(pointA1))); DEFV(Argument,DEFV(pointF_2D,POINTERs(pointC1))); /* Definition du triangle BAC de depart. ATTENTION : 'A' designe le sommet, alors que */ /* 'B' et 'C' designent les deux autres angles (egaux...). */ DEFV(Argument,DEFV(Logical,symetriser)); /* Parametre destine a provoquer eventuellement une symetrie du triangle par rapport a son */ /* axe (vertical) de symetrie n'etant utile que si 'IL_FAUT(generation_pseudo_periodique)'. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ Test(IZGT(profondeur)) Bblock DEFINITION_DES_TRIANGLES_B1A1C1_ET_B2A2C2; /* Definition des notations relatives a un triangle "plat" BAC : */ /* */ /* */ /* A */ /* */ /* * */ /* * | * */ /* * | * */ /* * . | . * */ /* * | * */ /* F * | * E */ /* * + . | . + * */ /* * + | + * */ /* * + | + * */ /* * + | + * */ /* * + | + * */ /* * + * */ /* * . + | + . * */ /* * + | + * */ /* *-------------------------------------------------------* */ /* H */ /* B D G C */ /* */ /* */ /* Phi = le Nombre d'Or */ /* */ /* AB = AC = 1 */ /* */ /* BC = Phi */ /* */ /* / \ pi */ /* ABC = ---- */ /* 5 */ /* */ /* BC */ /* BD = ---------------- = GC = CE = FB */ /* / \ 2 */ /* (2.cos(ABC)) */ /* */ /* */ /* Liste des triangles "plat"s = {BAC,DEC,BFG,BDA,CGA} */ /* Liste des triangles "mince"s = {ADE,AGF} */ /* */ DEFV(pointF_2D,pointD2); DEFV(pointF_2D,pointE2); DEFV(pointF_2D,pointF2); DEFV(pointF_2D,pointG2); DEFV(Float,INIT(longueur_du_cote_BD,FLOT__UNDEF)); DEFV(Float,INIT(longueur_du_cote_CE,FLOT__UNDEF)); DEFV(Float,INIT(longueur_du_cote_FB,FLOT__UNDEF)); DEFV(Float,INIT(longueur_du_cote_GC,FLOT__UNDEF)); CALCUL_DES_TRIANGLES_B1A1C1_ET_B2A2C2; EGAL(longueur_du_cote_BD,DIVI(longueur_du_cote_BC,EXP2(DOUB(COSX(SOUS(inclinaison_du_cote_BC,inclinaison_du_cote_AB)))))); EGAL(longueur_du_cote_CE,longueur_du_cote_BD); EGAL(longueur_du_cote_FB,longueur_du_cote_CE); EGAL(longueur_du_cote_GC,longueur_du_cote_BD); /* On notera que l'on definit ici des grandeurs qui ne sont pas toutes utiles, mais c'est */ /* tout simplement par symetrie (et puis, on ne sait jamais...). */ gINITIALISATION_POINT_2D(pointD2 ,BARY(ASI1(pointB1,x),ASI1(pointC1,x),DIVI(longueur_du_cote_BD,longueur_du_cote_BC)) ,BARY(ASI1(pointB1,y),ASI1(pointC1,y),DIVI(longueur_du_cote_BD,longueur_du_cote_BC)) ,ASD1 ); gINITIALISATION_POINT_2D(pointG2 ,BARY(ASI1(pointC1,x),ASI1(pointB1,x),DIVI(longueur_du_cote_GC,longueur_du_cote_BC)) ,BARY(ASI1(pointC1,y),ASI1(pointB1,y),DIVI(longueur_du_cote_GC,longueur_du_cote_BC)) ,ASD1 ); gINITIALISATION_POINT_2D(pointE2 ,BARY(ASI1(pointC1,x),ASI1(pointA1,x),DIVI(longueur_du_cote_CE,longueur_du_cote_CA)) ,BARY(ASI1(pointC1,y),ASI1(pointA1,y),DIVI(longueur_du_cote_CE,longueur_du_cote_CA)) ,ASD1 ); gINITIALISATION_POINT_2D(pointF2 ,BARY(ASI1(pointB1,x),ASI1(pointA1,x),DIVI(longueur_du_cote_FB,longueur_du_cote_AB)) ,BARY(ASI1(pointB1,y),ASI1(pointA1,y),DIVI(longueur_du_cote_FB,longueur_du_cote_AB)) ,ASD1 ); Test(IL_FAUT(generation_pseudo_periodique)) /* Test introduit le 20120508103552... */ Bblock Test(IL_FAUT(symetriser)) /* ATTENTION : on notera que le forcage des bornes inferieure et superieure est fait a */ /* l'inverse de ce qui est fait dans 'GenerationDunTriangleMince(...)' et ce afin de */ /* garantir la compatibilite anterieure a 20120508103552... */ Bblock EGAL(valeur_aleatoire_courante,borne_inferieure_du_generateur_aleatoire); Eblock ATes Bblock EGAL(valeur_aleatoire_courante,borne_superieure_du_generateur_aleatoire); Eblock ETes Eblock ATes Bblock Test(IL_FAUT(utiliser_la_generation_aleatoire_pour_les_triangles_plats_)) Bblock GENERATION_DE_LA_VALEUR_ALEATOIRE_COURANTE(valeur_aleatoire_courante); Eblock ATes Bblock Test(IL_FAUT(forcer_la_premiere_branche_pour_les_triangles_plats_)) Bblock EGAL(valeur_aleatoire_courante,borne_inferieure_du_generateur_aleatoire); Eblock ATes Bblock EGAL(valeur_aleatoire_courante,borne_superieure_du_generateur_aleatoire); Eblock ETes Eblock ETes Eblock ETes Test(IFLE(valeur_aleatoire_courante,seuil_du_generateur_aleatoire)) Bblock /* Definition des reecritures du triangle "plat" BAC (symetriser=VRAI) : */ /* */ /* */ /* A */ /* */ /* * */ /* * * */ /* * * */ /* * . * */ /* * * */ /* * * E */ /* * . FAUX + * */ /* * + * */ /* * + * */ /* * . + * */ /* * + * */ /* * + * */ /* * . + * */ /* * VRAI + FAUX * */ /* *-------------------------------------------------------* */ /* */ /* B D C */ /* */ /* */ REGLE_TRIANGLE_PLAT_(pointA2,pointD2,pointB2,SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {A2,D2,B2} AVEC symetrie eventuelle (=VRAI) */ /* */ REGLE_TRIANGLE_MINCE(pointE2,pointD2,pointA2,NE_PAS_SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {E2,D2,A2} SANS symetrie eventuelle (=FAUX) */ /* */ REGLE_TRIANGLE_PLAT_(pointD2,pointE2,pointC2,NE_PAS_SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {D2,E2,C2} SANS symetrie eventuelle (=FAUX) */ /* */ Eblock ATes Bblock /* Definition des reecritures du triangle "plat" BAC (symetriser=FAUX) : */ /* */ /* */ /* A */ /* */ /* * */ /* * * */ /* * * */ /* * . * */ /* * * */ /* F * VRAI * */ /* * + . * */ /* * + * */ /* * + * */ /* * + . * */ /* * + * */ /* * + * */ /* * + . * */ /* * VRAI + FAUX * */ /* *-------------------------------------------------------* */ /* */ /* B G C */ /* */ /* */ REGLE_TRIANGLE_PLAT_(pointC2,pointG2,pointA2,NE_PAS_SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {C2,G2,A2} SANS symetrie eventuelle (=FAUX) */ /* */ REGLE_TRIANGLE_MINCE(pointA2,pointG2,pointF2,SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {A2,G2,F2} AVEC symetrie eventuelle (=VRAI) */ /* */ REGLE_TRIANGLE_PLAT_(pointB2,pointF2,pointG2,SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {B2,F2,G2} AVEC symetrie eventuelle (=VRAI) */ /* */ Eblock ETes Eblock ATes Bblock Eblock ETes RETU_ERROR; Eblock EFonctionIB DEFV(Local,DEFV(Logical,INIT(utiliser_la_generation_aleatoire_pour_les_triangles_minces ,UTILISER_LA_GENERATION_ALEATOIRE_POUR_LES_TRIANGLES_MINCES ) ) ); DEFV(Local,DEFV(Logical,INIT(forcer_la_premiere_branche_pour_les_triangles_minces ,FORCER_LA_PREMIERE_BRANCHE_POUR_LES_TRIANGLES_MINCES ) ) ); /* Conditionnement de la generation des triangles "mince"s... */ BFonctionIB DEFV(LoF,DEFV(FonctionIB,GenerationDunTriangleMince(profondeur,pointB1,pointA1,pointC1,symetriser))) /* Le type 'FonctionIB' est rendu necessaire par les references en avant dont elle est */ /* l'objet dans 'GenerationDunTrianglePlat(...)'... */ DEFV(Argument,DEFV(Int,profondeur)); /* Profondeur de la generation courante... */ DEFV(Argument,DEFV(pointF_2D,POINTERs(pointB1))); DEFV(Argument,DEFV(pointF_2D,POINTERs(pointA1))); DEFV(Argument,DEFV(pointF_2D,POINTERs(pointC1))); /* Definition du triangle BAC de depart. ATTENTION : 'A' designe le sommet, alors que */ /* 'B' et 'C' designent les deux autres angles (egaux...). */ DEFV(Argument,DEFV(Logical,symetriser)); /* Parametre destine a provoquer eventuellement une symetrie du triangle par rapport a son */ /* axe (vertical) de symetrie n'etant utile que si 'IL_FAUT(generation_pseudo_periodique)'. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ Test(IZGT(profondeur)) Bblock DEFINITION_DES_TRIANGLES_B1A1C1_ET_B2A2C2; /* Definition des notations relatives a un triangle "mince" BAC : */ /* */ /* */ /* A */ /* */ /* * */ /* | */ /* | */ /* *|* */ /* | */ /* | */ /* * | * */ /* | */ /* | */ /* * | * */ /* | */ /* | */ /* * | * */ /* | */ /* | */ /* * | * */ /* | */ /* | */ /* * | * */ /* | */ /* | */ /* D * | * E */ /* . | . */ /* . | . */ /* * .|. * */ /* . . */ /* . | . */ /* * . | . * */ /* . | . */ /* . | . */ /* *-------------------* */ /* H */ /* B C */ /* */ /* */ /* Phi = le Nombre d'Or */ /* */ /* AB = AC = 1 */ /* */ /* 1 */ /* BC = ----- */ /* Phi */ /* */ /* / \ 2.pi */ /* ABC = ------ */ /* 5 */ /* */ /* / \ */ /* DB = 2.BC.cos(ABC) = CE */ /* */ /* */ /* Liste des triangles "plat"s = {ADC,AEB} */ /* Liste des triangles "mince"s = {BAC,BCD,CBE} */ /* */ DEFV(pointF_2D,pointD2); DEFV(pointF_2D,pointE2); DEFV(Float,INIT(longueur_du_cote_DB,FLOT__UNDEF)); DEFV(Float,INIT(longueur_du_cote_CE,FLOT__UNDEF)); CALCUL_DES_TRIANGLES_B1A1C1_ET_B2A2C2; EGAL(longueur_du_cote_DB,MUL2(longueur_du_cote_BC,DOUB(FfABSO(COSX(SOUS(inclinaison_du_cote_BC,inclinaison_du_cote_AB)))))); EGAL(longueur_du_cote_CE,longueur_du_cote_DB); /* On notera que l'on definit ici des grandeurs qui ne sont pas toutes utiles, mais c'est */ /* tout simplement par symetrie (et puis, on ne sait jamais...). */ gINITIALISATION_POINT_2D(pointD2 ,BARY(ASI1(pointB1,x),ASI1(pointA1,x),DIVI(longueur_du_cote_DB,longueur_du_cote_AB)) ,BARY(ASI1(pointB1,y),ASI1(pointA1,y),DIVI(longueur_du_cote_DB,longueur_du_cote_AB)) ,ASD1 ); gINITIALISATION_POINT_2D(pointE2 ,BARY(ASI1(pointC1,x),ASI1(pointA1,x),DIVI(longueur_du_cote_CE,longueur_du_cote_CA)) ,BARY(ASI1(pointC1,y),ASI1(pointA1,y),DIVI(longueur_du_cote_CE,longueur_du_cote_CA)) ,ASD1 ); Test(IL_FAUT(generation_pseudo_periodique)) /* Test introduit le 20120508103552... */ Bblock Test(IL_FAUT(symetriser)) /* ATTENTION : on notera que le forcage des bornes inferieure et superieure est fait a */ /* l'inverse de ce qui est fait dans 'GenerationDunTrianglePlat_(...)' et ce afin de */ /* garantir la compatibilite anterieure a 20120508103552... */ Bblock EGAL(valeur_aleatoire_courante,borne_superieure_du_generateur_aleatoire); Eblock ATes Bblock EGAL(valeur_aleatoire_courante,borne_inferieure_du_generateur_aleatoire); Eblock ETes Eblock ATes Bblock Test(IL_FAUT(utiliser_la_generation_aleatoire_pour_les_triangles_minces)) Bblock GENERATION_DE_LA_VALEUR_ALEATOIRE_COURANTE(valeur_aleatoire_courante); Eblock ATes Bblock Test(IL_FAUT(forcer_la_premiere_branche_pour_les_triangles_minces)) Bblock EGAL(valeur_aleatoire_courante,borne_inferieure_du_generateur_aleatoire); Eblock ATes Bblock EGAL(valeur_aleatoire_courante,borne_superieure_du_generateur_aleatoire); Eblock ETes Eblock ETes Eblock ETes Test(IFLE(valeur_aleatoire_courante,seuil_du_generateur_aleatoire)) Bblock /* Definition des reecritures du triangle "mince" BAC (symetriser=FAUX) : */ /* */ /* */ /* A */ /* */ /* * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* D * * */ /* . */ /* . */ /* * . * */ /* FAUX . */ /* .FAUX */ /* * . * */ /* . */ /* . */ /* *-------------------* */ /* */ /* B C */ /* */ /* */ REGLE_TRIANGLE_PLAT_(pointC2,pointD2,pointA2,NE_PAS_SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {C2,D2,A2} SANS symetrie eventuelle (=FAUX) */ /* */ REGLE_TRIANGLE_MINCE(pointD2,pointC2,pointB2,NE_PAS_SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {D2,C2,B2} SANS symetrie eventuelle (=FAUX) */ /* */ Eblock ATes Bblock /* Definition des reecritures du triangle "mince" BAC (symetriser=VRAI) : */ /* */ /* */ /* A */ /* */ /* * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * */ /* */ /* */ /* * * E */ /* . */ /* . */ /* * . * */ /* . VRAI */ /* VRAI. */ /* * . * */ /* . */ /* . */ /* *-------------------* */ /* */ /* B C */ /* */ /* */ REGLE_TRIANGLE_PLAT_(pointA2,pointE2,pointB2,SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {A2,E2,B2} AVEC symetrie eventuelle (=VRAI) */ /* */ REGLE_TRIANGLE_MINCE(pointC2,pointB2,pointE2,SYMETRISER); /* Reecriture : */ /* */ /* {B1,A1,C1} --> {C2,B2,E2} AVEC symetrie eventuelle (=VRAI) */ /* */ Eblock ETes Eblock ATes Bblock Eblock ETes RETU_ERROR; Eblock EFonctionIB /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* S U B D I V I S I O N R E C U R S I V E E T A L E A T O I R E D ' U N T R I A N G L E D ' O R : */ /* */ /*************************************************************************************************************************************/ BCommande(nombre_d_arguments,arguments) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(partir_d_un_triangle_quelconque,PARTIR_D_UN_TRIANGLE_QUELCONQUE)); DEFV(Logical,INIT(partir_d_un_triangle_plat_,PARTIR_D_UN_TRIANGLE_PLAT_)); /* Choix du triangle de depart... */ DEFV(Logical,INIT(centrer_la_structure,CENTRER_LA_STRUCTURE)); /* Faut-il centrer la structure ('VRAI') ou pas ('FAUX') ? */ DEFV(Logical,INIT(faire_de_plus_le_triangle_symetrique_lorsque_la_structure_n_est_pas_centree ,FAIRE_DE_PLUS_LE_TRIANGLE_SYMETRIQUE_LORSQUE_LA_STRUCTURE_N_EST_PAS_CENTREE ) ); /* Lorsque la structure n'est pas centree, faut-il de plus faire le triangle symetrique */ /* par rapport a sa base (('VRAI') ou pas ('FAUX') ? Ceci fut introduit le 20120510111448. */ DEFV(Int,INIT(profondeur,PROFONDEUR)); /* Profondeur de la generation... */ DEFV(pointF_2D,pointA); DEFV(pointF_2D,pointB); DEFV(pointF_2D,pointC); /* Definition du triangle BAC de depart. */ /*..............................................................................................................................*/ INITIALISATION_POINT_2D(pointB,TRIANGLE_PLAT__SOMMET_B_X,TRIANGLE_PLAT__SOMMET_B_Y); INITIALISATION_POINT_2D(pointA,TRIANGLE_PLAT__SOMMET_A_X,TRIANGLE_PLAT__SOMMET_A_Y); INITIALISATION_POINT_2D(pointC,TRIANGLE_PLAT__SOMMET_C_X,TRIANGLE_PLAT__SOMMET_C_Y); /* Initialisation du triangle BAC de depart sur un triangle "plat" par defaut... */ EGAL(etiquette_des_triangles_minces,chain_Acopie(ETIQUETTE_DES_TRIANGLES_MINCES)); EGAL(etiquette_des_triangles_plats_,chain_Acopie(ETIQUETTE_DES_TRIANGLES_PLATS_)); /* Initialisation des etiquettes a utiliser pour distinguer les deux types de triangle lors */ /* de l'edition des points sous forme de segments (introduit le 20120510080356). */ GET_ARGUMENTSi(nombre_d_arguments ,BLOC(GET_ARGUMENT_L("triangle_quelconque=""quelconque=""tq=",partir_d_un_triangle_quelconque); GET_ARGUMENT_L("triangle_plat=""plat=""tp=",partir_d_un_triangle_plat_); GET_ARGUMENT_N("triangle_mince=""mince=""tm=",partir_d_un_triangle_plat_); GET_ARGUMENT_L("centrer_structure=""centrer=",centrer_la_structure); GET_ARGUMENT_L("triangle_symetrique=""ts=" ,faire_de_plus_le_triangle_symetrique_lorsque_la_structure_n_est_pas_centree ); /* Arguments introduits le 20120508100131... */ GET_ARGUMENT_L("editer_regles=""regles=",editer_les_regles_utilisees); GET_ARGUMENT_L("editer_coordonnees=""coordonnees=",editer_les_coordonnees_des_points); GET_ARGUMENT_L("editer_segments=""segments=",editer_les_points_sous_la_forme_de_segments); GET_ARGUMENT_N("editer_points=""points=",editer_les_points_sous_la_forme_de_segments); GET_ARGUMENT_L("editer_tous_niveaux=""tous_niveaux=""etn=",editer_les_points_a_tous_les_niveaux); GET_ARGUMENT_N("editer_un_niveau=""un_niveau=""un=",editer_les_points_a_tous_les_niveaux); GET_ARGUMENT_C("etiquette_triangles_plats=""etp=",etiquette_des_triangles_plats_); GET_ARGUMENT_C("etiquette_triangles_minces=""etm=",etiquette_des_triangles_minces); /* Arguments introduits le 20120510080356... */ GET_ARGUMENT_I("increment_etiquette_cotes_1=""iec1=",increment_de_l_etiquette_des_cotes_des_triangles_1); GET_ARGUMENT_I("increment_etiquette_cotes_2=""iec2=",increment_de_l_etiquette_des_cotes_des_triangles_2); GET_ARGUMENT_I("increment_etiquette_cotes_3=""iec3=",increment_de_l_etiquette_des_cotes_des_triangles_3); /* Arguments introduits le 20120514095338... */ GET_ARGUMENT_I("profondeur=""recursivite=",profondeur); GET_ARGUMENT_I("methode=",gen_ft_____methode_standard); GET_ARGUMENT_I("graine=",graine_du_generateur_aleatoire); /* ATTENTION : je note le 20170603093541 que la 'graine_du_generateur_aleatoire' n'est */ /* utilisee que si 'IL_NE_FAUT_PAS(generation_pseudo_periodique)'... */ GET_ARGUMENT_L("affiner_rdn=",rdnIFnD_____affiner_la_generation); GET_ARGUMENT_L("iterer_rdn=",rdnIFnD_____iterer_la_generation); GET_ARGUMENT_F("borne_inferieure=""inf=",borne_inferieure_du_generateur_aleatoire); GET_ARGUMENT_F("borne_superieure=""sup=",borne_superieure_du_generateur_aleatoire); GET_ARGUMENT_F("seuil=",seuil_du_generateur_aleatoire); GET_ARGUMENT_L("pseudo_periodique=""pp=",generation_pseudo_periodique); GET_ARGUMENT_L("symetriser_initialement_pseudo_periodique=""sipp=" ,symetriser_initialement_dans_le_cas_de_la_generation_pseudo_periodique ); /* Arguments introduits le 20120508100131... */ /* */ /* On notera le 20170604103954 que cette symetrie n'est pas tres interessante car, en effet, */ /* les deux possibilites 'VRAI/FAUX' donnent le meme pavage a une symetrie (d'axe OY par */ /* defaut) pres... */ GET_ARGUMENT_L("generation_aleatoire_triangles_plats=""gatp=" ,utiliser_la_generation_aleatoire_pour_les_triangles_plats_ ); GET_ARGUMENT_L("premiere_branche_triangles_plats=""pbtp=" ,forcer_la_premiere_branche_pour_les_triangles_plats_ ); GET_ARGUMENT_N("deuxieme_branche_triangles_plats=""dbtp=" ,forcer_la_premiere_branche_pour_les_triangles_plats_ ); GET_ARGUMENT_L("generation_aleatoire_triangles_minces=""gatm=" ,utiliser_la_generation_aleatoire_pour_les_triangles_minces ); GET_ARGUMENT_L("premiere_branche_triangles_minces=""pbtm=" ,forcer_la_premiere_branche_pour_les_triangles_minces ); GET_ARGUMENT_N("deuxieme_branche_triangles_minces=""dbtm=" ,forcer_la_premiere_branche_pour_les_triangles_minces ); GET_ARGUMENT_F("XB=""xB=",ASD1(pointB,x)); GET_ARGUMENT_F("YB=""yB=",ASD1(pointB,y)); GET_ARGUMENT_F("XA=""xA=",ASD1(pointA,x)); GET_ARGUMENT_F("YA=""yA=",ASD1(pointA,y)); GET_ARGUMENT_F("XC=""xC=",ASD1(pointC,x)); GET_ARGUMENT_F("YC=""yC=",ASD1(pointC,y)); ) ); Test(IFET(IL_FAUT(generation_pseudo_periodique),IFNE(graine_du_generateur_aleatoire,GRAINE_DU_GENERATEUR_ALEATOIRE))) Bblock PRINT_ATTENTION("en mode 'pseudo-periodique' le generateur aleatoire n'est pas utilise"); /* Avertissement introduit le 20170604095546... */ Eblock ATes Bblock Eblock ETes Test(IFET(IL_FAUT(editer_les_regles_utilisees),IL_FAUT(editer_les_coordonnees_des_points))) Bblock PRINT_ATTENTION("il n'est pas conseille d'editer simultanement les regles et les coordonnees des points"); Eblock ATes Bblock Eblock ETes Test(IFET(IL_FAUT(faire_de_plus_le_triangle_symetrique_lorsque_la_structure_n_est_pas_centree) ,IL_FAUT(centrer_la_structure) ) ) Bblock PRINT_ATTENTION("la construction supplementaire du triangle symetrique n'est possible que s'il n'y a pas centrage"); Eblock ATes Bblock Eblock ETes Test(IL_FAUT(partir_d_un_triangle_quelconque)) Bblock Eblock ATes Bblock Test(IL_FAUT(partir_d_un_triangle_plat_)) Bblock INITIALISATION_POINT_2D(pointB,TRIANGLE_PLAT__SOMMET_B_X,TRIANGLE_PLAT__SOMMET_B_Y); INITIALISATION_POINT_2D(pointA,TRIANGLE_PLAT__SOMMET_A_X,TRIANGLE_PLAT__SOMMET_A_Y); INITIALISATION_POINT_2D(pointC,TRIANGLE_PLAT__SOMMET_C_X,TRIANGLE_PLAT__SOMMET_C_Y); /* Initialisation du triangle BAC de depart sur un triangle "plat" (deja fait avant le */ /* 'GET_ARGUMENTSi(...)', mais malgre tout les coordonnees des sommets ont pu y etre */ /* changees...). */ Eblock ATes Bblock INITIALISATION_POINT_2D(pointB,TRIANGLE_MINCE_SOMMET_B_X,TRIANGLE_MINCE_SOMMET_B_Y); INITIALISATION_POINT_2D(pointA,TRIANGLE_MINCE_SOMMET_A_X,TRIANGLE_MINCE_SOMMET_A_Y); INITIALISATION_POINT_2D(pointC,TRIANGLE_MINCE_SOMMET_C_X,TRIANGLE_MINCE_SOMMET_C_Y); /* Initialisation du triangle BAC de depart sur un triangle "mince". */ Eblock ETes Eblock ETes SPIRALE_DEFINITION_GENERALE(SPIRALE_DELTA_HORIZONTAL_GLOBAL,SPIRALE_DELTA_VERTICAL_GLOBAL) SPIRALE_VALIDATION; INITIALISATION_POINT_2D(point_courant_de_l_espace_de_parametrage,Xmin,Ymin); /* Initialisation du generateur aleatoire... */ Test(IL_FAUT(centrer_la_structure)) Bblock DEFV(pointF_2D,pointB_centre); DEFV(pointF_2D,pointA_centre); DEFV(pointF_2D,pointC_centre); /* Definition du triangle BAC centre. */ DEFV(pointF_2D,barycentre_de_ABC); INITIALISATION_POINT_2D(barycentre_de_ABC ,MOY3(ASD1(pointB,x),ASD1(pointA,x),ASD1(pointC,x)) ,MOY3(ASD1(pointB,y),ASD1(pointA,y),ASD1(pointC,y)) ); /* Definition du barycentre du triangle BAC. */ INITIALISATION_POINT_2D(pointB_centre ,SOUS(ASD1(pointB,x),ASD1(barycentre_de_ABC,x)) ,SOUS(ASD1(pointB,y),ASD1(barycentre_de_ABC,y)) ); INITIALISATION_POINT_2D(pointA_centre ,SOUS(ASD1(pointA,x),ASD1(barycentre_de_ABC,x)) ,SOUS(ASD1(pointA,y),ASD1(barycentre_de_ABC,y)) ); INITIALISATION_POINT_2D(pointC_centre ,SOUS(ASD1(pointC,x),ASD1(barycentre_de_ABC,x)) ,SOUS(ASD1(pointC,y),ASD1(barycentre_de_ABC,y)) ); /* Centrage du triangle BAC... */ TRANSFERT_POINT_2D(pointB,pointB_centre); TRANSFERT_POINT_2D(pointA,pointA_centre); TRANSFERT_POINT_2D(pointC,pointC_centre); Eblock ATes Bblock Eblock ETes SUBDIVISION_INITIALE_DU_TRIANGLE; /* Subdivision du triangle BAC. */ Test(IFET(IL_FAUT(faire_de_plus_le_triangle_symetrique_lorsque_la_structure_n_est_pas_centree) ,IL_NE_FAUT_PAS(centrer_la_structure) ) ) Bblock EGAL(ASD1(pointA,y),NEGA(ASD1(pointA,y))); /* Le sommet 'A' du triangle BAC non centre est symetrise par rapport a la base 'BC'... */ EGAL(c_est_la_subdivision_directe,NOTL(c_est_la_subdivision_directe)); SUBDIVISION_INITIALE_DU_TRIANGLE; /* Et subdivision du triangle BAC symetrise (introduite le 20120510111448). */ Eblock ATes Bblock Eblock ETes EDITION_D_UNE_REGLE("\n"); RETU_Commande; Eblock ECommande