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