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