/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D ' U N E C O U R B E F R A C T A L E Q U A D R I D I M E N S I O N N E L L E */
/* D A N S L E C O R P S D E S Q U A T E R N I O N S : */
/* */
/* */
/* Author of '$xrc/Cfract_4D.11$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1996??????????). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 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_CL_____MODULE_NON_OPTIMISABLE
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_BASE
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D E B A S E E T U N I V E R S E L L E S : */
/* */
/*************************************************************************************************************************************/
#include xrk/attractor.11.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 3 */
/* D E F I N I T I O N D E L ' E S P A C E P H Y S I Q U E D A N S R ( D E B U T ) : */
/* */
/* */
/* Nota : */
/* */
/* Les extrema des coordonnees {x,y,z} */
/* ainsi que ceux de leurs differentielles */
/* {dx,dy,dz} sont fixees un peu arbitrairement */
/* et sans etre parametrees. */
/* */
/* */
/*************************************************************************************************************************************/
#define hXmin_ESPACE \
PARE(-1.0)
#define hYmin_ESPACE \
PARE(-1.0)
#define hZmin_ESPACE \
PARE(-1.0)
/* Definition du "coin" inferieur-gauche-arriere de l'espace physique. */
#define hXmax_ESPACE \
PARE(1.0)
#define hYmax_ESPACE \
PARE(1.0)
#define hZmax_ESPACE \
PARE(1.0)
/* Definition du "coin" superieur-droite-avant de l'espace physique. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* 3 */
/* D E F I N I T I O N D E L ' E S P A C E P H Y S I Q U E D A N S R ( D E B U T ) : */
/* */
/*************************************************************************************************************************************/
#include xrk/attractor.12.I"
#define dXmin_ESPACE \
PARE(0.0)
#define dYmin_ESPACE \
PARE(0.0)
#define dZmin_ESPACE \
PARE(0.0)
/* Definition des minima des differentielles {dx,dy,dz}. */
#define dXmax_ESPACE \
PARE(1.0)
#define dYmax_ESPACE \
PARE(1.0)
#define dZmax_ESPACE \
PARE(1.0)
/* Definition des maxima des differentielles {dx,dy,dz}. */
#include xrk/attractor.1D.I"
/* Formules de renormalisation des differentielles dans [0,1] ; elles sont utilisees lorsque */
/* la production d'images en couleurs est demandee (voir 'visualiser_en_RVB'). */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A S S A G E D E 4 A 3 D I M E N S I O N S : */
/* */
/*************************************************************************************************************************************/
#define DEFINITION_XX \
FU
#define DEFINITION_XY \
FZERO
#define DEFINITION_XZ \
FZERO
#define DEFINITION_XT \
FZERO
DEFV(Local,DEFV(Float,INIT(definition_XX,DEFINITION_XX)));
DEFV(Local,DEFV(Float,INIT(definition_XY,DEFINITION_XY)));
DEFV(Local,DEFV(Float,INIT(definition_XZ,DEFINITION_XZ)));
DEFV(Local,DEFV(Float,INIT(definition_XT,DEFINITION_XT)));
/* Definition de la coordonnee 'X' tridimensionnelle en fonction des coordonnees {X,Y,Z,T}. */
#define DEFINITION_YX \
FZERO
#define DEFINITION_YY \
FU
#define DEFINITION_YZ \
FZERO
#define DEFINITION_YT \
FZERO
DEFV(Local,DEFV(Float,INIT(definition_YX,DEFINITION_YX)));
DEFV(Local,DEFV(Float,INIT(definition_YY,DEFINITION_YY)));
DEFV(Local,DEFV(Float,INIT(definition_YZ,DEFINITION_YZ)));
DEFV(Local,DEFV(Float,INIT(definition_YT,DEFINITION_YT)));
/* Definition de la coordonnee 'Y' tridimensionnelle en fonction des coordonnees {X,Y,Z,T}. */
#define DEFINITION_ZX \
FZERO
#define DEFINITION_ZY \
FZERO
#define DEFINITION_ZZ \
FU
#define DEFINITION_ZT \
FZERO
DEFV(Local,DEFV(Float,INIT(definition_ZX,DEFINITION_ZX)));
DEFV(Local,DEFV(Float,INIT(definition_ZY,DEFINITION_ZY)));
DEFV(Local,DEFV(Float,INIT(definition_ZZ,DEFINITION_ZZ)));
DEFV(Local,DEFV(Float,INIT(definition_ZT,DEFINITION_ZT)));
/* Definition de la coordonnee 'Z' tridimensionnelle en fonction des coordonnees {X,Y,Z,T}. */
#define REDUCTION_D_UN_QUATERNION(nombre,definition_X,definition_Y,definition_Z,definition_T) \
HCreduction(nombre,definition_X,definition_Y,definition_Z,definition_T) \
/* Fonction generale de reduction des composantes d'un quaternion... */
#define REDUCTION_D_UN_QUATERNION_X(nombre) \
REDUCTION_D_UN_QUATERNION(nombre,definition_XX,definition_XY,definition_XZ,definition_XT) \
/* Fonction de reduction des composantes d'un quaternion pour generer une coordonnee 'X'. */
#define REDUCTION_D_UN_QUATERNION_Y(nombre) \
REDUCTION_D_UN_QUATERNION(nombre,definition_YX,definition_YY,definition_YZ,definition_YT) \
/* Fonction de reduction des composantes d'un quaternion pour generer une coordonnee 'Y'. */
#define REDUCTION_D_UN_QUATERNION_Z(nombre) \
REDUCTION_D_UN_QUATERNION(nombre,definition_ZX,definition_ZY,definition_ZZ,definition_ZT) \
/* Fonction de reduction des composantes d'un quaternion pour generer une coordonnee 'Z'. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D U M O D E D E R E P R E S E N T A T I O N D E S P O I N T S : */
/* */
/*************************************************************************************************************************************/
#define COLORIER_LES_POINTS_ALEATOIREMENT \
FAUX
DEFV(Local,DEFV(Logical,INIT(colorier_les_points_aleatoirement,COLORIER_LES_POINTS_ALEATOIREMENT)));
/* Cet indicateur permet de savoir si les points seront coloriees aleatoirement ('VRAI') */
/* ou seront representees autrement... */
#define COLORIER_LES_POINTS_AVEC_LE_CORPS_DES_QUATERNIONS \
VRAI
DEFV(Local,DEFV(Logical,INIT(colorier_les_points_avec_le_corps_des_quaternions,COLORIER_LES_POINTS_AVEC_LE_CORPS_DES_QUATERNIONS)));
/* Cet indicateur permet de savoir si les points seront coloriees en utilisant certaines */
/* informations du corps des Quaternions ('VRAI') ou seront representees autrement... */
#define COMPOSANTE_ROUGE_PAR_DEFAUT \
BLANC
DEFV(Local,DEFV(genere_p,INIT(composante_ROUGE_par_defaut,COMPOSANTE_ROUGE_PAR_DEFAUT)));
#define COMPOSANTE_VERTE_PAR_DEFAUT \
BLANC
DEFV(Local,DEFV(genere_p,INIT(composante_VERTE_par_defaut,COMPOSANTE_VERTE_PAR_DEFAUT)));
#define COMPOSANTE_BLEUE_PAR_DEFAUT \
BLANC
DEFV(Local,DEFV(genere_p,INIT(composante_BLEUE_par_defaut,COMPOSANTE_BLEUE_PAR_DEFAUT)));
/* Introduit le 20151207095033, date avant laquelle on ne pouvait forcer que du 'BLANC'... */
#define GENERATION_D_UNE_COMPOSANTE_DE_COULEUR_D_UN_POINT(point,composante,couleur,seuil_inferieur,seuil_superieur,niveau_par_defaut) \
Bblock \
Test(IL_FAUT(colorier_les_points_aleatoirement)) \
Bblock \
DEFV(Float,INIT(discriminateur \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_ROUGE) \
,FU \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_VERTE) \
,FDEUX \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_BLEUE) \
,FTROIS \
,FLOT__UNDEF \
) \
) \
) \
) \
); \
\
EGAL(ASD1(point_courant_de_l_espace_de_parametrage,x) \
,_cDENORMALISE_OX(MUL2(discriminateur,HReelle(point))) \
); \
EGAL(ASD1(point_courant_de_l_espace_de_parametrage,y) \
,_cDENORMALISE_OY(MUL2(discriminateur,HImaginaire(point))) \
); \
/* Cette modification de 'point_courant_de_l_espace_de_parametrage' en fonction du 'point' */ \
/* est destinee a obtenir toujours les memes couleurs au meme point, ce qui sinon ne serait */ \
/* pas possible, car, sauf pour les extremites 'Gauche' et 'Droite' du segment de depart, */ \
/* chaque point calcule est utilise deux fois (une premiere fois en tant que 'Droite', puis */ \
/* une seconde fois en tant que 'Gauche'). Enfin, l'intervention de 'discriminateur' est */ \
/* destine a generer des valeurs differentes pour les trois composantes... */ \
\
GENERATION_D_UNE_VALEUR(composante \
,FLOT(seuil_inferieur) \
,FLOT(seuil_superieur) \
); \
/* Lorsque la composante est aleatoire, on la tire au sort... */ \
Eblock \
ATes \
Bblock \
Test(IL_FAUT(colorier_les_points_avec_le_corps_des_quaternions)) \
Bblock \
DEFV(Float,INIT(discriminateur \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_ROUGE) \
,NORM(DIVI(REDUCTION_D_UN_QUATERNION_X(q_difference) \
,HCmodule(q_difference) \
) \
,NEGA(FU) \
,NEUT(FU) \
) \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_VERTE) \
,NORM(DIVI(REDUCTION_D_UN_QUATERNION_Y(q_difference) \
,HCmodule(q_difference) \
) \
,NEGA(FU) \
,NEUT(FU) \
) \
,COND(IFEQ(couleur,COMPOSANTE_CHROMATIQUE_BLEUE) \
,NORM(DIVI(REDUCTION_D_UN_QUATERNION_Z(q_difference) \
,HCmodule(q_difference) \
) \
,NEGA(FU) \
,NEUT(FU) \
) \
,FLOT__UNDEF \
) \
) \
) \
) \
); \
/* Lorsque la composante utilise le corps des Quaternions suivant le code arbitraire : */ \
/* */ \
/* ROUGE : DIVI(REDUCTION_D_UN_QUATERNION_X(q_difference),HCmodule(q_difference)) */ \
/* VERTE : DIVI(REDUCTION_D_UN_QUATERNION_Y(q_difference),HCmodule(q_difference)) */ \
/* BLEUE : DIVI(REDUCTION_D_UN_QUATERNION_Z(q_difference),HCmodule(q_difference)) */ \
/* */ \
\
EGAL(composante \
,SCAL(discriminateur \
,FU \
,FLOT__BLANC \
) \
); \
Eblock \
ATes \
Bblock \
EGAL(composante,FLOT(niveau_par_defaut)); \
/* Dans le dernier cas, on fixe un niveau par defaut (a priori le maximum, soit 'BLANC'). */ \
Eblock \
ETes \
Eblock \
ETes \
\
EGAL(composante \
,______NORMALISE_NIVEAU(TRON(composante \
,seuil_inferieur \
,seuil_superieur \
) \
) \
); \
/* Seuillage de la composante courante. On notera que lorsque la valeur est aleatoire cela */ \
/* n'est pas utile, mais ainsi, on prevoit l'avenir... */ \
Eblock \
/* Generation d'une des trois composantes de la couleur d'un point... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A T E R I A L I S A T I O N D E S C O N N E X I O N S : */
/* */
/*************************************************************************************************************************************/
#define MATERIALISER_LES_CONNEXIONS \
VRAI
#include xrk/recuit_2D.14.I"
#define AJUSTER_AUTOMATIQUEMENT_LE_NOMBRE_DE_POINTS_SUR_UNE_CHAINE_DE_CONNEXION \
VRAI
DEFV(Local,DEFV(Logical,INIT(ajuster_automatiquement_le_nombre_de_points_sur_une_chaine_de_connexion
,AJUSTER_AUTOMATIQUEMENT_LE_NOMBRE_DE_POINTS_SUR_UNE_CHAINE_DE_CONNEXION
)
)
);
/* Indique si l'on doit ajuster automatiquement le nombre de points sur une chaine de */
/* connexion ('VRAI') ou bien utiliser 'nombre_absolu_de_points_sur_une_chaine_de_connexion' */
/* ('FAUX'). */
#define FACTEUR_DU_NOMBRE_RELATIF_DE_POINTS_SUR_UNE_CHAINE_DE_CONNEXION \
FU
DEFV(Local,DEFV(Float,INIT(facteur_du_nombre_relatif_de_points_sur_une_chaine_de_connexion
,FACTEUR_DU_NOMBRE_RELATIF_DE_POINTS_SUR_UNE_CHAINE_DE_CONNEXION
)
)
);
/* En fait facteur multiplicatif permettant de passer de la longueur d'une chaine de */
/* connexion au nombre de points a utiliser. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S D I F F E R E N T S E S P A C E S E T D E L ' E F F E T D E B R U M E : */
/* */
/*************************************************************************************************************************************/
#include xrk/attractor.13.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* A I D E A U C A D R A G E D E S I M A G E S : */
/* */
/*************************************************************************************************************************************/
#include xrk/attractor.1C.I"
DONNEES_DE_RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES
/* Definition des extrema des coordonnees et des derivees. On notera bien l'absence de */
/* point-virgule apres 'DONNEES_DE_RECHERCHE_DES_EXTREMA_DES_COORDONNEES_ET_DES_DERIVEES'. */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D E S I M A G E S : */
/* */
/*************************************************************************************************************************************/
#include xrv/champs_5.14.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S G E N E R A L E S R E L A T I V E S A L A V I S U A L I S A T I O N : */
/* */
/*************************************************************************************************************************************/
#define NOMBRE_D_ITERATIONS \
QUATRE \
/* Le nombre d'iterations est initialise pour la courbe de von Koch... */
#include xrv/particule.41.I"
#include xrk/attractor.14.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F O N C T I O N D E M E M O R I S A T I O N D U P O I N T C O U R A N T : */
/* */
/*************************************************************************************************************************************/
#define RAYON_DE_VISUALISATION \
GRO2(FRA10(FRA10(FU)))
#include xrk/recuit_2D.16.I"
#define MEMORISATION_DU_QUATERNION_COURANT(memoriser,nombre,dcxZ,dcyZ,dczZ) \
Bblock \
Test(IL_FAUT(memoriser)) \
Bblock \
EGAL(cx,REDUCTION_D_UN_QUATERNION_X(nombre)); \
EGAL(cy,REDUCTION_D_UN_QUATERNION_Y(nombre)); \
EGAL(cz,REDUCTION_D_UN_QUATERNION_Z(nombre)); \
/* Recuperation de la position du point courant (cx,cy,cz)... */ \
\
GENERATION_D_UNE_COMPOSANTE_DE_COULEUR_D_UN_POINT(nombre \
,dcxZ \
,COMPOSANTE_CHROMATIQUE_ROUGE \
,seuil_inferieur_du_ROUGE,seuil_superieur_du_ROUGE \
,composante_ROUGE_par_defaut \
); \
GENERATION_D_UNE_COMPOSANTE_DE_COULEUR_D_UN_POINT(nombre \
,dcyZ \
,COMPOSANTE_CHROMATIQUE_VERTE \
,seuil_inferieur_du_VERTE,seuil_superieur_du_VERTE \
,composante_VERTE_par_defaut \
); \
GENERATION_D_UNE_COMPOSANTE_DE_COULEUR_D_UN_POINT(nombre \
,dczZ \
,COMPOSANTE_CHROMATIQUE_BLEUE \
,seuil_inferieur_du_BLEUE,seuil_superieur_du_BLEUE \
,composante_BLEUE_par_defaut \
); \
/* Generation des couleurs... */ \
EGAL(dcx,dcxZ); \
EGAL(dcy,dcyZ); \
EGAL(dcz,dczZ); \
/* Forcage des derivees (dcx,dcy,dcz) au point courant. */ \
\
CALS(memorisation_1_point_08(SOUS(cx,Xcentre_ESPACE) \
,SOUS(cy,Ycentre_ESPACE) \
,SOUS(cz,Zcentre_ESPACE) \
,dcx \
,dcy \
,dcz \
,UNDEF \
,MUL2(grossissement_du_rayon_de_visualisation_des_points \
,rayon_de_visualisation \
) \
) \
); \
Eblock \
ATes \
Bblock \
Eblock \
ETes \
\
EGAL(memoriser_qG,FAUX); \
/* Ainsi, seul le 'qG' qui definit le segment de "base" est trace ; les autres 'qG' obtenus */ \
/* recursivement ne le sont pas, car, en effet, un 'qG' est toujours le 'qD' du segment */ \
/* suivant de la courbe... */ \
Eblock \
/* Memorisation du quaternion courant... */
BFonctionI
DEFV(Local,DEFV(FonctionI,memorisation_1_point_07(AXf,AYf,AZf,AdXf,AdYf,AdZf,numero_de_l_iteration_courante)))
/* Fonction introduite le 20151207111747 pour 'VISUALISATION_D_UNE_CHAINE_DE_CONNEXION(...)' */
/* ci-apres... */
DEFV(Argument,DEFV(Float,AXf));
DEFV(Argument,DEFV(Float,AYf));
DEFV(Argument,DEFV(Float,AZf));
/* Definition de la position {x,y,z} de l'iteration courante. */
DEFV(Argument,DEFV(Float,AdXf));
DEFV(Argument,DEFV(Float,AdYf));
DEFV(Argument,DEFV(Float,AdZf));
/* Definition des differentielles {dx,dy,dz} de la position de l'iteration courante. */
DEFV(Argument,DEFV(Int,numero_de_l_iteration_courante));
/* Numero de l'iteration courante afin d'attenuer eventuellement la luminance des points */
/* materialisant chaque iteration en fonction de leur numero (les premieres iterations etant */
/* plus sombres, et les dernieres etant plus lumineuses). */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
#include xrk/attractor.15.I"
INIT_ERROR;
/*..............................................................................................................................*/
MEMORISATION_DU_POINT_COURANT(X_DERIVEE_DANS_01(AdXf)
,Y_DERIVEE_DANS_01(AdYf)
,Z_DERIVEE_DANS_01(AdZf)
);
/* Memorisation du point courant en Noir et Blanc ou en Couleurs, mais uniquement s'il est */
/* visible en fonction des conditions de visualisation... */
RETU_ERROR;
Eblock
EFonctionI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F O N C T I O N S D E V I S U A L I S A T I O N E T D ' I N T E R P O L A T I O N : */
/* */
/*************************************************************************************************************************************/
=define ZOOM_IMPLICITE \
GRO7(FRA10(FU)) \
/* Afin d'etre sur de voir toutes les particules generees... */
#include xrk/attractor.17.I"
#define NE_PAS_GENERER_grossissement_du_rayon_de_visualisation_des_points
#include xrv/particule.31.I"
/* Introduit le 20151207103640... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S I N I T I A L I S A T I O N S : */
/* */
/*************************************************************************************************************************************/
#include xrk/attractor.18.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P O U R D E S R A I S O N S D E C O M P A T I B I L I T E : */
/* */
/*************************************************************************************************************************************/
#include xrk/integr.1B.vv.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N D E S A N G L E S D E R O T A T I O N : */
/* */
/*************************************************************************************************************************************/
#include xrv/particule.22.I"
dfTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_1,fichier_ANGLE_DE_ROTATION_1,ANGLE_DE_ROTATION_1_IMPLICITE,FZERO)
dfTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_2,fichier_ANGLE_DE_ROTATION_2,ANGLE_DE_ROTATION_2_IMPLICITE,FZERO)
dfTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_3,fichier_ANGLE_DE_ROTATION_3,ANGLE_DE_ROTATION_3_IMPLICITE,FZERO)
/* On verra avec interet 'v $xtc/FracCurve.11$c' qui tire au sort ses parametres, puis */
/* les edite... */
#define sANGLE_DE_ROTATION_1(numero_de_l_angle) \
FLOT(sTRANSFORMAT_31(numero_de_l_angle,liste_ANGLE_DE_ROTATION_1))
#define sANGLE_DE_ROTATION_2(numero_de_l_angle) \
FLOT(sTRANSFORMAT_31(numero_de_l_angle,liste_ANGLE_DE_ROTATION_2))
#define sANGLE_DE_ROTATION_3(numero_de_l_angle) \
FLOT(sTRANSFORMAT_31(numero_de_l_angle,liste_ANGLE_DE_ROTATION_3))
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P R O C E D U R E R E C U R S I V E D E */
/* G E N E R A T I O N D ' U N E C O U R B E F R A C T A L E Q U A D R I D I M E N S I O N N E L L E : */
/* */
/*************************************************************************************************************************************/
#define COMPATIBILITE_20151207 \
FAUX \
/* Permet de proceder a des generations compatibles a celles qui furent effectues */ \
/* anterieurement au 20151207102820. */
DEFV(Logical,INIT(compatibilite_20151207,COMPATIBILITE_20151207));
/* Permet de proceder a des generations compatibles a celles qui furent effectues */
/* anterieurement au 20151207102820. */
#define XG \
NEGA(FU)
#define YG \
FZERO
#define ZG \
FZERO
#define TG \
FZERO
/* Definition de l'extremite "Gauche" de la courbe. */
#define XD \
NEUT(FU)
#define YD \
FZERO
#define ZD \
FZERO
#define TD \
FZERO
/* Definition de l'extremite "Droite" de la courbe. */
DEFV(Local,DEFV(Float,INIT(xG,XG)));
DEFV(Local,DEFV(Float,INIT(yG,YG)));
DEFV(Local,DEFV(Float,INIT(zG,ZG)));
DEFV(Local,DEFV(Float,INIT(tG,TG)));
/* Definition de l'extremite "Gauche" de la courbe. */
DEFV(Local,DEFV(Float,INIT(xD,XD)));
DEFV(Local,DEFV(Float,INIT(yD,YD)));
DEFV(Local,DEFV(Float,INIT(zD,ZD)));
DEFV(Local,DEFV(Float,INIT(tD,TD)));
/* Definition de l'extremite "Droite" de la courbe. */
#define APLATIR(q_courbe,q_plat) \
COND(IL_FAUT(aplatir_la_courbe_fractale),q_plat,q_courbe)
#define qG_general \
APLATIR(qG,qG_a_plat)
#define qD_general \
APLATIR(qD,qD_a_plat)
DEFV(Local,DEFV(Logical,INIT(c_est_le_premier_segment,VRAI)));
DEFV(Local,DEFV(hyper_complexe,qD_a_plat_precedent));
#define APLATIR_LA_COURBE_FRACTALE \
FAUX
DEFV(Local,DEFV(Logical,INIT(aplatir_la_courbe_fractale,APLATIR_LA_COURBE_FRACTALE)));
/* Faut-il generer la courbe "standard" ('FAUX') ou bien l'aplatir ('VRAI') et ce afin de */
/* voir comment varie sa longueur (ceci a ete introduit le 20181202094039). */
#define NIVEAU_DE_RECURSION_A_NE_PAS_DEPASSER \
TROIS
DEFV(Local,DEFV(Int,INIT(niveau_de_recursion_a_ne_pas_depasser,NIVEAU_DE_RECURSION_A_NE_PAS_DEPASSER)));
/* Niveau de recursion a ne pas depasser... */
#define RAPPORT_DE_REDUCTION \
FTROIS
DEFV(Local,DEFV(Float,INIT(rapport_de_reduction,RAPPORT_DE_REDUCTION)));
/* Facteur de reduction initialise pour la courbe de von Koch. */
#define ROTATION_ET_CONSTRUCTION(alpha,phi,theta) \
Bblock \
HCegal(qG_reduit,qD_reduit); \
/* Initialisation du nombre "Gauche" avec le nombre "Droite". */ \
HCrotation(q_difference_reduite,q_difference_reduite,alpha,phi,theta); \
/* Rotation et homothetie du generateur. */ \
/* */ \
/* ATTENTION, la definition de 'HCrotation_et_homothetie(...)' a ete modifiee le */ \
/* 19970226154138 ('v $ximcd/operator$FON FHCrotation_et_homothetie'). */ \
HCsomme(qD_reduit,qG_reduit,q_difference_reduite); \
/* Initialisation du nombre "Droite" avec le nombre "Gauche" translate. */ \
CALS(construction_de_la_courbe_fractale(ADRESSE(qG_reduit) \
,ADRESSE(qD_reduit) \
,SUCC(niveau_de_recursion) \
,memoriser_qG \
) \
); \
/* Et enfin, construction recursive... */ \
Eblock \
/* Construction recursive de la courbe fractale... */
#define EDITER_LES_NOMBRES_G_ET_D \
FAUX
DEFV(Local,DEFV(Logical,INIT(editer_les_nombres_G_et_D,EDITER_LES_NOMBRES_G_ET_D)));
/* Controle de l'edition eventuelle des nombres 'qG' et 'qD' (introduit le 20181130161202). */
BFonctionI
DEFV(Local,DEFV(FonctionI,construction_de_la_courbe_fractale(ARGUMENT_POINTERs(AqG)
,ARGUMENT_POINTERs(AqD)
,niveau_de_recursion
,memoriser_qG
)
)
)
DEFV(Argument,DEFV(hyper_complexe,POINTERs(AqG)));
DEFV(Argument,DEFV(hyper_complexe,POINTERs(AqD)));
/* Nombres "Gauche" et "Droite" courants. */
DEFV(Argument,DEFV(Int,niveau_de_recursion));
/* Niveau de recursion courant. */
DEFV(Argument,DEFV(Logical,memoriser_qG));
/* Faut-il memoriser 'qG' ? */
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(hyper_complexe,qG);
DEFV(hyper_complexe,qD);
/* Nombres "Gauche" et "Droite" courants. */
DEFV(hyper_complexe,qG_a_plat);
DEFV(hyper_complexe,qD_a_plat);
/* Nombres "Gauche" et "Droite" courants lors de la mise a plat de la courbe... */
DEFV(hyper_complexe,q_difference);
/* Difference entre les nombres "Gauche" et "Droite" courants. */
INIT_ERROR;
/*..............................................................................................................................*/
HCegal(qG,INDIRECT(AqG));
HCegal(qD,INDIRECT(AqD));
/* Recuperation des nombres "Gauche" et "Droite" courants. */
Test(IL_FAUT(editer_les_nombres_G_et_D))
/* Test introduit le 20181130161202... */
Bblock
Repe(PRED(niveau_de_recursion));
Bblock
CALS(FPrme0(" "));
Eblock
ERep
CAL3(Prme1("niveau=%d",niveau_de_recursion));
CAL3(Prme4(" G={%+.^^^,%+.^^^,%+.^^^,%+.^^^}",HReelle(qG),HImaginaire(qG),HJmaginaire(qG),HKmaginaire(qG)));
CAL3(Prme4(" D={%+.^^^,%+.^^^,%+.^^^,%+.^^^}",HReelle(qD),HImaginaire(qD),HJmaginaire(qD),HKmaginaire(qD)));
CALS(Fsauts_de_lignes(UN));
Eblock
ATes
Bblock
Eblock
ETes
HCdifference(q_difference,qD,qG);
/* Calcul de la difference entre les nombres "Gauche" et "Droite" courants. */
Test(IFGE(niveau_de_recursion,niveau_de_recursion_a_ne_pas_depasser))
Bblock
DEFV(Float,INIT(dcxZG,FLOT__UNDEF));
DEFV(Float,INIT(dcyZG,FLOT__UNDEF));
DEFV(Float,INIT(dczZG,FLOT__UNDEF));
/* Couleur du point 'qG'. */
DEFV(Float,INIT(dcxZD,FLOT__UNDEF));
DEFV(Float,INIT(dcyZD,FLOT__UNDEF));
DEFV(Float,INIT(dczZD,FLOT__UNDEF));
/* Couleur du point 'qD'. */
Test(IL_FAUT(aplatir_la_courbe_fractale))
Bblock
Test(EST_VRAI(c_est_le_premier_segment))
Bblock
HCinitialisation(qG_a_plat,HReelle(qG),yG,zG,tG);
HCinitialisation(qD_a_plat,HReelle(qD),yG,zG,tG);
/* ATTENTION : je rappelle le 20181130151634 que c'est bien 'yG' que l'on utilise deux fois */
/* ci-dessus (pour 'qG_a_plat' ET 'qD_a_plat') car, en effet, on veut obtenir un segment */
/* horizontal (et donc a 'y' constant)... */
EGAL(c_est_le_premier_segment,FAUX);
Eblock
ATes
Bblock
HCinitialisation(qG_a_plat
,HReelle(qD_a_plat_precedent)
,yG
,zG
,tG
);
HCinitialisation(qD_a_plat
,ADD2(HReelle(qG_a_plat)
,RdisF4D(HReelle(qG),HImaginaire(qG),HJmaginaire(qG),HKmaginaire(qG)
,HReelle(qD),HImaginaire(qD),HJmaginaire(qD),HKmaginaire(qD)
)
)
,yG
,zG
,tG
);
/* Ainsi, on se deplace a l'horizontal (a 'y' constant et egal a 'yG'), l'amplitude du */
/* deplacement horizontal etant egal a la distance entre 'qG' et 'qD'... */
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
HCegal(qD_a_plat_precedent,qD_a_plat);
/* Dispositif de mise a plat introduit le 20181202094039... */
MEMORISATION_DU_QUATERNION_COURANT(memoriser_qG,qG_general,dcxZG,dcyZG,dczZG);
MEMORISATION_DU_QUATERNION_COURANT(VRAI,qD_general,dcxZD,dcyZD,dczZD);
/* Memorisation des nombres complexes "Gauche" et "Droite" courants. */
Test(IL_FAUT(materialiser_les_connexions))
Bblock
Test(IL_FAUT(compatibilite_20151207))
/* Test introduit le 20151207102820... */
Bblock
Repe(nombre_absolu_de_points_sur_une_chaine_de_connexion)
Bblock
DEFV(Float,INIT(lambda
,ADD2(COORDONNEE_BARYCENTRIQUE_MINIMALE
,SCAL(compteur_des_repetitions_du_Repe
,SOUS(ADD3(UN,nombre_absolu_de_points_sur_une_chaine_de_connexion,UN)
,PREMIERE_ITERATION_D_UN_Repe
)
,SOUS(COORDONNEE_BARYCENTRIQUE_MAXIMALE
,COORDONNEE_BARYCENTRIQUE_MINIMALE
)
)
)
)
);
/* Definition de la coordonnee barycentrique d'interpolation des coordonnees et des */
/* couleurs des points de l'espace. On notera le 'ADD3(UN,...,UN)' destine a prendre en */
/* compte le fait que 'nombre_absolu_de_points_sur_une_chaine_de_connexion' exclut les */
/* extremites qui correspondent aux points du reseau eux-memes... */
EGAL(cx,BARY(REDUCTION_D_UN_QUATERNION_X(qG_general),REDUCTION_D_UN_QUATERNION_X(qD_general),lambda));
EGAL(cy,BARY(REDUCTION_D_UN_QUATERNION_Y(qG_general),REDUCTION_D_UN_QUATERNION_Y(qD_general),lambda));
EGAL(cz,BARY(REDUCTION_D_UN_QUATERNION_Z(qG_general),REDUCTION_D_UN_QUATERNION_Z(qD_general),lambda));
/* Recuperation de la position du point courant (cx,cy,cz)... */
EGAL(dcx,BARY(dcxZG,dcxZD,lambda));
EGAL(dcy,BARY(dcyZG,dcyZD,lambda));
EGAL(dcz,BARY(dczZG,dczZD,lambda));
/* Forcage arbitraire des derivees (dcx,dcy,dcz) au point courant. */
CALS(memorisation_1_point_08(SOUS(cx,Xcentre_ESPACE)
,SOUS(cy,Ycentre_ESPACE)
,SOUS(cz,Zcentre_ESPACE)
,dcx
,dcy
,dcz
,UNDEF
,NEUT(rayon_de_visualisation)
)
);
/* Memorisation du point courant... */
Eblock
ERep
Eblock
ATes
Bblock
DEFV(Int,INIT(nombre_effectif_de_points_sur_une_chaine_de_connexion,UNDEF));
/* Nombre de points effectif sur une chaine de connexion. */
Test(IL_FAUT(ajuster_automatiquement_le_nombre_de_points_sur_une_chaine_de_connexion))
Bblock
EGAL(nombre_effectif_de_points_sur_une_chaine_de_connexion
,TRPU(ARRI(MUL2(facteur_du_nombre_relatif_de_points_sur_une_chaine_de_connexion
,DIVI(RdisF3D(REDUCTION_D_UN_QUATERNION_X(qG_general)
,REDUCTION_D_UN_QUATERNION_Y(qG_general)
,REDUCTION_D_UN_QUATERNION_Z(qG_general)
,REDUCTION_D_UN_QUATERNION_X(qD_general)
,REDUCTION_D_UN_QUATERNION_Y(qD_general)
,REDUCTION_D_UN_QUATERNION_Z(qD_general)
)
,rayon_de_visualisation
)
)
)
)
);
/* Cas ou il y a ajustement automatique du nombre de points : celui-ci est alors fonction */
/* de la distance d(A,B) et des rayons de visualisation (sans oublier que ceux-ci sont */
/* definis dans [0,1] et non pas dans l'espace physique. */
Eblock
ATes
Bblock
EGAL(nombre_effectif_de_points_sur_une_chaine_de_connexion
,nombre_absolu_de_points_sur_une_chaine_de_connexion
);
/* Cas ou il n'y a pas d'ajustement automatique du nombre de points... */
Eblock
ETes
EGAL(nombre_effectif_de_points_sur_une_chaine_de_connexion
,MAX2(nombre_effectif_de_points_sur_une_chaine_de_connexion,DEUX)
);
/* Il faut malgre tout visualiser au moins 2 points (les 2 extremites 'A' et 'B'). */
VISUALISATION_D_UNE_CHAINE_DE_CONNEXION(REDUCTION_D_UN_QUATERNION_X(qG_general)
,REDUCTION_D_UN_QUATERNION_Y(qG_general)
,REDUCTION_D_UN_QUATERNION_Z(qG_general)
,dcxZG,dcyZG,dczZG
,rayon_de_visualisation
,REDUCTION_D_UN_QUATERNION_X(qD_general)
,REDUCTION_D_UN_QUATERNION_Y(qD_general)
,REDUCTION_D_UN_QUATERNION_Z(qD_general)
,dcxZD,dcyZD,dczZD
,rayon_de_visualisation
,nombre_effectif_de_points_sur_une_chaine_de_connexion
,UNDEF
,interpoler_les_chaines_de_connexion_par_des_splines_cubiques
,dcxZG,dcyZG,dczZG
,dcxZD,dcyZD,dczZD
);
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ATes
Bblock
DEFV(hyper_complexe,q_difference_reduite);
/* Afin de reduire la difference courante suivant le facteur et l'angle courants... */
DEFV(hyper_complexe,qG_reduit);
DEFV(hyper_complexe,qD_reduit);
/* Nouveaux nombres "Gauche" et "Droite" apres reduction... */
HCegal(qD_reduit,qG);
/* Initialisation du nombre "Droite" reduit avec le nombre "Gauche" courant. */
HChomothetie(q_difference_reduite,q_difference,INVE(rapport_de_reduction));
/* Reduction de la difference courante suivant le facteur courant. */
/* */
/* ATTENTION, la definition de 'HCrotation_et_homothetie(...)' a ete modifiee le */
/* 19970226154138 ('v $ximcd/operator$FON FHCrotation_et_homothetie'). */
Komp(numero_de_l_angle,nombre_d_iterations)
Bblock
ROTATION_ET_CONSTRUCTION(sANGLE_DE_ROTATION_1(numero_de_l_angle)
,sANGLE_DE_ROTATION_2(numero_de_l_angle)
,sANGLE_DE_ROTATION_3(numero_de_l_angle)
);
Eblock
EKom
Eblock
ETes
RETU_ERROR;
Eblock
EFonctionI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* G E N E R A T I O N D ' U N E C O U R B E F R A C T A L E Q U A D R I D I M E N S I O N N E L L E */
/* D A N S L E C O R P S D E S Q U A T E R N I O N S : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(hyper_complexe,qG);
DEFV(hyper_complexe,qD);
/* Nombres "Gauche" et "Droite" de depart... */
/*..............................................................................................................................*/
INITIALISATIONS_GENERALES;
/* Initialisations generales faites au tout debut... */
iTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_1,ANGLE_DE_ROTATION_1_IMPLICITE);
iTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_2,ANGLE_DE_ROTATION_2_IMPLICITE);
iTRANSFORMAT_31(liste_ANGLE_DE_ROTATION_3,ANGLE_DE_ROTATION_3_IMPLICITE);
/* Initialisation de la liste des angles. */
#include xrv/champs_5.1A.I"
GET_ARGUMENTSv(nombre_d_arguments
,BLOC(GET_ARGUMENT_L("compatibilite_20151207=",compatibilite_20151207);
PROCESS_ARGUMENT_I("iterations=",nombre_d_iterations
,BLOC(VIDE;)
,BLOC(PRINT_AVERTISSEMENT("'iterations=' doit etre defini avant tout fichier");)
);
/* ATTENTION : la recuperation de 'nombre_d_iterations' doit preceder les */
/* 'PROCESS_ARGUMENT_C(...)' qui suivent car ils l'utilisent. */
PROCESS_ARGUMENTS_GEOMETRIQUES;
PROCESS_ARGUMENTS_DE_DEFINITION_DES_FICHIERS_12;
/* Ces parametres ont ete introduits le 20021105122910. */
PROCESS_ARGUMENT_FICHIER("ANGLE_DE_ROTATION_1="
,fichier_ANGLE_DE_ROTATION_1
,liste_ANGLE_DE_ROTATION_1
,ANGLE_DE_ROTATION_1_IMPLICITE
,lTRANSFORMAT_12
);
PROCESS_ARGUMENT_FICHIER("ANGLE_DE_ROTATION_2="
,fichier_ANGLE_DE_ROTATION_2
,liste_ANGLE_DE_ROTATION_2
,ANGLE_DE_ROTATION_2_IMPLICITE
,lTRANSFORMAT_12
);
PROCESS_ARGUMENT_FICHIER("ANGLE_DE_ROTATION_3="
,fichier_ANGLE_DE_ROTATION_3
,liste_ANGLE_DE_ROTATION_3
,ANGLE_DE_ROTATION_3_IMPLICITE
,lTRANSFORMAT_12
);
PROCESS_ARGUMENTS_DE_VISUALISATION;
GET_ARGUMENT_L("aplatir=""plat",aplatir_la_courbe_fractale);
GET_ARGUMENT_N("courbe=",aplatir_la_courbe_fractale);
/* Ces options ont ete introduites le 20181202094039... */
GET_ARGUMENT_F("XX=",definition_XX);
GET_ARGUMENT_F("XY=",definition_XY);
GET_ARGUMENT_F("XZ=",definition_XZ);
GET_ARGUMENT_F("XT=",definition_XT);
GET_ARGUMENT_F("YX=",definition_YX);
GET_ARGUMENT_F("YY=",definition_YY);
GET_ARGUMENT_F("YZ=",definition_YZ);
GET_ARGUMENT_F("YT=",definition_YT);
GET_ARGUMENT_F("ZX=",definition_ZX);
GET_ARGUMENT_F("ZY=",definition_ZY);
GET_ARGUMENT_F("ZZ=",definition_ZZ);
GET_ARGUMENT_F("ZT=",definition_ZT);
GET_ARGUMENT_L("aleatoire=",colorier_les_points_aleatoirement);
GET_ARGUMENT_I("graine=",graine_du_generateur_d_evenements);
GET_ARGUMENT_L("affiner_rdn=",rdnIFnD_____affiner_la_generation);
GET_ARGUMENT_L("iterer_rdn=",rdnIFnD_____iterer_la_generation);
GET_ARGUMENT_L("quaternion=",colorier_les_points_avec_le_corps_des_quaternions);
GET_ARGUMENT_P("composante_ROUGE=""cROUGE=",composante_ROUGE_par_defaut);
GET_ARGUMENT_P("composante_VERTE=""cVERTE=",composante_VERTE_par_defaut);
GET_ARGUMENT_P("composante_BLEUE=""cBLEUE=",composante_BLEUE_par_defaut);
/* Ces options ont ete introduites le 20151207095033... */
GET_ARGUMENT_L("connexions=",materialiser_les_connexions);
GET_ARGUMENT_L("ajuster_points=""Pajuster="
,ajuster_automatiquement_le_nombre_de_points_sur_une_chaine_de_connexion
);
GET_ARGUMENT_L("equidistance=",garantir_l_equidistance_des_points_successifs_d_une_chaine_de_connexion);
GET_ARGUMENT_L("equidistance_chaine_connexion_____compatibilite_20051230=""compatibilite_20051230="
,equidistance_des_points_successifs_d_une_chaine_de_connexion_____compatibilite_20051230
);
GET_ARGUMENT_L("equidistance_chaine_connexion_____compatibilite_20081109=""compatibilite_20081109="
,equidistance_des_points_successifs_d_une_chaine_de_connexion_____compatibilite_20081109
);
GET_ARGUMENT_F("dm=""distance_minimale=""distance="
,distance_minimale_entre_deux_points_successifs_d_une_chaine_de_connexion
);
GET_ARGUMENT_F("amelioration_lambda=""al=",facteur_d_amelioration_du_lambda_d_une_chaine_de_connexion);
GET_ARGUMENT_I("points=""nombreA=""Apoints=",nombre_absolu_de_points_sur_une_chaine_de_connexion);
GET_ARGUMENT_F("nombreR=""Rpoints=",facteur_du_nombre_relatif_de_points_sur_une_chaine_de_connexion);
GET_ARGUMENT_F("grossissement=",grossissement_du_rayon_de_visualisation_des_points);
GET_ARGUMENT_L("cubique=",interpoler_les_chaines_de_connexion_par_des_splines_cubiques);
/* Toutes ces options ont ete introduites ou mises a jour le 20151207103640... */
GET_ARGUMENT_I("recursion=",niveau_de_recursion_a_ne_pas_depasser);
GET_ARGUMENT_F("reduction=""rapport=",rapport_de_reduction);
GET_ARGUMENT_F("XG=""xG=",xG);
GET_ARGUMENT_F("YG=""yG=",yG);
GET_ARGUMENT_F("ZG=""zG=",zG);
GET_ARGUMENT_F("TG=""tG=",tG);
GET_ARGUMENT_F("XD=""xD=",xD);
GET_ARGUMENT_F("YD=""yD=",yD);
GET_ARGUMENT_F("ZD=""zD=",zD);
GET_ARGUMENT_F("TD=""tD=",tD);
/* Le 20200808102653 les majuscules ont ete introduites pour {x,y,z,t}... */
GET_ARGUMENT_L("editer_GD=""eGD=",editer_les_nombres_G_et_D);
/* Options introduites le 20181130161202... */
)
);
#include xrv/champs_5.19.I"
/* Pour eviter le message : */
/* */
/* Static function is not referenced. */
/* */
/* sur 'SYSTEME_ES9000_AIX_CC'... */
#include xrk/attractor.19.I"
/* Validations et definition de l'espace physique. */
begin_nouveau_block
Bblock
Komp(numero_de_la_periode_courante_de_la_simulation,nombre_de_periodes_de_la_simulation)
Bblock
RE_INITIALISATION_DE_L_HORLOGE;
INITIALISATIONS_RELATIVES_A_CHAQUE_NOUVELLE_IMAGE(numero_de_la_periode_courante);
/* Initialisations necessaires avant le calcul et la generation de chaque nouvelle image. */
HCinitialisation(qG,xG,yG,zG,tG);
HCinitialisation(qD,xD,yD,zD,tD);
/* Initialisation des extremites de la courbe. */
CALS(construction_de_la_courbe_fractale(ADRESSE(qG),ADRESSE(qD),UN,VRAI));
/* Construction de la courbe. */
#include xrk/attractor.1A.I"
PARALLELISME(BLOC(GENERATION_D_UNE_IMAGE_ET_PASSAGE_A_LA_SUIVANTE(BLOC(VIDE;));
/* Generation de l'image courante... */
)
,BLOC(PASSAGE_A_L_IMAGE_SUIVANTE;)
,numero_de_la_periode_courante
);
Eblock
EKom
Eblock
end_nouveau_block
RETU_Commande;
Eblock
ECommande