_______________________________________________________________________________________________________________________________________ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N S D E G E N E R A T I O N S A L E A T O I R E S : */ /* */ /* */ /* Definition : */ /* */ /* Ce fichier contient toutes les fonctions */ /* de base de generation des champs fractals. */ /* */ /* */ /* Author of '$xiii/aleat.2$vv$FON' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 19870000000000). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E D I T I O N S D I V E R S E S : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____editer_les_mailles_et_les_ponderations,FAUX))); /* Cet indicateur permet d'editer les differentes caracteristiques des mailles, autorisant */ /* la "mise au point" des differents parametres de ponderation intervenant dans la fonction */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____aborter_apres_l_edition_des_mailles_et_des_ponderations,FAUX))); /* Cet indicateur introduit le 20180708114359 permet de sortir immediatement et tres */ /* brutalement du '$K' appelant et ce pour gagner du temps apres ces editions... */ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____editer_les_noeuds_et_les_valeurs_aleatoires,FAUX))); /* Cet indicateur permet d'editer les coordonnees des noeuds, ainsi que la valeur aleatoire */ /* associee (introduit le 20220111093529)... */ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____editer_uniquement_les_noeuds,FAUX))); /* Cet indicateur permet d'editer uniquement les coordonnees des noeuds (introduit */ /* le 20220113171311)... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E R I V A T I O N N U M E R I Q U E : */ /* */ /*************************************************************************************************************************************/ #define NORMALISATION_DES_FONCTIONS_A_DERIVER(fonction) \ DIVI(fonction,SOUS(borne_superieure,borne_inferieure)) \ /* "Pseudo-normalisation" des fonctions a deriver. */ DEFV(Common,DEFV(Float,ZINT(IFfractal_2D_precises__IFfractal_3D_precises_____facteur_des_derivees_numeriques,FU))); /* En diminuant ce facteur ou adoucit les transitions d'une maille a l'autre, alors qu'en */ /* l'augmentant, on les rend plus "cassantes"... */ /* */ /* Le nom 'facteur_des_derivees_numeriques' a ete "enrichi" le 20050411102008 car, en */ /* effet, il entrait en collision avec un autre 'Common' de meme nom qui etait defini */ /* dans 'v $xiii/di_image$FON 20050411102453'... */ #define DERIVATION_NUMERIQUE(derivee,fonction_origine,fonction_extremite,pas_du_maillage) \ Bblock \ EGAL(derivee \ ,MUL2(IFfractal_2D_precises__IFfractal_3D_precises_____facteur_des_derivees_numeriques \ ,DERIVATION_PARTIELLE(NORMALISATION_DES_FONCTIONS_A_DERIVER(fonction_origine) \ ,NORMALISATION_DES_FONCTIONS_A_DERIVER(fonction_extremite) \ ,DOUB(pas_du_maillage) \ ) \ ) \ ); \ Eblock \ /* Calcul de la derivee numerique d'une fonction, la variable de derivation 't', etant */ \ /* celle qui est definie dans les formules d'interpolation ci-dessus ; on notera que */ \ /* jusqu'au 1995120800 la fonction 'DERIVATION_PARTIELLE(...)' etait utilisee avec comme */ \ /* "amplitude" de la variable 'DOUB(AMPLITUDE_DU_PARAMETRE_D_INTERPOLATION_CUBIQUE)'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L ' E C H E L L E : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_d_echelle_global,FU))); /* Facteur global d'echelle. */ #define X_facteur_d_echelle \ MUL2(aleat_2_____facteur_d_echelle_global,ASI1(facteur_d_echelle,cx)) #define Y_facteur_d_echelle \ MUL2(aleat_2_____facteur_d_echelle_global,ASI1(facteur_d_echelle,cy)) #define Z_facteur_d_echelle \ MUL2(aleat_2_____facteur_d_echelle_global,ASI1(facteur_d_echelle,cz)) /* Definition des facteurs d'echelle. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E S T I O N D E S T R A N S L A T I O N S S U R U N T O R E : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Logical,ZINT(TRANSLATION_TORIQUE_____compatibilite_20090918,FAUX))); /* Afin d'assurer la compatibilite anterieure au 20090918101134... */ #define DIMENSION_D_UN_TORE(origine,extremite,xyz) \ SOUA(ASD1(extremite,xyz),ASD1(origine,xyz)) \ /* Dimension d'un tore (introduit le 20090918084309). */ #define TRANSLATION_TORIQUE(translation,dxyz,origine,extremite,xyz) \ COND(IL_FAUT(TRANSLATION_TORIQUE_____compatibilite_20090918) \ ,ASD1(translation,dxyz) \ ,COND(IZLE(ASD1(translation,dxyz)) \ ,NEGA(MODF(NEGA(ASD1(translation,dxyz)),FZERO,DIMENSION_D_UN_TORE(origine,extremite,xyz))) \ ,SOUS(MODF(NEUT(ASD1(translation,dxyz)),FZERO,DIMENSION_D_UN_TORE(origine,extremite,xyz)) \ ,DIMENSION_D_UN_TORE(origine,extremite,xyz) \ ) \ ) \ ) \ /* Aux environs du 20090918084309, j'ai decouvert qu'en mode "torique" la translation des */ \ /* champs fonctionnait bien si elle etait negative. Par 'TRANSLATION_TORIQUE(...)' toute */ \ /* translation positive est donc ramenee a une translation negative. En effet, en supposant */ \ /* une translation 'T' (suivant 'OX', 'OY' ou 'OZ') ramenee dans [0,P[ ou 'P' designe la */ \ /* periode (c'es-a-dire la "taille" du tore suivant l'une des directions 'OX', 'OY' ou 'OZ') */ \ /* on a evidemment : */ \ /* */ \ /* T ~ T-P */ \ /* */ \ /* Ce probleme semble venir de la fonction 'Fcalcul_d_un_noeud_relativement_au_centre(...)' */ \ /* sans que cela soit une certitude, mais elle traite de facon dissymetrique la droite et */ \ /* la gauche, en testant d'abord si le noeud est "a droite" du point avant de tester s'il */ \ /* est "a gauche"... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A R E C U R S I V I T E : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Int,ZINT(aleat_2_____premier_niveau_de_recursion_a_utiliser,FIRST_NIVEAU_DE_RECURSION))); /* Premier niveau de recursion a utiliser dans le cumul de calcul de la fonction fractale. */ /* La valeur implicite utilise tout ce qui est calcule. Plus cette valeur sera grande, */ /* moins il y aura de basses frequences... */ #define NIVEAU_DE_RECURSION \ EXP2(SEIZE) DEFV(Common,DEFV(Int,ZINT(aleat_2_____borne_superieure_du_niveau_de_recursion,NIVEAU_DE_RECURSION))); /* Borne superieure du niveau de recursion ; cette valeur est tout a fait */ /* arbitraire, mais on notera que si l'on appelle 'Ifractal_2D' avec une petite */ /* valeur, le champ sera plus "lisse" qu'avec une grande valeur, car alors */ /* en effet, de part la decroissance exponentielle, les derniers termes de */ /* ponderation sont equivalents et voisins de l'UNITE : on rajoute donc beaucoup */ /* de bruit... */ /* */ /* D'autre part, en designant par "modulo" cette variable, elle permet de faire des */ /* zooms autosimilaires. Soit 'E' l'echelle a laquelle le champ est identique a ce qu'il */ /* est a l'echelle 1 (ceci est aussi vrai des echelles n.E, ou 'n' designe un nombre entier */ /* quelconque). Cela signifie que l'on a : */ /* */ /* maille(1) */ /* maille(1+modulo) = ----------- */ /* E */ /* */ /* On verra a ce propos les sequences du type : */ /* */ /* xivPdf 7 2 / 006515_006531 */ /* */ /* qui donnent des exemples d'utilisation... */ #define LAST_NIVEAU_DE_RECURSION \ LSTX(FIRST_NIVEAU_DE_RECURSION,NIVEAU_DE_RECURSION) \ /* Index du dernier element. */ DEFV(Common,DEFV(Int,INIT(aleat_2_____facteur_de_generation_entiere,UNDEF))); /* Ce parametre est conserve, bien qu'inutile, pour des raisons de compatibilite anterieure. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____plus_petite_maille_significative,ADD2(FDEUX,GRO9(FRA10(FU)))))); /* Taille de la maille a partir de laquelle on arrete le processus de reduction. Cette */ /* variable s'appelle ainsi pour des raisons de compatibilite anterieure. En fait, elle */ /* designe maintenant une plus petite taille exprimee en unites denormalisees. ATTENTION, */ /* une valeur trop grande peut creer une bande centrale assez visible... */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____distance_relative_limite_des_mailles,GRO1(FRA10(FU))))); /* "Distance" relative limite entre deux mailles successives en deca de laquelle, on */ /* considere que deux mailles successives sont identiques (donc a 'epsilon pres', 'epsilon */ /* etant 'aleat_2_____distance_relative_limite_des_mailles'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P O U R G E R E R L E S N O M B R E S F L O T T A N T S C O M M E D E S E N T I E R S : */ /* */ /*************************************************************************************************************************************/ #define ARRI_FRACTAL(valeur,epsilon) \ ffARRI(valeur,epsilon) \ /* Fonction d'arrondi des valeurs flottantes. ATTENTION, ces fonctions sont conservees */ \ /* parce que je n'aime pas jeter, mais elles sont rendues neutres car de toute evidence, */ \ /* elles interferent malheureusement avec 'CALCUL_DES_NEUDS_VERSION_02'... */ #define ARRI_FRACTAL_COORDONNEE(valeur) \ NEUT(valeur) \ /* Fonction d'arrondi des coordonnees... */ #define ARRI_FRACTAL_COORDONNEE_NOEUD(valeur) \ NEUT(valeur) \ /* Fonction d'arrondi des coordonnees d'un noeud... */ #define ARRI_FRACTAL_MAILLE(valeur) \ NEUT(valeur) \ /* Fonction d'arrondi des mailles. On notera que j'ai essaye, apres avoir introduit la */ \ /* reduction lineaire, la fonction suivante : */ \ /* */ \ /* ARRI_FRACTAL(...,PUIX(BASE10,FLOT(INTE(MOIT(LO1X(epsilon_de_generation_fractale)))))) */ \ /* */ \ /* mais cela n'a rien ameliore, d'ou le retour a la neutralite... */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____epsilon_de_generation_fractale,PARE(1.0e-08)))); /* Cette definition permet par la suite de travailler sur les nombres flottants comme sur */ /* des nombres entiers, l'unite ('1') etant remplacee par 'epsilon_de_generation_fractale'. */ /* Sans cette operation, faite via 'fARRI(...)', il peut arriver que l'on ne tombe pas sur */ /* les noeuds sur lesquels on souhaiterait tomber lors de 'MOVE_NOEUD(...)' en particulier. */ /* Ainsi, on peut dire que, si 'X' est un nombre flottant, alors le nombre : */ /* */ /* X */ /* --------- */ /* epsilon */ /* */ /* peut etre considere comme un entier... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* U T I L I S A T I O N D E S L I S T E S D E S U B S T I T U T I O N : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Logical,ZINT(IFfractal_____transformer_les_coordonnees_barycentriques,FAUX))); /* Afin de savoir s'il faut transformer par 'TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(...)' */ /* les coordonnees barycentriques ('VRAI') ou pas ('FAUX') via la liste de SUBSTITUTION */ /* courante... */ /* */ /* On notera qu'on utilisera en general simultanement : */ /* */ /* IL_FAUT(IFfractal_____transformer_les_coordonnees_barycentriques) */ /* */ /* et : */ /* */ /* IL_NE_FAUT_PAS(IFfractal_2D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) */ /* IL_NE_FAUT_PAS(IFfractal_3D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) */ /* */ /* mais que cela n'est pas obligatoire... */ #define TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(coordonnee_barycentrique,liste_flottante_approximee_de_substitution) \ SUBSTITUTION_D_UNE_COORDONNEE_BARYCENTRIQUE(coordonnee_barycentrique \ ,IFfractal_____transformer_les_coordonnees_barycentriques \ ,liste_flottante_approximee_de_substitution \ ) \ /* Fonction de transformation des coordonnees barycentriques via la liste de SUBSTITUTION */ \ /* courante... */ DEFV(Common,DEFV(Logical,ZINT(IFfractal_____lissage,FAUX))); /* Afin de savoir s'il faut lisser ('VRAI') ou pas ('FAUX') la liste de SUBSTITUTION */ /* courante lors de sa conversion... */ DEFV(Common,DEFV(Int,ZINT(IFfractal_____nombre_de_passes_de_lissage,UN))); /* Indique alors le nombre de passes de lissage ("plus on lisse, plus c'est lisse..."). */ DEFV(Common,DEFV(Int,ZINT(IFfractal_____PAS_COULEURS_de_lissage,PAS_COULEURS))); /* Pas des couleurs pour les fonctions 'nPREK(...)' et 'nSUCK(...)' lors du lissage. */ DEFV(Local,DEFV(genere_Float,DTb1(liste_flottante_approximee_de_substitution_courante,COULEURS))); /* Cette table contient la liste de SUBSTITUTION courante convertie en 'genere_Float' et */ /* mise dans [COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE], puis */ /* eventuellement lissee par approximation. */ #define liste_de_substitution_X_DANS_IFfractal \ liste_flottante_approximee_de_substitution_ROUGE #define liste_de_substitution_Y_DANS_IFfractal \ liste_flottante_approximee_de_substitution_VERTE #define liste_de_substitution_Z_DANS_IFfractal \ liste_flottante_approximee_de_substitution_BLEUE DEFV(Local,DEFV(genere_Float,DTb1(liste_flottante_approximee_de_substitution_ROUGE,COULEURS))); DEFV(Local,DEFV(genere_Float,DTb1(liste_flottante_approximee_de_substitution_VERTE,COULEURS))); DEFV(Local,DEFV(genere_Float,DTb1(liste_flottante_approximee_de_substitution_BLEUE,COULEURS))); /* Ces trois tables introduites le 19980903140842 vont permettre de transformer les */ /* coordonnees barycentriques (via 'TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(...)') suivant */ /* leur type a l'aide de la correspondance : */ /* */ /* ROUGE --> X */ /* VERTE --> Y */ /* BLEUE --> Z */ /* */ #define PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION(liste_de_SUBSTITUTION,liste_flottante_approximee_de_substitution) \ Bblock \ Test(IFET(IL_FAUT(IFfractal_____transformer_les_coordonnees_barycentriques) \ ,IFET(IZNE(aleat_2_____facteur_de_composante_21_de_la_fonction_generale_de_reduction) \ ,I3OU(IFEQ(num_liste_de_substitution,L_SUBSTITUTION_ROUGE) \ ,IFEQ(num_liste_de_substitution,L_SUBSTITUTION_VERTE) \ ,IFEQ(num_liste_de_substitution,L_SUBSTITUTION_BLEUE) \ ) \ ) \ ) \ ) \ Bblock \ PRINT_ATTENTION("la liste de SUBSTITUTION courante va avoir deux fonctions simultanement"); \ PRINT_ATTENTION("via la 'composante_21' et la transformation des coordonnees barycentriques"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ /* ATTENTION, on n'optimise pas ce qui suit par : */ \ /* */ \ /* Test(IZNE(facteur_de_composante_21_de_la_fonction_generale_de_reduction)) */ \ /* Bblock */ \ /* CONVERSION_FLOTTANTE_D_UNE_LISTE_DE_SUBSTITUTION(...); */ \ /* Eblock */ \ /* ATes */ \ /* Bblock */ \ /* Eblock */ \ /* ETes */ \ /* */ \ /* car, en effet, 'liste_flottante_approximee_de_substitution' doit etre accedee meme dans */ \ /* ce cas via le 'LRZ6(...)' qui ne teste pas la nullite eventuelle des differents facteurs */ \ /* utilises. On risquerait alors de tomber sur des elements initialises avec des valeurs */ \ /* flottantes illicites... */ \ \ PUSH_SUBSTITUTION; \ /* Sauvegarde de la SUBSTITUTION courante. */ \ SUBSTITUTION(liste_de_SUBSTITUTION); \ /* Mise en place de la SUBSTITUTION demandee. */ \ PUSH_FILTRAGE; \ /* Sauvegarde de l'etat courant du filtrage des niveaux. */ \ SET_FILTRAGE(ACTIF); \ /* Et on active le filtrage puisque la fonction 'Nsubstitution(...)' va etre utilisee */ \ /* ci-apres dans 'CONVERSION_FLOTTANTE_D_UNE_LISTE_DE_SUBSTITUTION(...)'. */ \ \ CONVERSION_FLOTTANTE_D_UNE_LISTE_DE_SUBSTITUTION(liste_flottante_approximee_de_substitution \ ,COORDONNEE_BARYCENTRIQUE_MINIMALE \ ,COORDONNEE_BARYCENTRIQUE_MAXIMALE \ ,IFfractal_____lissage \ ,IFfractal_____nombre_de_passes_de_lissage \ ,IFfractal_____PAS_COULEURS_de_lissage \ ); \ \ PULL_FILTRAGE; \ PULL_SUBSTITUTION; \ /* Et restauration des conditions initiales... */ \ Eblock \ /* Preparation d'une liste de SUBSTITUTION au cas ou elle serait necessaire... */ #define PREPARATION_DE_L_UTILISATION_DES_LISTES_DE_SUBSTITUTION \ Bblock \ PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION(num_liste_de_substitution \ ,liste_flottante_approximee_de_substitution_courante \ ); \ /* Preparation de la liste de SUBSTITUTION courante au cas ou elle serait necessaire... */ \ PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION(L_SUBSTITUTION_ROUGE \ ,liste_flottante_approximee_de_substitution_ROUGE \ ); \ PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION(L_SUBSTITUTION_VERTE \ ,liste_flottante_approximee_de_substitution_VERTE \ ); \ PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION(L_SUBSTITUTION_BLEUE \ ,liste_flottante_approximee_de_substitution_BLEUE \ ); \ /* Preparation des trois listes de SUBSTITUTION {ROUGE,VERTE,BLEUE} au cas ou... */ \ Eblock \ /* Preparation de la liste de SUBSTITUTION courante et des trois listes de SUBSTITUTION */ \ /* {ROUGE,VERTE,BLEUE} au cas ou l'une d'entre-elles serait necessaire... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A R E D U C T I O N R E C U R S I V E : */ /* */ /*************************************************************************************************************************************/ #define EPSILON(epsilon) \ MUL2(fonction_generale_de_reduction_____epsilon,epsilon) DEFV(Common,DEFV(Float,ZINT(fonction_generale_de_reduction_____epsilon,FU))); #define INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant) \ MUL2(fonction_generale_de_reduction_____inverse_de_l_exposant,inverse_de_l_exposant) DEFV(Common,DEFV(Float,ZINT(fonction_generale_de_reduction_____inverse_de_l_exposant,FU))); /* Facteurs multiplicatifs de 'epsilon' et de 'inverse_de_l_exposant' dans la fonction */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_01_de_la_fonction_generale_de_reduction,FZERO))); /* Facteurs multiplicatifs de 'COMPOSANTE_01_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_01_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ MUL2(x0 \ ,AXPB(NEGA(EPSILON(epsilon)) \ ,DIVI(FLOT(SOUS(iteration,FIRST_NIVEAU_DE_RECURSION)) \ ,INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant) \ ) \ ,COORDONNEE_BARYCENTRIQUE_MAXIMALE \ ) \ ) \ /* Composante '01' de la fonction generale de reduction : */ \ /* */ \ /* n - 1 */ \ /* X(n) = X(1).(1 - (epsilon.---------)) */ \ /* inverse */ \ /* */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_02_de_la_fonction_generale_de_reduction,FZERO))); /* Facteurs multiplicatifs de 'COMPOSANTE_02_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_02_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ MUL2(x0 \ ,BARY(EPSILON(epsilon) \ ,COORDONNEE_BARYCENTRIQUE_MAXIMALE \ ,PUIX(INVE(INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant)),SOUS(iteration,FIRST_NIVEAU_DE_RECURSION)) \ ) \ ) \ /* Composante '02' de la fonction generale de reduction : */ \ /* */ \ /* 1 1 */ \ /* X(n) = X(1).[------------ + (1 - ------------).epsilon] */ \ /* n-1 n-1 */ \ /* inverse inverse */ \ /* */ \ /* Une solution identique a celle utilisee pour realiser les zooms sur les ensembles du */ \ /* type Mandelbrot a ete employee. Soit 'D' et 'A' es valeur de Depart et d'Arrivee */ \ /* 'K' designe un facteur de reduction. Enfin, 'X(n)' represente la valeur courante. La */ \ /* methode est donc : */ \ /* */ \ /* X(1) = D */ \ /* */ \ /* puis : */ \ /* */ \ /* X(n) = K.X(n) + (1-K).A */ \ /* */ \ /* une manipulation simple utilisant une progression geometrique montre que ('VERSION_03') : */ \ /* */ \ /* n n */ \ /* X(n) = K .D + (1-K ).A */ \ /* */ \ /* d'ou : */ \ /* */ \ /* n n A */ \ /* X(n) = X(1).[K + (1-K ).---] */ \ /* D */ \ /* */ \ /* ce que l'on ecrira : */ \ /* */ \ /* 1 1 */ \ /* X(n) = X(1).[------------ + (1 - ------------).epsilon] */ \ /* n-1 n-1 */ \ /* inverse inverse */ \ /* */ \ /* voir a ce propos le programme 'v $xtc/mailles.02$c'. Une bonne valeur de 'epsilon' est */ \ /* alors : */ \ /* */ \ /* epsilon = 0.01 */ \ /* */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_03_de_la_fonction_generale_de_reduction,FZERO))); /* Facteurs multiplicatifs de 'COMPOSANTE_03_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_03_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ BARY(EPSILON(epsilon) \ ,x0 \ ,PUIX(INVE(INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant)),SOUS(iteration,FIRST_NIVEAU_DE_RECURSION)) \ ) \ /* Composante '03' de la fonction generale de reduction. On notera ici un inconvenient */ \ /* qui est qu'en general 'D' designe la maille de depart qui risque donc d'etre "scalee" */ \ /* par le facteur d'echelle ; or ce n'est pas le cas, malheureusement, de 'A' (c'est-a-dire */ \ /* 'epsilon'). La 'COMPOSANTE_02_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' ne possede pas */ \ /* ce defaut... */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_04_de_la_fonction_generale_de_reduction,FZERO))); /* Facteurs multiplicatifs de 'COMPOSANTE_04_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_04_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ MUL2(x0 \ ,PUIX(INVE(INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant)),SOUS(iteration,FIRST_NIVEAU_DE_RECURSION)) \ ) \ /* Composante '04' de la fonction generale de reduction. On notera ici la propriete */ \ /* suivante : */ \ /* */ \ /* X(n+1) */ \ /* -------- = constante \-/ n */ \ /* X(n) */ \ /* */ \ /* puisque : */ \ /* */ \ /* 1 */ \ /* X(n) = X(1).------------ */ \ /* n-1 */ \ /* inverse */ \ /* */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_11_de_la_fonction_generale_de_reduction,FU))); /* Facteurs multiplicatifs de 'COMPOSANTE_11_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_11_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ MUL2(x0 \ ,PUIX(COND(EST_FAUX(on_est_sur_un_tore) \ ,COMP(EPSILON(epsilon)) \ ,FDU \ ) \ ,DIVI(FLOT(SOUS(iteration,FIRST_NIVEAU_DE_RECURSION)) \ ,COND(EST_FAUX(on_est_sur_un_tore) \ ,MOIT(INVERSE_DE_L_EXPOSANT(inverse_de_l_exposant)) \ ,FU \ ) \ ) \ ) \ ) \ /* Composante '11' de la fonction generale de reduction : */ \ /* */ \ /* 2.(n - 1) */ \ /* ----------- */ \ /* inverse */ \ /* X(n) = X(1).(1 - epsilon) */ \ /* */ \ /* ou lorsqu'on est sur un tore : */ \ /* */ \ /* 1 */ \ /* X(n) = X(1).------- */ \ /* n-1 */ \ /* 2 */ \ /* */ \ /* On notera le 'MOIT(inverse_de_l_exposant)' qui a priori n'est la que pour assurer une */ \ /* pseudo-compatibilite visuelle avec les valeurs numeriques utilisees dans les programmes */ \ /* type 'v $xci/fract_2D.01$K' et qui avaient ete fixees avec les versions anterieures de */ \ /* ce code. Une bonne valeur de 'epsilon' est alors : */ \ /* */ \ /* epsilon = 0.1 */ \ /* */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____facteur_de_composante_21_de_la_fonction_generale_de_reduction,FZERO))); /* Facteurs multiplicatifs de 'COMPOSANTE_21_DE_LA_FONCTION_GENERALE_DE_REDUCTION(...)' */ /* 'FONCTION_GENERALE_DE_REDUCTION(...)'. */ #define COMPOSANTE_21_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ MUL2(x0 \ ,ITb1(liste_flottante_approximee_de_substitution_courante \ ,INDX(TRNP(NIVA(SOUS(iteration,FIRST_NIVEAU_DE_RECURSION))) \ ,NOIR \ ) \ ) \ ) \ /* Composante '21' de la fonction generale de reduction : */ \ /* */ \ /* X(n) = X(1).Nsubstitution(n) */ \ /* */ \ /* ou 'Nsubstitution(...)' represente "symboliquement" la conversion flottante normalisee */ \ /* dans [COORDONNEE_BARYCENTRIQUE_MINIMALE,COORDONNEE_BARYCENTRIQUE_MAXIMALE] de la liste */ \ /* de SUBSTITUTION courante... */ #define FONCTION_GENERALE_DE_REDUCTION(x0,iteration,inverse_de_l_exposant,epsilon) \ LRZ6(aleat_2_____facteur_de_composante_01_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_01_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ,aleat_2_____facteur_de_composante_02_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_02_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ,aleat_2_____facteur_de_composante_03_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_03_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ,aleat_2_____facteur_de_composante_04_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_04_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ,aleat_2_____facteur_de_composante_11_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_11_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ,aleat_2_____facteur_de_composante_21_de_la_fonction_generale_de_reduction \ ,COMPOSANTE_21_DE_LA_FONCTION_GENERALE_DE_REDUCTION(x0 \ ,iteration \ ,inverse_de_l_exposant \ ,epsilon \ ) \ ) \ /* Fonction generale de reduction. La fonction ici definie permet de calculer l'element */ \ /* 'X(n)' d'une suite dont on se donne le premier element 'X(1)'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A F A C O N D E C A L C U L E R L E S N O E U D S : */ /* */ /*************************************************************************************************************************************/ #nodefine CALCUL_DES_NEUDS_VERSION_01 \ /* Methode calculant le noeud voisin d'un point donne a partir de ce point par une division */ \ /* et une sorte d'arrondi... */ #define CALCUL_DES_NEUDS_VERSION_02 \ /* Methode calculant le noeud voisin d'un point donne en se repositionnant systematiquement */ \ /* par rapport a un point de reference (le centre du champ). */ #ifdef CALCUL_DES_NEUDS_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ DEFV(Common,DEFV(Logical,_____CALCUL_DES_NEUDS_VERSION_01)); #Aifdef CALCUL_DES_NEUDS_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ #Eifdef CALCUL_DES_NEUDS_VERSION_01 /* Common,DEFV(Fonction,) : avec 'VERSION_01'. */ #ifdef CALCUL_DES_NEUDS_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ DEFV(Common,DEFV(Logical,_____CALCUL_DES_NEUDS_VERSION_02)); #Aifdef CALCUL_DES_NEUDS_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ #Eifdef CALCUL_DES_NEUDS_VERSION_02 /* Common,DEFV(Fonction,) : avec 'VERSION_02'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L D E S N O E U D S : */ /* */ /*************************************************************************************************************************************/ #ifdef CALCUL_DES_NEUDS_VERSION_01 # define CALCUL_D_UN_NOEUD(coordonnee_d_un_point,maille,coordonnee_du_centre) \ ffMULD(coordonnee_d_un_point,maille) \ /* Calcul du noeud voisin d'un point donne en fonction de la maille. On notera l'argument */ \ /* 'coordonnee_du_centre' non utilise en 'CALCUL_DES_NEUDS_VERSION_01', mais present malgre */ \ /* tout afin que le nombre d'arguments de 'CALCUL_D_UN_NOEUD(...)' soit toujours le meme... */ #Aifdef CALCUL_DES_NEUDS_VERSION_01 #Eifdef CALCUL_DES_NEUDS_VERSION_01 #ifdef CALCUL_DES_NEUDS_VERSION_02 BFonctionF # define CALCUL_D_UN_NOEUD(coordonnee_d_un_point,maille,coordonnee_du_centre) \ Fcalcul_d_un_noeud_relativement_au_centre(coordonnee_d_un_point,maille,coordonnee_du_centre) \ /* Calcul du noeud voisin d'un point donne en fonction de la maille. */ # define DETECTEUR_DE_BOUCLAGE_DE_Fcalcul_d_un_noeud_relativement_au_centre \ MILLION \ /* Afin de pouvoir detecter les eventuels bouclages de */ \ /* 'Fcalcul_d_un_noeud_relativement_au_centre(...)'. */ DEFV(Common,DEFV(Logical,SINT(Fcalcul_d_un_noeud_relativement_au_centre_____compatibilite_20080925,FAUX))); /* Afin d'assurer la compatibilite anterieure au 20080925163518... */ DEFV(Common,DEFV(Logical,SINT(Fcalcul_d_un_noeud_relativement_au_centre_____editer_message_bouclage_de_calcul_d_un_noeud,VRAI))); /* Faut-il editer le message indiquant que le processus de calcul d'un noeud boucle */ /* ('VRAI') ou pas ('FAUX'). Ceci fut introduit le 20140625123118... */ # define IFLE______compatibilite_20080925(x,a) \ IFOU(IFET(IL_FAUT(Fcalcul_d_un_noeud_relativement_au_centre_____compatibilite_20080925) \ ,IFLE(x,a) \ ) \ ,IFET(IL_NE_FAUT_PAS(Fcalcul_d_un_noeud_relativement_au_centre_____compatibilite_20080925) \ ,FfIFLE(x,a) \ ) \ ) \ /* Test 'IFLE(...)' pour traiter le probleme du 'v $xiii/aleat.2$vv$FON 20080924174528'... */ # define IFGT______compatibilite_20080925(x,a) \ IFOU(IFET(IL_FAUT(Fcalcul_d_un_noeud_relativement_au_centre_____compatibilite_20080925) \ ,IFGT(x,a) \ ) \ ,IFET(IL_NE_FAUT_PAS(Fcalcul_d_un_noeud_relativement_au_centre_____compatibilite_20080925) \ ,FfIFGT(x,a) \ ) \ ) \ /* Test 'IFGT(...)' pour traiter le probleme du 'v $xiii/aleat.2$vv$FON 20080924174528'... */ DEFV(Local,DEFV(FonctionF,Fcalcul_d_un_noeud_relativement_au_centre(coordonnee_d_un_point,maille,coordonnee_du_centre))) DEFV(Argument,DEFV(Float,coordonnee_d_un_point)); /* Coordonnee ('X', 'Y' ou 'Z') du point courant dont on cherche le noeud "voisin", */ DEFV(Argument,DEFV(Float,maille)); /* Maille du reseau auquel appartient ce noeud voisin. */ DEFV(Argument,DEFV(Float,coordonnee_du_centre)); /* Coordonnee ('X', 'Y' ou 'Z') du centre du champ (point de reference absolu). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Int,INIT(detecteur_de_bouclage_de_Fcalcul_d_un_noeud_relativement_au_centre ,DETECTEUR_DE_BOUCLAGE_DE_Fcalcul_d_un_noeud_relativement_au_centre ) ); /* Afin de pouvoir detecter les eventuels bouclages de 'MOVE_NOEUD(...)'. */ DEFV(Float,INIT(coordonnee_du_noeud,coordonnee_du_centre)); /* On se positionne initialement par rapport au centre (c'est-a-dire de facon absolu et */ /* donc independamment du point courant). */ DEFV(Logical,INIT(chercher_le_noeud,VRAI)); /* Indicateur permettant de boucler tant que le noeud cherche n'a pas ete trouve... */ /*..............................................................................................................................*/ Test(IZLE(maille)) Bblock PRINT_ERREUR("lors du calcul d'un noeud par rapport au centre, une maille n'est pas strictement positive"); CAL1(Prer1("maille=%+.17f\n",maille)); Eblock ATes Bblock Eblock ETes Tant(IL_FAUT(chercher_le_noeud)) Bblock Test(IFGT______compatibilite_20080925(coordonnee_du_noeud,coordonnee_d_un_point)) /* Le remplacement de 'IFGT(...)' par 'FfIFGT(...)' est suggere par 'v $xtc/noeud.11$c'... */ Bblock DECR(coordonnee_du_noeud,maille); /* Lorsque le noeud est "a droite" du point, on le deplace a gauche, de facon a le faire */ /* passer, au bout d'un certain nombre de fois, a gauche du point : */ /* */ /* P N */ /* --*-------+---------*----------- */ /* ^ | */ /* | | */ /* ----------------- */ /* -maille */ /* */ /* On notera que cette operation arithmetique n'utilise pas 'coordonnee_d_un_point'... */ Eblock ATes Bblock Test(IFLE______compatibilite_20080925(coordonnee_du_noeud,SOUS(coordonnee_d_un_point,maille))) /* Le remplacement de 'IFLE(...)' par 'FfIFLE(...)' est suggere par 'v $xtc/noeud.11$c'... */ /* ATTENTION, il faut utiliser 'IFLE(...)' et non pas 'IFLT(...)' a cause des points qui */ /* sont sur des neuds strictement "a droite" et qui alors se verraient associes au noeud */ /* immediatement a gauche et non pas au noeud sur lesquels ils sont... */ Bblock INCR(coordonnee_du_noeud,maille); /* Lorsque le noeud est "a gauche" du point decale d'un cran a gauche, on le deplace a */ /* droite de facon a le faire passer, au bout d'un certain nombre de fois, juste a gauche */ /* du point (ou confondu avec lui...) : */ /* */ /* N P-maille P */ /* --*-------+---------*-------+--- */ /* | ^ */ /* | | */ /* ----------------- */ /* +maille */ /* */ /* On notera que cette operation arithmetique n'utilise pas 'coordonnee_d_un_point'... */ Eblock ATes Bblock EGAL(chercher_le_noeud,FAUX); /* On a trouve enfin le noeud. On notera que tout cela n'est peut-etre pas tres optimise, */ /* mais est destine a ne pas faire d'operations arithmetiques utilisant les coordonnees */ /* du point courant. Cela implique que le reseau de noeud ne peut pas varier (a cause des */ /* problemes d'arrondi) d'un instant a l'autre, lorsqu'on l'evalue pour un autre point */ /* courant... */ Eblock ETes Eblock ETes DECR(detecteur_de_bouclage_de_Fcalcul_d_un_noeud_relativement_au_centre,I); Test(IZLT(detecteur_de_bouclage_de_Fcalcul_d_un_noeud_relativement_au_centre)) Bblock Test(IL_FAUT(Fcalcul_d_un_noeud_relativement_au_centre_____editer_message_bouclage_de_calcul_d_un_noeud)) Bblock PRINT_ERREUR("lors du calcul d'un noeud par rapport au centre, le processus boucle"); CAL1(Prer1("coordonnee apres deplacement = %+.17f\n",coordonnee_du_noeud)); CAL1(Prer1("maille...................... = %+.17f\n",maille)); Eblock ATes Bblock Eblock ETes EGAL(chercher_le_noeud,FAUX); /* Et on arrete donc de corriger... */ Eblock ATes Bblock Eblock ETes Eblock ETan RETU(coordonnee_du_noeud); /* Le 20080924174528, je note que les commandes : */ /* */ /* Std */ /* $xci/fract_2D.01$X niveau=1 mx=0.1 my=0.1 graine=1111 ... */ /* */ /* donnent ici pour le point {0,461} les valeurs suivantes (avec le format "%.18f") : */ /* */ /* coordonnee_d_un_point =0.400000000000000022 */ /* - */ /* maille =0.100000000000000006 */ /* coordonnee_du_centre =0.000000000000000000 */ /* coordonnee_du_noeud =0.300000000000000044 */ /* # */ /* */ /* sur {$LACT15,$LACT16}, ce qui est incorrect (puisque le noeud devrait etre en 0.4...), */ /* et : */ /* */ /* coordonnee_d_un_point =0.400000000000000022 */ /* - */ /* maille =0.100000000000000006 */ /* coordonnee_du_centre =0.000000000000000000 */ /* coordonnee_du_noeud =0.400000000000000022 */ /* = */ /* */ /* sur {$LACT18}, ce qui est correct (puisque le noeud est bien en 0.4...). */ /* */ /* Evidemment, d'autres points exhibent ce comportement inexplique a cette date. Peut-etre */ /* la valeur de la maille, contrairement aux apparences, different d'une MACHINE a l'autre ? */ /* */ /* La compilation en mode 'PRAGMA_CL_____MODULE_NON_OPTIMISABLE' de 'v $xbii/aleatoires.2$K' */ /* n'a rien change a ce phenomene. Malgre tout, peut-etre faudrait-il peut-etre utiliser */ /* le 'GooF'... */ /* */ /* Le 20080925130610 ce comportement a ete reproduit grace a 'v $xtc/noeud.01$c' a condition */ /* de le compiler avec '-O2' ou '-O3'. Dans le cas de '-O0' ou '-O1', les resultats obtenus */ /* sur '$LACT18' sont les memes que sur '$LACT15' et sur '$LACT16' et ce, que l'option */ /* '-ffloat-store' soit absente ou presente... */ /* */ /* La solution fut trouvee le 20080925163518 grace a 'v $xtc/noeud.11$c'... */ Eblock # undef IFLE______compatibilite_20080925 # undef IFGT______compatibilite_20080925 # undef DETECTEUR_DE_BOUCLAGE_DE_Fcalcul_d_un_noeud_relativement_au_centre EFonctionF #Aifdef CALCUL_DES_NEUDS_VERSION_02 #Eifdef CALCUL_DES_NEUDS_VERSION_02 /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S M A I L L E S : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____visualiser_les_mailles,FAUX))); /* Cet indicateur permet de visualiser le maillage avec le niveau 'borne_inferieure'. */ DEFV(Common,DEFV(Positive,ZINT(aleat_2_____epaisseur_de_visualisation_des_mailles,ZERO))); /* Introduit le 20210604130249 pour permettre l'epaississement du trace des mailles, la */ /* valeur par defaut garantissant la compatibilite anterieure... */ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____visualiser_les_mailles__avec__borne_inferieure,VRAI))); DEFV(Common,DEFV(Float,ZINT(aleat_2_____visualiser_les_mailles__avec__une_valeur_donnee,FLOT__NOIR))); /* L'indicateur 'aleat_2_____visualiser_les_mailles' a ete complete le 20111019100232... */ /* */ /* Malheureusement, je note le 20111019102512 que cela ne marque pas les mailles avec un */ /* numero unique (sauf evidemment s'il n'y a qu'un seul niveau de recursivite). En effet, */ /* les valeurs de 'fonction___au_point_uUvV' et de 'fonction___au_point_uUvVwW' sont forcees */ /* avec 'aleat_2_____visualiser_les_mailles__avec__une_valeur_donnee' sur les mailles, mais */ /* ces valeurs sont cumulees au cours du processus recursif et cette valeur forcee n'est */ /* donc pas celle du champ genere en ces points... */ DEFV(Common,DEFV(Logical,ZINT(aleat_2_____valider_les_mailles,VRAI))); /* Cet indicateur permet de bloquer la validation des mailles, qui en mode "tore" serait */ /* la source d'une avalanche de messages... */ #define VALIDATION_MAILLE_OX \ Bblock \ Test(IFET(IL_FAUT(aleat_2_____valider_les_mailles),EST_VRAI(on_est_sur_un_tore))) \ Bblock \ Test(fNON_DIVISIBLE(DIMENSION_D_UN_TORE(veritable_origine_du_repliement,veritable_extremite_du_repliement,x) \ ,X_maille(niveau) \ ) \ ) \ Bblock \ PRINT_ERREUR("la maille initiale le long de 'OX' ne divise pas la 'longueur' de cet axe"); \ PRINT_ERREUR("le resultat a de fortes chances d'etre mauvais mais, malgre cela, le calcul se poursuit"); \ PRINT_ERREUR("(en particulier, des 'bouclages' lors des deplacements sont possibles)"); \ CAL1(Prer2("axe=(%+.17f,%+.17f)\n" \ ,ASD1(veritable_origine_du_repliement,x) \ ,ASD1(veritable_extremite_du_repliement,x) \ ) \ ); \ CAL1(Prer1("maille=%+.17f\n" \ ,X_maille(niveau) \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Test(IZLE(X_maille(niveau))) \ Bblock \ PRINT_ERREUR("une maille negative ou nulle est apparue sur l'axe 'OX'"); \ CAL1(Prer1("niveau=%d\n",niveau)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* Validation de la maille initiale le long de 'OX'. */ #define VALIDATION_MAILLE_OY \ Bblock \ Test(IFET(IL_FAUT(aleat_2_____valider_les_mailles),EST_VRAI(on_est_sur_un_tore))) \ Bblock \ Test(fNON_DIVISIBLE(DIMENSION_D_UN_TORE(veritable_origine_du_repliement,veritable_extremite_du_repliement,y) \ ,Y_maille(niveau) \ ) \ ) \ Bblock \ PRINT_ERREUR("la maille initiale le long de 'OY' ne divise pas la 'longueur' de cet axe"); \ PRINT_ERREUR("le resultat a de fortes chances d'etre mauvais mais, malgre cela, le calcul se poursuit"); \ CAL1(Prer2("axe=(%+.17f,%+.17f)\n" \ ,ASD1(veritable_origine_du_repliement,y) \ ,ASD1(veritable_extremite_du_repliement,y) \ ) \ ); \ CAL1(Prer1("maille=%+.17f\n" \ ,Y_maille(niveau) \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Test(IZLE(Y_maille(niveau))) \ Bblock \ PRINT_ERREUR("une maille negative ou nulle est apparue sur l'axe 'OY'"); \ CAL1(Prer1("niveau=%d\n",niveau)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* Validation de la maille initiale le long de 'OY'. */ #define VALIDATION_MAILLE_OZ \ Bblock \ Test(IFET(IL_FAUT(aleat_2_____valider_les_mailles),EST_VRAI(on_est_sur_un_tore))) \ Bblock \ Test(fNON_DIVISIBLE(DIMENSION_D_UN_TORE(veritable_origine_du_repliement,veritable_extremite_du_repliement,z) \ ,Z_maille(niveau) \ ) \ ) \ Bblock \ PRINT_ERREUR("la maille initiale le long de 'OZ' ne divise pas la 'longueur' de cet axe"); \ PRINT_ERREUR("le resultat a de fortes chances d'etre mauvais mais, malgre cela, le calcul se poursuit"); \ CAL1(Prer2("axe=(%+.17f,%+.17f)\n" \ ,ASD1(veritable_origine_du_repliement,z) \ ,ASD1(veritable_extremite_du_repliement,z) \ ) \ ); \ CAL1(Prer1("maille=%+.17f\n" \ ,Z_maille(niveau) \ ) \ ); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ATes \ Bblock \ Test(IZLE(Z_maille(niveau))) \ Bblock \ PRINT_ERREUR("une maille negative ou nulle est apparue sur l'axe 'OZ'"); \ CAL1(Prer1("niveau=%d\n",niveau)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ /* Validation de la maille initiale le long de 'OZ'. */ #define VALIDATION_PONDERATION \ Bblock \ Test(IZLE(ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)))) \ Bblock \ PRINT_ERREUR("une ponderation negative ou nulle est apparue"); \ CAL1(Prer1("niveau=%d\n",niveau)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Validation de la ponderation d'un maille. */ %define X_maille(niveau) \ ASD1(ITb1(maille,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)),dx) %define Y_maille(niveau) \ ASD1(ITb1(maille,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)),dy) %define Z_maille(niveau) \ ASD1(ITb1(maille,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)),dz) /* Definition de la maille courante. */ DEFV(Local,DEFV(Float,DTb1(coefficients_de_ponderation,NIVEAU_DE_RECURSION))); /* Liste des coefficients de ponderation pour reduire recursivement la participation */ /* de chaque terme de la suite fractale. On notera la situation 'Local(...)' tres speciale */ /* de 'coefficients_de_ponderation', car, en effet, il est utilise par les deux fonctions */ /* 'IFfractal_2D_precises(...)' et 'Ifractal_2D(...)' ; la solution la plus simple est donc */ /* celle-ci. Pour eviter de le redefinir une seconde fois, cette liste sera aussi utilisee */ /* par 'IFfractal_3D_precises(...)'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E S N O E U D S : */ /* */ /*************************************************************************************************************************************/ %define X_centre_du_champ \ ASD1(centre_du_champ,x) %define Y_centre_du_champ \ ASD1(centre_du_champ,y) %define Z_centre_du_champ \ ASD1(centre_du_champ,z) /* Definition du centre du champ (n'a de sens qu'en 'CALCUL_DES_NEUDS_VERSION_02', mais */ /* est defini systematiquement afin que 'CALCUL_D_UN_NOEUD(...)' possede toujours le meme */ /* nombre d'argument... */ #define X_noeud_courant_du_reseau_a_l_echelle \ ASD1(noeud_courant_du_reseau_a_l_echelle,x) #define Y_noeud_courant_du_reseau_a_l_echelle \ ASD1(noeud_courant_du_reseau_a_l_echelle,y) #define Z_noeud_courant_du_reseau_a_l_echelle \ ASD1(noeud_courant_du_reseau_a_l_echelle,z) /* Definition du noeud courant du reseau a l'echelle. */ %define X_noeud_courant_du_reseau_eventuellement_dilate \ ASD1(noeud_courant_du_reseau_eventuellement_dilate,x) %define Y_noeud_courant_du_reseau_eventuellement_dilate \ ASD1(noeud_courant_du_reseau_eventuellement_dilate,y) %define Z_noeud_courant_du_reseau_eventuellement_dilate \ ASD1(noeud_courant_du_reseau_eventuellement_dilate,z) /* Definition du noeud courant du reseau eventuellement dilate. */ #define X_point_courant_du_reseau_a_l_echelle \ ASD1(point_courant_du_reseau_a_l_echelle,x) #define Y_point_courant_du_reseau_a_l_echelle \ ASD1(point_courant_du_reseau_a_l_echelle,y) #define Z_point_courant_du_reseau_a_l_echelle \ ASD1(point_courant_du_reseau_a_l_echelle,z) /* Definition du point courant du reseau a l'echelle. */ #define X_point_courant_du_reseau_eventuellement_dilate \ ASD1(point_courant_du_reseau_eventuellement_dilate,x) #define Y_point_courant_du_reseau_eventuellement_dilate \ ASD1(point_courant_du_reseau_eventuellement_dilate,y) #define Z_point_courant_du_reseau_eventuellement_dilate \ ASD1(point_courant_du_reseau_eventuellement_dilate,z) /* Definition du point courant du reseau eventuellement dilate. */ #define X_point_courant_du_reseau_minimal \ ASD1(point_courant_du_reseau_minimal,x) #define Y_point_courant_du_reseau_minimal \ ASD1(point_courant_du_reseau_minimal,y) #define Z_point_courant_du_reseau_minimal \ ASD1(point_courant_du_reseau_minimal,z) /* Definition du point courant du reseau minimal. */ #define DETECTEUR_DE_BOUCLAGE_DE_MOVE_NOEUD \ MILLION \ /* Afin de pouvoir detecter les eventuels bouclages de 'MOVE_NOEUD(...)'. */ DEFV(Common,DEFV(Logical,ZINT(MOVE_NOEUD_____editer_message_bouclage_de_calcul_d_un_noeud,VRAI))); /* Faut-il editer le message indiquant que le processus de calcul d'un noeud boucle */ /* ('VRAI') ou pas ('FAUX'). Ceci fut introduit le 20140625123118... */ #define MOVE_NOEUD(type,direction) \ Bblock \ DEFV(Int,INIT(detecteur_de_bouclage_de_MOVE_NOEUD,DETECTEUR_DE_BOUCLAGE_DE_MOVE_NOEUD)); \ /* Afin de pouvoir detecter les eventuels bouclages de 'MOVE_NOEUD(...)'. */ \ DEFV(Float,INIT(coordonnee_avant_le_deplacement,type`noeud_courant_du_reseau_eventuellement_dilate)); \ DEFV(Float,INIT(deplacement_calcule,FLOT__UNDEF)); \ /* Afin de permettre une validation de ce deplacement relativement au reseau... */ \ DEFV(Logical,INIT(corriger_le_deplacement,VRAI)); \ /* Afin de permettre une correction (eventuelle) du deplacement calcule... */ \ DEFV(Float,INIT(correction_du_deplacement,MOIT(type`maille(niveau_modulo)))); \ /* Cette correction de deplacement va s'ajouter au deplacement defini par la maille. On */ \ /* notera la presence de 'MOIT(...)' destine a eviter un probleme que l'on rencontrerait */ \ /* si l'on utilisait directement la maille, a savoir, la possibilite, a cause toujours des */ \ /* problemes d'arrondi de sauter un noeud ; par exemple : */ \ /* */ \ /* /\ "noeud saute" */ \ /* / \ */ \ /* /+0.4\ | */ \ /* \ / \|/ */ \ /* \ / . */ \ /* 0.4 0.8 1.2 */ \ /* --*-----------------*---------------------*------- */ \ /* | ^ */ \ /* | | */ \ /* --------------------------------------- */ \ /* 0.4+0.4 */ \ /* */ \ /* en partant du noeud '0.4' et en prenant une maille de '0.4' (exemple vecu). */ \ \ INCR(type`noeud_courant_du_reseau_eventuellement_dilate,direction(type`maille(niveau_modulo))); \ /* Deplacement, */ \ \ Tant(IL_FAUT(corriger_le_deplacement)) \ /* A priori, malgre les apparences, le dispositif ne peut pas boucler... */ \ Bblock \ EGAL(type`noeud_courant_du_reseau_eventuellement_dilate \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE(type`noeud_courant_du_reseau_eventuellement_dilate) \ ,type`maille(niveau_modulo) \ ,type`centre_du_champ \ ) \ ); \ /* Et ceci afin de rester sur le reseau... */ \ \ EGAL(deplacement_calcule \ ,SOUS(type`noeud_courant_du_reseau_eventuellement_dilate,coordonnee_avant_le_deplacement) \ ); \ /* Deplacement que l'on vient d'effectuer. */ \ Test(IFEQ_a_peu_pres_absolu(deplacement_calcule \ ,direction(type`maille(niveau_modulo)) \ ,FRA4(type`maille(niveau_modulo)) \ ) \ ) \ Bblock \ /* Apparemment, le deplacement calcule est compatible avec le reseau : */ \ EGAL(corriger_le_deplacement,FAUX); \ /* On arrete donc de corriger... */ \ Eblock \ ATes \ Bblock \ /* Apparemment, le deplacement calcule est incompatible avec le reseau : */ \ EGAL(type`noeud_courant_du_reseau_eventuellement_dilate,coordonnee_avant_le_deplacement); \ /* On revient donc sur la position initiale, */ \ INCR(type`noeud_courant_du_reseau_eventuellement_dilate,direction(type`maille(niveau_modulo))); \ INCR(type`noeud_courant_du_reseau_eventuellement_dilate,correction_du_deplacement); \ /* Et on effectue un nouveau deplacement egal a celui qui est demande plus ou moins la */ \ /* la correction... */ \ EGAL(correction_du_deplacement,NEGA(correction_du_deplacement)); \ /* Et preparation d'une eventuelle correction ulterieure... */ \ \ DECR(detecteur_de_bouclage_de_MOVE_NOEUD,I); \ Test(IZLT(detecteur_de_bouclage_de_MOVE_NOEUD)) \ Bblock \ Test(IL_FAUT(MOVE_NOEUD_____editer_message_bouclage_de_calcul_d_un_noeud)) \ Bblock \ PRINT_ERREUR("lors du passage d'un noeud a son voisin, le processus boucle"); \ CAL1(Prer1("coordonnee avant le deplacement = %+.17f\n",coordonnee_avant_le_deplacement)); \ CAL1(Prer1("maille......................... = %+.17f\n" \ ,direction(type`maille(niveau_modulo)) \ ) \ ); \ CAL1(Prer1("correction du deplacement...... = %+.17f\n",correction_du_deplacement)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ EGAL(corriger_le_deplacement,FAUX); \ /* Et on arrete donc de corriger... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ETes \ Eblock \ ETan \ Eblock \ /* Passage d'un noeud a son voisin sur un reseau de pas 'maille(niveau_modulo)' suivant la */ \ /* direction definie par la fonction 'direction(...)'. La plus grande partie de ce code est */ \ /* destinee a garantir que l'on de deplace sur un reseau bien determine, et ce malgre les */ \ /* problemes d'arrondi lors des operations arithmetiques avec les nombres flottants. */ #define NOEUD_APRES(type) \ Bblock \ MOVE_NOEUD(type,NEUT); \ Eblock \ /* Passage d'un noeud a son voisin sur un reseau eventuellement dilate. */ #define NOEUD_AVANT(type) \ Bblock \ MOVE_NOEUD(type,NEGA); \ Eblock \ /* Passage d'un noeud a son voisin sur un reseau eventuellement dilate. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A R E D U C T I O N R E C U R S I V E B I D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Float,ZINT(aleat_2_____X_epsilon_de_reduction_2D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des mailles le long de 'OX'. */ #define REDUCTION_OX(x0) \ ARRI_FRACTAL_MAILLE(FONCTION_GENERALE_DE_REDUCTION(x0 \ ,niveau \ ,X_puissance_de_reduction \ ,aleat_2_____X_epsilon_de_reduction_2D \ ) \ ) \ /* Reduction recursive d'une longueur selon l'axe 'OX'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Y_epsilon_de_reduction_2D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des mailles le long de 'OY'. */ #define REDUCTION_OY(y0) \ ARRI_FRACTAL_MAILLE(FONCTION_GENERALE_DE_REDUCTION(y0 \ ,niveau \ ,Y_puissance_de_reduction \ ,aleat_2_____Y_epsilon_de_reduction_2D \ ) \ ) \ /* Reduction recursive d'une longueur selon l'axe 'OY'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____P_epsilon_de_reduction_2D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des ponderation des mailles. */ #define REDUCTION_PONDERATION(p0) \ FONCTION_GENERALE_DE_REDUCTION(p0 \ ,niveau \ ,P_puissance_de_reduction \ ,aleat_2_____P_epsilon_de_reduction_2D \ ) \ /* Reduction recursive d'une ponderation. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M I S E S U R U N T O R E : */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Local,DEFV(FonctionF,Fmise_sur_un_tore(coordonnee,origine_du_tore,extremite_du_tore,on_est_sur_un_tore))) DEFV(Argument,DEFV(Float,coordonnee)); /* Coordonnee ('X', 'Y' ou 'Z') que l'on veut simuler sur un tore... */ DEFV(Argument,DEFV(Float,origine_du_tore)); /* Definition de la valeur de la coordonnee minimale sur le tore, */ DEFV(Argument,DEFV(Float,extremite_du_tore)); /* Definition de la valeur de la coordonnee maximale sur le tore. */ DEFV(Argument,DEFV(Logical,on_est_sur_un_tore)); /* Cet indicateur precise si l'on est sur un tore ('VRAI') ou pas ('FAUX') ; dans */ /* ce dernier cas au moins un des couples (origine,extremite) pour l'une des */ /* coordonnees est different de (TORE_PLAT_INFERIEUR,TORE_PLAT_SUPERIEUR). */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock /*..............................................................................................................................*/ RETU(COND(EST_FAUX(on_est_sur_un_tore) ,coordonnee ,ARRI_FRACTAL_COORDONNEE(MODF(coordonnee,origine_du_tore,extremite_du_tore)) ) ); Eblock EFonctionF /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S F O R M A T I O N S G E O M E T R I Q U E S B I D I M E N S I O N N E L L E S : */ /* */ /* */ /* Note sur les 'TRANSFORMATION_GEOMETRIQUE_3D_F?' : */ /* */ /* Grace aux 'TRANSFORMATION_GEOMETRIQUE_3D_F?', */ /* et en particulier aux 'ROTATION_*' qu'elles */ /* permettent, il est possible de faire tourner */ /* de facon continue le champ fractal genere. */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Float,ZINT(aleat_2_____X_translation1_2D,FZERO))); /* Parametre definissant la premiere translation du reseau le long de 'OX'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Y_translation1_2D,FZERO))); /* Parametre definissant la premiere translation du reseau le long de 'OY'. */ #define TRANSFORMATION_OX(x,y,fx,fy,translation) \ AXPB(INVE(fx) \ ,TRANSFORMATION_GEOMETRIQUE_3D_Fx(x \ ,y \ ,FZERO \ ,aleat_2_____X_translation1_2D \ ) \ ,ASD1(translation,dx) \ ) \ /* Transformation de la coordonnee 'x' le long de l'axe 'OX'. */ #define TRANSFORMATION_OY(x,y,fx,fy,translation) \ AXPB(INVE(fy) \ ,TRANSFORMATION_GEOMETRIQUE_3D_Fy(x \ ,y \ ,FZERO \ ,aleat_2_____Y_translation1_2D \ ) \ ,ASD1(translation,dy) \ ) \ /* Transformation de la coordonnee 'y' le long de l'axe 'OY'. */ #define REPLIEMENT_OX(Cx,Cy) \ Fmise_sur_un_tore(Cx \ ,ASD1(veritable_origine_du_repliement,x) \ ,ASD1(veritable_extremite_du_repliement,x) \ ,on_est_sur_un_tore \ ) \ /* Definition du repliement de la coordonnee 'Cx' le long de l'axe 'OX'. */ #define REPLIEMENT_OY(Cx,Cy) \ Fmise_sur_un_tore(Cy \ ,ASD1(veritable_origine_du_repliement,y) \ ,ASD1(veritable_extremite_du_repliement,y) \ ,on_est_sur_un_tore \ ) \ /* Definition du repliement de la coordonnee 'Cy' le long de l'axe 'OY'. */ #define REPLIEMENT_2D(noeud2,noeud1) \ Bblock \ INITIALISATION_POINT_2D(noeud2 \ ,REPLIEMENT_OX(ASD1(noeud1,x),ASD1(noeud1,y)) \ ,REPLIEMENT_OY(ASD1(noeud1,x),ASD1(noeud1,y)) \ ); \ Eblock \ /* Definition du repliement bi-dimensionnel d'un 'noeud1' sur un 'noeud2'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T E U R A L E A T O I R E B I D I M E N S I O N N E L : */ /* */ /*************************************************************************************************************************************/ #define CONVERSION_NIVEAU_RDN(niveau) \ ADD2(borne_inferieure \ ,SCAL(NIVR(niveau) \ ,NIVR(BLANC) \ ,SOUS(borne_superieure,borne_inferieure) \ ) \ ) \ /* Conversion d'un niveau de la "source" en une fausse valeur aleatoire... */ #define RDN_FRACTAL_2D(noeud_courant) \ COND(EST_FAUX(il_y_a_une_source_aleatoire) \ ,rdnF2D_etendu(ADRESSE(noeud_courant) \ ,OUEX(graine,niveau_modulo) \ ,RDN_GENERE \ ,FLOT__ARGUMENT_ABSENT \ ,FLOT__ARGUMENT_ABSENT \ ) \ ,CONVERSION_NIVEAU_RDN(load_point_valide(source_aleatoire \ ,_cDENORMALISE_OX(ASD1(noeud_courant,x)) \ ,_cDENORMALISE_OY(ASD1(noeud_courant,y)) \ ) \ ) \ ) \ /* Calcul d'une valeur aleatoire fonction de : */ \ /* */ \ /* 1 - le noeud courant, */ \ /* 2 - le niveau de recursion courant "modulo", */ \ /* 3 - la graine argument, */ \ /* */ \ /* ou bien utilisant une image comme source aleatoire... */ #define CALCUL_NOEUD_2D_COURANT(valeur_du_noeud,noeud_courant) \ Bblock \ REPLIEMENT_2D(noeud_eventuellement_replie,noeud_courant); \ \ INITIALISATION_POINT_2D(noeud_eventuellement_replie \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE_NOEUD(ASD1(noeud_eventuellement_replie,x)) \ ,X_maille(niveau_modulo) \ ,X_centre_du_champ \ ) \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE_NOEUD(ASD1(noeud_eventuellement_replie,y)) \ ,Y_maille(niveau_modulo) \ ,Y_centre_du_champ \ ) \ ); \ \ EGAL(valeur_du_noeud,RDN_FRACTAL_2D(noeud_eventuellement_replie)); \ \ Test(IL_FAUT(aleat_2_____editer_les_noeuds_et_les_valeurs_aleatoires)) \ Bblock \ CAL3(Prme5("Niveau=%d/%d Noeud=(%+.17f,%+.17f) ValeurAleatoire=%+.17f\n" \ ,niveau \ ,profondeur \ ,ASD1(noeud_eventuellement_replie,x) \ ,ASD1(noeud_eventuellement_replie,y) \ ,valeur_du_noeud \ ) \ ); \ /* Possibilite introduite le 20220111093529... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Calcul de la valeur de la fonction aleatoire au noeud courant. */ #define CALCUL_NOEUD_2D_COURANT_DILATE(valeur_du_noeud) \ Bblock \ CALCUL_NOEUD_2D_COURANT(valeur_du_noeud,noeud_courant_du_reseau_eventuellement_dilate); \ Eblock \ /* Calcul de la valeur de la fonction aleatoire au noeud courant du reseau dilate. */ #define INTERPOLATION_FRACTALE_2D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ COND(IL_FAUT(IFfractal_2D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) \ ,INTERPOLATION_CUBIQUE(fonction_origine,derivee_origine \ ,fonction_extremite,derivee_extremite \ ,lambda \ ) \ ,INTERPOLATION_LINEAIRE(fonction_origine \ ,fonction_extremite \ ,lambda \ ) \ ) #define INTERPOLATION_FRACTALE_2D_X(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ INTERPOLATION_FRACTALE_2D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) #define INTERPOLATION_FRACTALE_2D_Y(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ INTERPOLATION_FRACTALE_2D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) /* Definition de la fonction d'interpolation a utiliser : il s'agit d'une interpolation */ /* cubique, dont on fera le "produit avec elle-meme" pour les 2 et 3 dimensions... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N T R O L E D U C E N T R A G E D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ #define CENTRAGE_FRACTAL_OX(coordonnee) \ COND(IL_FAUT(IFfractal_2D_precises_____centrer_les_coordonnees),CENTRAGE_OX(coordonnee),NEUT(coordonnee)) #define CENTRAGE_FRACTAL_OY(coordonnee) \ COND(IL_FAUT(IFfractal_2D_precises_____centrer_les_coordonnees),CENTRAGE_OY(coordonnee),NEUT(coordonnee)) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O O R D O N N E E S B A R Y C E N T R I Q U E S B I D I M E N S I O N N E L L E S : */ /* */ /*************************************************************************************************************************************/ #define COORDONNEE_U_0(u,v) \ NEUT(u) #define COORDONNEE_1_U(u,v) \ COMP(u) #define COORDONNEE_V_0(u,v) \ NEUT(v) #define COORDONNEE_1_V(u,v) \ COMP(v) /* Definition des coordonnees barycentriques {u,1-u,v,1-v}. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H A M P F R A C T A L " P R E C I S " S P A T I A L E M E N T B I - D I M E N S I O N N E L : */ /* */ /* */ /* *****@@@@@@@*@@@@******.......................................** */ /* ******@@@@****@@*****...............*...**.....................* */ /* *********************........................................... */ /* ******************....... ................................. */ /* ****************........ ...............................* */ /* **********............ ...............*....***....** */ /* ********............ ..............**************** */ /* *******.............. . ............*******.*....**** */ /* ******............... ... .............******........*** */ /* ****........... .... .... ...........*******.*....***** */ /* ***.......... .. .... .....................*.....****** */ /* ****....... ...... .........................****** */ /* .......... ........ ..........................******* */ /* .................... ... ...........................****** */ /* .................... ............. .........******* */ /* ..................... ............ . .......******** */ /* ....................... . .... .... .. .......******.. */ /* ............***........................... ...........**.... */ /* .......................................... .. ............... */ /* ..........********..*..**................... ........ .......... */ /* *****..************************................................. */ /* ********************************.****.****...................... */ /* ********************************************.................... */ /* *******@@@@@@@@@@@*@********@@**************.................... */ /* ***@*@@@@@@*@@@@@@@@@@@@@@@@@@@****************................. */ /* **@@@@@@@@@@*@@@@@@@@@@@@@@@@********************............... */ /* ****@@@@@@@@@@@@@@@@@@@@@@@@@@********************.............. */ /* ******@@@@@@@@@@@@@@@@@@@@@**************************........*** */ /* ****@@@@@@@@@@@@@@@@@@@@@******@@*************@**********...**** */ /* ****@*****@@@@@@@@@@@@@@@@@***@@@@@@@@@************************* */ /* ***********@@@@@@@@@@@@@@***@***@@@@@@@************************@ */ /* ************@@@@@@@@@@@@**********@@@@@@@@@*********@@*******@@@ */ /* */ /* */ /* ou dans sa version periodique... */ /* */ /* */ /* ***@***.*.*....********@**...... ..................***.********* */ /* *********..*******@@********........**..*.... ..*...*.********** */ /* *******..*****..******@******.... ..*....... ....... ..*.....**. */ /* *.**.***....**.****@@@*****... ........ .... . ..........** */ /* ****.*******@******@@@**@**.... .. ........... .....*.*....* */ /* @@@********@@@@@********@**....... . ... .............***..*** */ /* ****@**@@@*@@*************........... .. . .. ..........*...*@ */ /* @@@@@@@@@@@****@**@*****...... .. ...... .. ...........***** */ /* @@@***@*@@**********....*......*..****...... .........******..** */ /* ****.***@*******....*.........***.****.**.******************.*** */ /* *****....******...............**************@*@****************. */ /* ................. ......**..**.****@@@***@****@@********.** */ /* ........*......... .......**********************@************* */ /* .......**.... .............*.****@@******************@@********. */ /* .... . .. . ..........********@********@@@**@**********...* */ /* *........ . .......**@@@@@@@*@@@@@@@@***@******......***** */ /* ....*..... . ....*@*****@*@@@@**@@@@@@@@***********...**.. */ /* .....****.*.... ...*.********@@@@@*@@@@@@*@***.**.**.*....... */ /* .*****************...*******@@*@*@**@***@@*****..**.****.*...... */ /* **********@@*@**********.**@*@****@****.*....*...........**....* */ /* ************@*******.******@@@@*******......*..*........**.***** */ /* *****.*******************@*@@@@@***...... ............********** */ /* *....**.*********************@@*@*..............*.........*..*** */ /* *.************.*.***@***..**@*@*@***........ ...**..... . ...*.. */ /* ****************.**.*************@**..............*............* */ /* *******************...****..******..***.*... .....*.**.......... */ /* .*.*..*****@****************.***********........*..*****.*.**.*. */ /* ..*...*************@@@**********..******..*.......******.*****.. */ /* ..***************************.....*.....*.*....*..*...********** */ /* ..***********.************........*.....***..**......**********. */ /* *********.*...*************.*.....*......*****..*...*******@**** */ /* ******.**.*....**************.......*... .***.*....************* */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Logical,SINT(IFfractal_2D_precises_____compatibilite_20191108,FAUX))); /* Afin d'assurer la compatibilite anterieure au 20191108135531... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_2D_precises_____centrer_les_coordonnees,VRAI))); /* Indicateur controlant le centrage des coordonnees (introduit le 20220113180147), la */ /* valeur par defaut assurant la compatibilite anterieure... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_2D_precises_____valider_les_coordonnees_barycentriques,VRAI))); /* Faut-il valider les coordonnees barycentriques ('VRAI') ou pas ('FAUX'). Ceci fut */ /* introduit le 20140625121516. */ DEFV(Common,DEFV(Logical,SINT(IFfractal_2D_precises_____utiliser_l_INTERPOLATION_CUBIQUE,VRAI))); /* Cet indicateur permet de choisir entre 'INTERPOLATION_CUBIQUE(...)' ('VRAI') et */ /* 'INTERPOLATION_LINEAIRE(...)' ('FAUX') dans 'IFfractal_2D_precises(...)'. */ /* */ /* On notera qu'on utilisera en general simultanement : */ /* */ /* IL_NE_FAUT_PAS(IFfractal_2D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) */ /* */ /* et : */ /* */ /* IL_FAUT(IFfractal_____transformer_les_coordonnees_barycentriques) */ /* */ /* mais que cela n'est pas obligatoire... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_2D_precises_____renormaliser_le_champ_automatiquement,FAUX))); /* Doit-on renormaliser le champ automatiquement ('VRAI') ou pas ('FAUX'). Ceci fut */ /* introduit le 20090307114051. */ DEFV(Common,DEFV(FonctionF,POINTERF(IFfractal_2D_precises(champ_fractal ,X_puissance_de_reduction ,Y_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,ARGUMENT_POINTERs(facteur_d_echelle) ,ARGUMENT_POINTERs(translation2) ,ARGUMENT_POINTERs(origine_du_repliement) ,ARGUMENT_POINTERs(extremite_du_repliement) ,ARGUMENT_POINTERs(maille_initiale) ,il_y_a_une_source_aleatoire ,ARGUMENT_FACULTATIF(source_aleatoire) ) ) ) ) DEFV(Argument,DEFV(imageF,champ_fractal)); /* Image Resultat, telle que : champ_fractal[X][Y]=fractal(X,Y). */ DEFV(Argument,DEFV(Float,X_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OX pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Y_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OY pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,P_puissance_de_reduction)); /* Puissance a laquelle est elevee un coefficient de ponderation pour le reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Int,dernier_niveau_de_recursion_demande)); /* Niveau de recursion demande, c'est-a-dire le nombre de recursions */ /* recursives realisees. */ DEFV(Argument,DEFV(Int,graine)); /* Graine arbitraire dont depend la generation. */ DEFV(Argument,DEFV(Float,borne_inferieure)); /* Borne inferieure du generateur ; 'NOIR' est une bonne valeur. */ DEFV(Argument,DEFV(Float,borne_superieure)); /* Borne superieure du generateur ; 'BLANC' est une bonne valeur. */ DEFV(Argument,DEFV(coeffF_2D,POINTERs(facteur_d_echelle))); /* Facteur d'echelle du champ suivant les deux dimensions. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation2))); /* Translation du champ exprimee dans des unites telles que l'unite represente */ /* respectivement [Xmin,Xmax] et [Ymin,Ymax]. */ DEFV(Argument,DEFV(pointF_2D,POINTERs(origine_du_repliement))); /* Origine du champ afin de pouvoir generer le champ sur un 2D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Voir de plus le commentaire suivant... */ DEFV(Argument,DEFV(pointF_2D,POINTERs(extremite_du_repliement))); /* Extremite du champ afin de pouvoir generer le champ sur un 2D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Mais ATTENTION : lorsque le mode repliement */ /* d'un champ sur un tore, la reduction du maillage ne se fait plus par une */ /* exponentielle (voir 'puissance_de_reduction'), mais par une dichotomie */ /* (divisions par 2 successives) ; de plus, la maille initiale doit etre */ /* une puissance de 2 (pour la dichotomie) et diviser exactement la longueur */ /* du tore (ceci etant valable pour les deux directions 'X' et 'Y' simulta- */ /* nement). */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(maille_initiale))); /* Definition de la maille de base qui sera ensuite reduite recursivement ; elle */ /* est exprime dans des unites telles que l'unite represente */ /* respectivement 'dimX' et 'dimY'. Voir de plus le commentaire precedent. */ /* */ /* ATTENTION, en cas d'utilisation de tres grandes valeurs (par rapport a 1) pour la */ /* maille initiale, il pourra etre necessaire d'augmenter correlativement la valeur du */ /* parametre 'rdnF2D_etendu_____extension' defini dans 'v $ximf/aleatoires$FON'. */ DEFV(Argument,DEFV(Logical,il_y_a_une_source_aleatoire)); /* Cet indicateur precise si l'on doit generer les valeurs aleatoires avec un generateur */ /* aleatoire ('FAUX') ou bien en prelevant les valeurs dans une image ('VRAI') dont la */ /* valeur suit. Mais ATTENTION : si l'on se trouve dans les conditions suivantes : */ /* */ /* EST_VRAI(il_y_a_une_source_aleatoire) */ /* */ /* et */ /* */ /* IFEQ(dernier_niveau_de_recursion_demande,FIRST_NIVEAU_DE_RECURSION) */ /* */ /* alors l'image calculee n'est pas renormalisee, ce qui est tres utile lorsque cette */ /* fonction est utilisee pour un lissage... */ DEFV(Argument,DEFV(image,source_aleatoire)); /* Image dans laquelle prendre les valeurs aleatoires ; son acces est conditionne par */ /* la valeur de la variable de controle 'il_y_a_une_source_aleatoire'. */ /* */ /* A la date du 20081123110627, la "source_aleatoire" ne semble pas fonctionner comme on */ /* pourrait le croire. Ainsi : */ /* */ /* $xci/fract_2D.01$X niveau=1 source=VRAI S=$BLANC lineaire=VRAI (...) */ /* */ /* ne donne pas une image uniforme de valeur '$BLANC', loin s'en faut. En fait, le probleme */ /* semble venir d'un decalage vers le haut a droite de 'source_aleatoire', le reste de */ /* l'image resultante correspondant au niveau 'Niveau____hors_image' utilise via le */ /* 'load_point_valide(...)' via 'RDN_FRACTAL_2D(...)'. En fait, la solution est d'utiliser */ /* la translation 'translation2' avec la valeur : */ /* */ /* translation2={+1/2,+1/2} */ /* */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(on_est_sur_un_tore,FAUX)); /* Cet indicateur precise si l'on est sur un tore ('VRAI') ou pas ('FAUX') ; dans */ /* ce dernier cas au moins un des couples (origine,extremite) pour l'une des */ /* coordonnees est different de (TORE_PLAT_INFERIEUR,TORE_PLAT_SUPERIEUR). */ /* */ /* ATTENTION, l'indicateur 'on_est_sur_un_tore' porte simultanement sur les axes 'OX' et */ /* 'OY', meme si un seul d'entre eux est "torique"... */ DEFV(Int,INIT(profondeur ,COND(IL_FAUT(IFfractal_2D_precises_____compatibilite_20191108) ,FIRST_NIVEAU_DE_RECURSION ,PRED(FIRST_NIVEAU_DE_RECURSION) ) ) ); /* Niveau reel de recursion qui sera utilise dans le calcul, tel qu'il n'y ait pas de */ /* mailles plus petites qu'un point. Il est initialise par 'FIRST_NIVEAU_DE_RECURSION' */ /* au cas ou les tests de son calcul seraient toujours faux... */ /* */ /* La nouvelle valeur par defaut introduite le 20191108140604 permet de garantir que l'on */ /* ne fait rien si l'argument 'dernier_niveau_de_recursion_demande' est negatif ou nul... */ DEFV(deltaF_2D,tore_plat_inferieur); DEFV(deltaF_2D,tore_plat_superieur); /* Ceci a ete introduit le 20001229164219 car, en l'absence de ces structures et donc en */ /* utilisant directement les composantes avec lesquelles on les definit, on observait sur */ /* 'SYSTEME_APC_...' ('$LACT14' ou encore '$CMAP27') un curieux phenomene. En effet, meme */ /* si l'on avait, a l'appel de la fonction 'IFfractal_2D_precises(...)' : */ /* */ /* origine_du_repliement = TORE_PLAT_INFERIEUR */ /* extremite_du_repliement = TORE_PLAT_SUPERIEUR */ /* */ /* ou le couple {TORE_PLAT_INFERIEUR,TORE_PLAT_SUPERIEUR} est destine a indiquer que */ /* l'on n'est pas sur un tore, le test ci-apres, destine a positionner l'indicateur */ /* 'on_est_sur_un_tore', determinait, par erreur, que l'on etait malgre tout sur un tore. */ /* L'introduction de ces structures intermediaires a resolu ce probleme... */ DEFV(pointF_2D,veritable_origine_du_repliement); DEFV(pointF_2D,veritable_extremite_du_repliement); /* Origine et extremite du champ reellement utilisees apres mise a l'echelle... */ DEFV(deltaF_2D,translation_neutre); /* Les origine et extremite des tores n'ont pas a etre translatees, de meme que le centre */ /* du champ... */ DEFV(deltaF_2D,translation_dans_le_champ); /* Translation dans le champ. */ DEFV(pointF_2D,centre_du_champ); /* Centre du champ. */ DEFV(pointF_2D,noeud_courant_du_reseau_a_l_echelle); /* Noeud courant du reseau a l'echelle. */ DEFV(pointF_2D,noeud_courant_du_reseau_eventuellement_dilate); /* Noeud courant du reseau eventuellement dilate. */ DEFV(pointF_2D,noeud_eventuellement_replie); /* Noeud obtenu par repliement eventuel du noeud courant du reseau eventuellement dilate. */ DEFV(pointF_2D,barycentre); DEFV(pointF_2D,barycentre_transforme); /* Pour calculer les coordonnees barycentriques d'un point dans une maille et sa version */ /* eventuellement transformee par 'TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(...)'. */ DEFV(deltaF_2D,maille_courante_a_l_echelle); /* Maille courante a l'echelle. */ DEFV(deltaF_2D,DTb1(maille,NIVEAU_DE_RECURSION)); /* Liste des mailles reduites recursivement a partir de 'maille_initiale'. */ DEFV(Float,INIT(ponderation_courante,FLOT__UNDEF)); /* Coefficient courant de ponderation ; il est en fait egale a */ /* l'aire de la maille initiale ; mais il faut noter que sa 'NORMALISATION' */ /* est obligatoire, de facon que la ponderation courante soit superieure */ /* a 1, afin que 'coefficients_de_ponderation' soit une suite decroissante. */ DEFV(Int,INIT(niveau,UNDEF)); /* Niveau de recursion courant. */ DEFV(Float,INIT(fonction___au_noeud_u0v0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=0), */ DEFV(Float,INIT(fonction___au_noeud_u1v0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=0), */ DEFV(Float,INIT(fonction___au_noeud_u0v1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+1), */ DEFV(Float,INIT(fonction___au_noeud_u1v1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+1). */ DEFV(Float,INIT(fonction___au_noeud_u9v0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=0), */ DEFV(Float,INIT(fonction___au_noeud_u2v0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=0), */ DEFV(Float,INIT(fonction___au_noeud_u9v1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=+1), */ DEFV(Float,INIT(fonction___au_noeud_u2v1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=+1). */ DEFV(Float,INIT(fonction___au_noeud_u0v9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=-1), */ DEFV(Float,INIT(fonction___au_noeud_u1v9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=-1), */ DEFV(Float,INIT(fonction___au_noeud_u0v2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+2), */ DEFV(Float,INIT(fonction___au_noeud_u1v2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+2). */ DEFV(Float,INIT(fonction___au_point_uUv0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=0), */ DEFV(Float,INIT(fonction___au_point_uUv1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=+1). */ DEFV(Float,INIT(fonction___au_point_uUvV,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=V). */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=+1), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=+1). */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=+1), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=+1). */ DEFV(Float,INIT(derivee_Dv_au_point_uUv0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=0), */ DEFV(Float,INIT(derivee_Dv_au_point_uUv1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=+1). */ DEFV(Float,INIT(niveau_courant,FLOT__UNDEF)); /* Niveau flottant du point courant. */ /*..............................................................................................................................*/ INITIALISATION_ACCROISSEMENT_2D(tore_plat_inferieur ,_____cNORMALISE_OX(TORE_PLAT_INFERIEUR) ,_____cNORMALISE_OY(TORE_PLAT_INFERIEUR) ); INITIALISATION_ACCROISSEMENT_2D(tore_plat_superieur ,_____cNORMALISE_OX(TORE_PLAT_SUPERIEUR) ,_____cNORMALISE_OY(TORE_PLAT_SUPERIEUR) ); PREPARATION_DE_L_UTILISATION_DES_LISTES_DE_SUBSTITUTION; /* Preparation de la liste de SUBSTITUTION courante et des trois listes de SUBSTITUTION */ /* {ROUGE,VERTE,BLEUE} au cas ou l'une d'entre-elles serait necessaire... */ gTRANSFERT_ACCROISSEMENT_2D(translation_dans_le_champ ,translation2 ,ASD1 ,ASI1 ); /* Translation dans le champ. */ INITIALISATION_ACCROISSEMENT_2D(translation_neutre ,FZERO ,FZERO ); /* Les origine et extremite des tores n'ont pas a etre translatees, de meme que le centre */ /* du champ... */ INITIALISATION_TRANSFORMATION; /* Au cas ou... */ Test(IFOU(IZLE(X_facteur_d_echelle) ,IZLE(Y_facteur_d_echelle) ) ) Bblock PRINT_ERREUR("le facteur d'echelle est incorrect"); Eblock ATes Bblock Eblock ETes Test(IFOU(IFOU(IFGT(ASI1(origine_du_repliement,x),ASD1(tore_plat_inferieur,dx)) ,IFGT(ASI1(origine_du_repliement,y),ASD1(tore_plat_inferieur,dy)) ) ,IFOU(IFLT(ASI1(extremite_du_repliement,x),ASD1(tore_plat_superieur,dx)) ,IFLT(ASI1(extremite_du_repliement,y),ASD1(tore_plat_superieur,dy)) ) ) ) Bblock Test(IFOU(IFGE(ASI1(origine_du_repliement,x),ASI1(extremite_du_repliement,x)) ,IFGE(ASI1(origine_du_repliement,y),ASI1(extremite_du_repliement,y)) ) ) Bblock PRINT_ERREUR("la definition du tore de repliement est incorrecte"); CAL1(Prer2("origine..=(%+.17f,%+.17f)\n" ,ASI1(origine_du_repliement,x),ASI1(origine_du_repliement,y) ) ); CAL1(Prer2("extremite=(%+.17f,%+.17f)\n" ,ASI1(extremite_du_repliement,x),ASI1(extremite_du_repliement,y) ) ); Eblock ATes Bblock EGAL(on_est_sur_un_tore,VRAI); /* Lorsque la definition du tore de repliement est correcte, on l'adopte... */ Eblock ETes Eblock ATes Bblock Eblock ETes Test(EST_FAUX(on_est_sur_un_tore)) Bblock INITIALISATION_POINT_2D(veritable_origine_du_repliement ,ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ); INITIALISATION_POINT_2D(veritable_extremite_du_repliement ,ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ); /* Et mise en place des veritables origine et extremite... */ Eblock ATes Bblock INITIALISATION_POINT_2D(veritable_origine_du_repliement ,TRANSFORMATION_OX(ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ); INITIALISATION_POINT_2D(veritable_extremite_du_repliement ,TRANSFORMATION_OX(ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ); /* Et mise en place des veritables origine et extremite... */ INITIALISATION_ACCROISSEMENT_2D(translation_dans_le_champ ,TRANSLATION_TORIQUE(translation_dans_le_champ,dx ,veritable_origine_du_repliement,veritable_extremite_du_repliement,x ) ,TRANSLATION_TORIQUE(translation_dans_le_champ,dy ,veritable_origine_du_repliement,veritable_extremite_du_repliement,y ) ); /* Aux environs du 20090918084309, j'ai decouvert qu'en mode "torique" la translation des */ /* champs fonctionnait bien si elle etait negative. Par 'TRANSLATION_TORIQUE(...)' toute */ /* translation positive est donc ramenee a une translation negative. Ce probleme semble */ /* venir de la fonction 'Fcalcul_d_un_noeud_relativement_au_centre(...)' sans que cela soit */ /* une certitude... */ Eblock ETes Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme2("tore OX=(%+.17f,%+.17f)\n" ,ASD1(veritable_origine_du_repliement,x),ASD1(veritable_extremite_du_repliement,x) ) ); CAL3(Prme2("tore OY=(%+.17f,%+.17f)\n" ,ASD1(veritable_origine_du_repliement,y),ASD1(veritable_extremite_du_repliement,y) ) ); Eblock ATes Bblock Eblock ETes INITIALISATION_POINT_2D(noeud_courant_du_reseau_eventuellement_dilate,Xmin,Ymin); Test(EST_FAUX(il_y_a_une_source_aleatoire)) Bblock CALS(rdnF2D_etendu(ADRESSE(noeud_courant_du_reseau_eventuellement_dilate) ,UNDEF ,RDN_INIT ,borne_inferieure,borne_superieure ) ); /* Initialisation du generateur aleatoire. */ Eblock ATes Bblock Eblock ETes DoIn(niveau ,FIRST_NIVEAU_DE_RECURSION ,COND(IL_FAUT(IFfractal_2D_precises_____compatibilite_20191108) ,TRON(dernier_niveau_de_recursion_demande,FIRST_NIVEAU_DE_RECURSION,NIVEAU_DE_RECURSION) ,dernier_niveau_de_recursion_demande ) ,I ) /* La modification du 20191108135531 permet de ne pas faire d'iterations et d'alors */ /* renvoyer le champ initial (en general uniforme et meme nul...). */ Bblock INITIALISATION_ACCROISSEMENT_2D(ITb1(maille,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,REDUCTION_OX(ASI1(maille_initiale,dx)) ,REDUCTION_OY(ASI1(maille_initiale,dy)) ); INITIALISATION_ACCROISSEMENT_2D(maille_courante_a_l_echelle ,REDUCTION_OX(MUL2(X_facteur_d_echelle,ASI1(maille_initiale,dx))) ,REDUCTION_OY(MUL2(Y_facteur_d_echelle,ASI1(maille_initiale,dy))) ); /* Puis reduction recursive de la maille. */ EGAL(ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,REDUCTION_PONDERATION(RAC2(MUL2(ASI1(maille_initiale,dx),ASI1(maille_initiale,dy)))) ); /* Generation de la liste des coefficients de ponderation. */ /* */ /* Le 20070227142652, 'PUIX(...,INVE(FLOT(BI_DIMENSIONNEL))' fut remplace par 'RAC2(...)'. */ Test(IFET(IFOU(IFGT(F__lDENORMALISE_OX(ASD1(maille_courante_a_l_echelle,dx)) ,MUL2(aleat_2_____plus_petite_maille_significative,FLOT(INTER_POINT)) ) ,IFGT(F__lDENORMALISE_OY(ASD1(maille_courante_a_l_echelle,dy)) ,MUL2(aleat_2_____plus_petite_maille_significative,FLOT(INTER_POINT)) ) ) ,IFOU(IFEQ(niveau,FIRST_NIVEAU_DE_RECURSION) ,IFET(IFGT(niveau,FIRST_NIVEAU_DE_RECURSION) ,IFOU(IFNE_a_peu_pres_relatif(ASD1(ITb1(maille,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)),dx) ,ASD1(ITb1(maille,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)),dx) ,aleat_2_____distance_relative_limite_des_mailles ) ,IFNE_a_peu_pres_relatif(ASD1(ITb1(maille,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)),dy) ,ASD1(ITb1(maille,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)),dy) ,aleat_2_____distance_relative_limite_des_mailles ) ) ) ) ) ) /* ATTENTION, le test d'arret sur la taille des mailles doit etre fait en coordonnees */ /* ecran ('INTER_POINT') et non pas l'inverse car il faut noter que, par exemple, en mode */ /* 'Pal' ou les images sont rectangulaires, si l'on definit des mailles initiales carrees */ /* c'est-a-dire ayant des valeurs de 'dx' et 'dy' egales, en fait visuellement elles */ /* ne seront pas carrees mais rectangulaires (dans le format 'Pal'), phenomene qui est */ /* completement masque par les coordonnees [0,1] et qui fausse donc le test d'arret... */ /* */ /* ATTENTION, le 19970717141103 'COMPOSANTE_21_DE_LA_FONCTION_GENERALE_DE_REDUCTION' a ete */ /* introduit. Dans ces conditions, avec par exemple '$xiP/complement' il est possible de */ /* tomber sur le test relatif a 'distance_relative_limite_des_mailles' des la premiere */ /* maille. Dans ce cas, 'profondeur' peut s'arreter a 'FIRST_NIVEAU_DE_RECURSION'... */ Bblock EGAL(profondeur,niveau); /* On calcule progressivement la valeur de recursion a utiliser reellement. */ VALIDATION_MAILLE_OX; VALIDATION_MAILLE_OY; VALIDATION_PONDERATION; Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme4(" maille(%04d)=%+.17fx(%+.17f,%+.17f)" ,niveau ,ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,X_maille(niveau),Y_maille(niveau) ) ); Test(IFGT(niveau,FIRST_NIVEAU_DE_RECURSION)) Bblock CAL3(Prme3(" maille(%04d)/maille(%04d)=%+.17f" ,NEUT(niveau) ,PRED(niveau) ,DIVI(ITb1(coefficients_de_ponderation,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)) ,ITb1(coefficients_de_ponderation,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)) ) ) ); Eblock ATes Bblock Eblock ETes CALS(Fsauts_de_lignes(UN)); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock EDoI Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme1("profondeur=%d\n",profondeur)); /* Edition introduite le 20040107152646... */ Test(IL_FAUT(aleat_2_____aborter_apres_l_edition_des_mailles_et_des_ponderations)) Bblock Abort(OK); /* Sortie tres brutale introduite le 20180708114359 pour gagner du temps lors de tests... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes INITIALISATION_POINT_2D(centre_du_champ ,TRANSFORMATION_OX(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(Xcentre)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Ycentre)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(Xcentre)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Ycentre)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_neutre ) ); /* Ce calcul est effectue systematiquement, alors qu'il n'a de sens que pour le calcul des */ /* noeuds 'CALCUL_DES_NEUDS_VERSION_02', afin de simplifier 'CALCUL_D_UN_NOEUD(...)' qui, */ /* sinon, n'aurait pas le meme nombre d'arguments d'une version a l'autre... */ begin_image Bblock DEFV(pointF_2D,point_courant_du_reseau_a_l_echelle); /* Point courant du reseau a l'echelle. */ DEFV(pointF_2D,point_courant_du_reseau_eventuellement_dilate); /* Point courant du reseau eventuellement dilate. */ Test(IL_FAUT(IFfractal_2D_precises_____compatibilite_20191108)) Bblock CLIR(niveau_courant); /* Nettoyage du cumul pour le point courant. */ Eblock ATes Bblock EGAL(niveau_courant,loadF_point(champ_fractal,X,Y)); /* Ceci permet de recuperer la valeur initiale du champ dans le cas ou il n'y a pas */ /* d'iterations (introduit le 20191108155047)... */ Eblock ETes INITIALISATION_POINT_2D(point_courant_du_reseau_a_l_echelle ,TRANSFORMATION_OX(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(X)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Y)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_dans_le_champ ) ,TRANSFORMATION_OY(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(X)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Y)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,translation_dans_le_champ ) ); EGAL(X_point_courant_du_reseau_a_l_echelle,ARRI_FRACTAL_COORDONNEE(X_point_courant_du_reseau_a_l_echelle)); EGAL(Y_point_courant_du_reseau_a_l_echelle,ARRI_FRACTAL_COORDONNEE(Y_point_courant_du_reseau_a_l_echelle)); /* Et ce afin d'eviter des problemes de calcul. En procedant ainsi, on manipule les */ /* nombres flottats comme des nombres entiers dont l'unite ('1') ne serait plus '1' */ /* mais 'aleat_2_____epsilon_de_generation_fractale'... */ DoIn(niveau,aleat_2_____premier_niveau_de_recursion_a_utiliser,profondeur,I) Bblock DEFV(Int,INIT(niveau_modulo,MODS(niveau,FIRST_NIVEAU_DE_RECURSION,aleat_2_____borne_superieure_du_niveau_de_recursion))); /* Pour assurer l'interpolation d'echelle via les niveaux generes... */ INITIALISATION_POINT_2D(noeud_courant_du_reseau_a_l_echelle ,CALCUL_D_UN_NOEUD(X_point_courant_du_reseau_a_l_echelle,X_maille(niveau),X_centre_du_champ) ,CALCUL_D_UN_NOEUD(Y_point_courant_du_reseau_a_l_echelle,Y_maille(niveau),Y_centre_du_champ) ); /* Noeud courant du reseau avant "arrondi fractal". */ Test(IFEQ(niveau,niveau_modulo)) Bblock TRANSFERT_POINT_2D(point_courant_du_reseau_eventuellement_dilate,point_courant_du_reseau_a_l_echelle); /* Lorsque le 'niveau' et le 'niveau_modulo' coincident, le point courant et le point */ /* courant a l'echelle coincident aussi... */ TRANSFERT_POINT_2D(noeud_courant_du_reseau_eventuellement_dilate,noeud_courant_du_reseau_a_l_echelle); /* Lorsque le 'niveau' et le 'niveau_modulo' coincident, le noeud courant et le noeud */ /* courant a l'echelle coincident aussi... */ Eblock ATes Bblock INITIALISATION_POINT_2D(point_courant_du_reseau_eventuellement_dilate ,ARRI_FRACTAL_COORDONNEE(SCAL(X_point_courant_du_reseau_a_l_echelle ,X_maille(niveau) ,X_maille(niveau_modulo) ) ) ,ARRI_FRACTAL_COORDONNEE(SCAL(Y_point_courant_du_reseau_a_l_echelle ,Y_maille(niveau) ,Y_maille(niveau_modulo) ) ) ); /* Point courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'point_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ INITIALISATION_POINT_2D(noeud_courant_du_reseau_eventuellement_dilate ,CALCUL_D_UN_NOEUD(X_point_courant_du_reseau_eventuellement_dilate ,X_maille(niveau_modulo) ,X_centre_du_champ ) ,CALCUL_D_UN_NOEUD(Y_point_courant_du_reseau_eventuellement_dilate ,Y_maille(niveau_modulo) ,Y_centre_du_champ ) ); /* Noeud courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'noeud_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ Eblock ETes INITIALISATION_POINT_2D(barycentre ,DIVI(SOUS(X_point_courant_du_reseau_eventuellement_dilate ,X_noeud_courant_du_reseau_eventuellement_dilate ) ,X_maille(niveau_modulo) ) ,DIVI(SOUS(Y_point_courant_du_reseau_eventuellement_dilate ,Y_noeud_courant_du_reseau_eventuellement_dilate ) ,Y_maille(niveau_modulo) ) ); /* Calcul des coordonnees barycentriques (u,v) alias {ASD1(barycentre,x),ASD1(barycentre,y)} */ /* du point {X,Y} courant par rapport a la maille courante ; on n'oubliera pas */ /* que : */ /* */ /* [(1-u)*(1-v)] */ /* +[u*(1-v)] */ /* +[u*v] */ /* +[(1-u)*v] = 1. */ /* */ /* ATTENTION, on notera que le barycentre est evalue avant de faire l'"arrondi fractal" afin */ /* d'evaluer correctement la distance (par 'SOUS(...)') entre le point courant et le noeud */ /* courant. En effet, sinon, etant donne que 'ARRI_FRACTAL_COORDONNEE(...)' travaille par */ /* defaut, elle a tendance a eloigner artificiellement le noeud du point courant ; donc, */ /* dans certains cas, cela peut donner des coordonnees barycentriques superieures a 1. */ /* Enfin, cela fait que le barycentre est evalue systematiquement et donc meme s'il n'est */ /* pas utile par la suite... */ INITIALISATION_POINT_2D(barycentre_transforme ,TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(ASD1(barycentre,x) ,liste_de_substitution_X_DANS_IFfractal ) ,TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(ASD1(barycentre,y) ,liste_de_substitution_Y_DANS_IFfractal ) ); /* Et transformation eventuelle... */ INITIALISATION_POINT_2D(noeud_courant_du_reseau_a_l_echelle ,ARRI_FRACTAL_COORDONNEE(X_noeud_courant_du_reseau_a_l_echelle) ,ARRI_FRACTAL_COORDONNEE(Y_noeud_courant_du_reseau_a_l_echelle) ); /* Noeud courant du reseau apres "arrondi fractal". Cette operation doit imperativement */ /* etre effectuee ici, et non pas dans le test sur le niveau qui precede car, en effet, */ /* le calcul du barycentre demande un noeud courant n'ayant pas subi encore l'"arrondi */ /* fractal", or le noeud courant du reseau a l'echelle a pu servir a initialiser le noeud */ /* courant du reseau eventuellement dilate (voir le test qui precede...). */ INITIALISATION_POINT_2D(noeud_courant_du_reseau_eventuellement_dilate ,ARRI_FRACTAL_COORDONNEE(X_noeud_courant_du_reseau_eventuellement_dilate) ,ARRI_FRACTAL_COORDONNEE(Y_noeud_courant_du_reseau_eventuellement_dilate) ); /* Noeud courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'noeud_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ Test(IL_FAUT(aleat_2_____editer_uniquement_les_noeuds)) Bblock /* Ce test a ete mis ici le 20220114064137 et sorti d'un test identique au test suivant */ /* par symetrie avec ce qui est fait dans 'IFfractal_3D_precises(...)' ou la coordonnee */ /* 'Z' est constante... */ Test(IFET(IFEQ(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,IFEQ(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ) ) Bblock CAL3(Prme4("Niveau=%d/%d Noeud=(%+.17f,%+.17f)\n" ,niveau ,profondeur ,CHOI(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,CHOI(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ) ); /* Possibilite introduite le 20220113172718... */ /* */ /* On notera le 20220113142621 qu'editer ici les deux coordonnees */ /* {X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle} ou bien */ /* {X_noeud_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle} qui sont */ /* egales est un bon moyen de tester les problemes d'homothetie qui se rencontre des que */ /* le format d'image est different d'un carre puissance de 2. Ainsi, par exemple on trouve */ /* (avec les mailles par defauts : {mx=+0.389027431421446,my=+0.3890274314214464}) : */ /* */ /* Puq Pud */ /* */ /* x=-0.389744 y=-0.384615 # x=-0.389744 y=-0.390244 */ /* x=+0.000000 y=-0.384615 # x=+0.000000 y=-0.390244 */ /* x=+0.389744 y=-0.384615 # x=+0.389744 y=-0.390244 */ /* */ /* x=-0.389744 y=+0.000000 = x=-0.389744 y=+0.000000 */ /* x=+0.000000 y=+0.000000 = x=+0.000000 y=+0.000000 */ /* x=+0.389744 y=+0.000000 = x=+0.389744 y=+0.000000 */ /* */ /* x=-0.389744 y=+0.384615 # x=-0.389744 y=+0.390244 */ /* x=+0.000000 y=+0.384615 # x=+0.000000 y=+0.390244 */ /* x=+0.389744 y=+0.384615 # x=+0.389744 y=+0.390244 */ /* */ /* */ /* XYmax 200 200 XYmax 400 400 */ /* */ /* x=-0.388060 y=-0.388060 # x=-0.389027 y=-0.389027 */ /* x=+0.000000 y=-0.388060 # x=+0.000000 y=-0.389027 */ /* x=+0.388060 y=-0.388060 # x=+0.389027 y=-0.389027 */ /* x=-0.388060 y=+0.000000 # x=-0.389027 y=+0.000000 */ /* */ /* x=+0.000000 y=+0.000000 = x=+0.000000 y=+0.000000 */ /* */ /* x=+0.388060 y=+0.000000 # x=+0.389027 y=+0.000000 */ /* x=-0.388060 y=+0.388060 # x=-0.389027 y=+0.389027 */ /* x=+0.000000 y=+0.388060 # x=+0.000000 y=+0.389027 */ /* x=+0.388060 y=+0.388060 # x=+0.389027 y=+0.389027 */ /* */ /* Le 20220114081036 le probleme d'homothetie a ete compris. Tout cela est detaille */ /* dans 'v $xci/fract_2D.01$K 20220114074303'... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Test(IFET(IFEQ(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,IFEQ(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ) ) Bblock CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_point_uUvV); /* Lorsque l'on est exactement sur l'un des noeuds du maillage courant, */ /* il n'y a pas d'interpolation a realiser. */ Eblock ATes Bblock Test(IL_FAUT(IFfractal_2D_precises_____valider_les_coordonnees_barycentriques)) Bblock Test(IFOU(NINCff(COORDONNEE_U_0(ASD1(barycentre,x),ASD1(barycentre,y)) ,COORDONNEE_BARYCENTRIQUE_MINIMALE ,COORDONNEE_BARYCENTRIQUE_MAXIMALE ) ,NINCff(COORDONNEE_V_0(ASD1(barycentre,x),ASD1(barycentre,y)) ,COORDONNEE_BARYCENTRIQUE_MINIMALE ,COORDONNEE_BARYCENTRIQUE_MAXIMALE ) ) ) Bblock PRINT_ERREUR("au moins une des coordonnees barycentriques (u,v) est hors [0,1]"); CAL1(Prer2("point.={%+.17f,%+.17f}\n" ,X_point_courant_du_reseau_a_l_echelle ,Y_point_courant_du_reseau_a_l_echelle ) ); CAL1(Prer2("noeud.={%+.17f,%+.17f}\n" ,X_noeud_courant_du_reseau_a_l_echelle ,Y_noeud_courant_du_reseau_a_l_echelle ) ); CAL1(Prer2("maille={%+.17f,%+.17f}\n" ,X_maille(niveau) ,Y_maille(niveau) ) ); CAL1(Prer2("{u,v}={%+.17f,%+.17f}\n" ,COORDONNEE_U_0(ASD1(barycentre,x),ASD1(barycentre,y)) ,COORDONNEE_V_0(ASD1(barycentre,x),ASD1(barycentre,y)) ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u0v0); NOEUD_APRES(X); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u1v0); NOEUD_APRES(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u1v1); NOEUD_AVANT(X); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u0v1); NOEUD_AVANT(Y); NOEUD_AVANT(X); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u9v0); NOEUD_APRES(X); NOEUD_AVANT(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u0v9); NOEUD_APRES(X); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u1v9); NOEUD_APRES(X); NOEUD_APRES(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u2v0); NOEUD_APRES(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u2v1); NOEUD_AVANT(X); NOEUD_APRES(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u1v2); NOEUD_AVANT(X); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u0v2); NOEUD_AVANT(X); NOEUD_AVANT(Y); CALCUL_NOEUD_2D_COURANT_DILATE(fonction___au_noeud_u9v1); NOEUD_AVANT(Y); NOEUD_APRES(X); /* Calcul des valeurs de la fonction aux noeuds entourant le carre de base, afin de pouvoir */ /* calculer ci-apres les derivees partielles en chacun de ses noeuds par des differences */ /* finies... */ DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v0 ,fonction___au_noeud_u9v0 ,fonction___au_noeud_u1v0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v0 ,fonction___au_noeud_u0v0 ,fonction___au_noeud_u2v0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v1 ,fonction___au_noeud_u0v1 ,fonction___au_noeud_u2v1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v1 ,fonction___au_noeud_u9v1 ,fonction___au_noeud_u1v1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v0 ,fonction___au_noeud_u0v9 ,fonction___au_noeud_u0v1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v0 ,fonction___au_noeud_u1v9 ,fonction___au_noeud_u1v1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v1 ,fonction___au_noeud_u1v0 ,fonction___au_noeud_u1v2 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v1 ,fonction___au_noeud_u0v0 ,fonction___au_noeud_u0v2 ,Y_maille(niveau_modulo) ); /* Calcul des derivees partielles en 'u' et 'v' aux noeuds du carre de base par des */ /* differences finies a l'aide des differentes valeurs aux noeuds du maillage... */ EGAL(derivee_Dv_au_point_uUv0 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v0 ,derivee_Dv_au_noeud_u1v0 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dv_au_point_uUv1 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v1 ,derivee_Dv_au_noeud_u1v1 ,ASD1(barycentre,x) ) ); /* Calcul des derivees partielles en 'u' et 'v' sur les aretes horizontales du carre de */ /* base par des interpolations lineaires a partir des sommets voisins (on notera que l'on */ /* ne peut utiliser d'interpolation cubique, puisqu'on ne connait pas encore les derivees). */ EGAL(fonction___au_point_uUv0 ,INTERPOLATION_FRACTALE_2D_X(fonction___au_noeud_u0v0 ,derivee_Du_au_noeud_u0v0 ,fonction___au_noeud_u1v0 ,derivee_Du_au_noeud_u1v0 ,ASD1(barycentre_transforme,x) ) ); EGAL(fonction___au_point_uUv1 ,INTERPOLATION_FRACTALE_2D_X(fonction___au_noeud_u0v1 ,derivee_Du_au_noeud_u0v1 ,fonction___au_noeud_u1v1 ,derivee_Du_au_noeud_u1v1 ,ASD1(barycentre_transforme,x) ) ); /* Calcul de la valeur de la fonction sur les aretes horizontales du carre de base... */ EGAL(fonction___au_point_uUvV ,INTERPOLATION_FRACTALE_2D_Y(fonction___au_point_uUv0 ,derivee_Dv_au_point_uUv0 ,fonction___au_point_uUv1 ,derivee_Dv_au_point_uUv1 ,ASD1(barycentre_transforme,y) ) ); /* Ordre des interpolations cubiques ('-1' est note '9') : */ /* */ /* */ /* v=2 - - - - - - - -0 2- - - - - - - -1 2- - - - - - - - */ /* | /| (10) (09) |\ | */ /* / \ */ /* | / | | \ | */ /* / \ */ /* | / | | \ | */ /* / \ */ /* | / | | \ | */ /* / [1] \ */ /* |/ | | \| */ /* v=1 9 1- - - - - - - -0 1---------U 1---1 1- - - - - - - -2 1 */ /* | (11) | (03) .(02) | (08) | */ /* | . | */ /* | | . | | */ /* | . | */ /* | | . | | */ /* | [2] U V | */ /* | | . | | */ /* | . | */ /* | (04) | (00) .(01) | (07) | */ /* v=0 9 0- - - - - - - -0 0---------U 0---1 0- - - - - - - -2 0 */ /* |\ | | /| */ /* \ [1] / */ /* | \ | | / | */ /* \ / */ /* | \ | | / | */ /* \ / */ /* | \ | | / | */ /* \ / */ /* | \| (05) (06) |/ | */ /* v=-1 - - - - - - - -0 9- - - - - - - -1 9- - - - - - - - */ /* */ /* u=-1 u=0 u=1 u=2 */ /* */ /* */ /* v ^ */ /* | */ /* | */ /* O----> */ /* u */ /* */ /* (on trouve entre parentheses sous la forme 'mn' le numero d'acces a ce noeud de '00' */ /* -le premier traite- a '11' -le dernier-). */ Eblock ETes Test(IL_FAUT(aleat_2_____visualiser_les_mailles)) Bblock Test(IFOU(IFLE(SOUA(NEUT(_cDENORMALISE_OX(X_point_courant_du_reseau_a_l_echelle)) ,SUCX(_cDENORMALISE_OX(X_noeud_courant_du_reseau_a_l_echelle)) ) ,aleat_2_____epaisseur_de_visualisation_des_mailles ) ,IFLE(SOUA(NEUT(_cDENORMALISE_OY(Y_point_courant_du_reseau_a_l_echelle)) ,SUCY(_cDENORMALISE_OY(Y_noeud_courant_du_reseau_a_l_echelle)) ) ,aleat_2_____epaisseur_de_visualisation_des_mailles ) ) ) /* L'utilisation des fonctions '_?DENORMALISE_O?(...)' est destinee a rendre positif des */ /* tests qui ne le seraient pas, et a cause d'une petite difference "epsilonnesque"... */ /* */ /* ATTENTION, l'utilisation des fonctions 'SUC?(...)' vient du phenomene suivant vu en */ /* editant, par exemple, les abscisses avec les parametres d'appels : */ /* */ /* premier=18 niveau=18 */ /* */ /* avec '$xci/fract_3D.01$X' en mode 'Sud'. On a donc : */ /* */ /* (...) */ /* X=120 point=-8 noeud=-12 */ /* */ /* X=121 point=-7 noeud=-8 */ /* X=122 point=-6 noeud=-8 */ /* X=123 point=-5 noeud=-8 */ /* X=124 point=-4 noeud=-8 */ /* */ /* X=125 point=-3 noeud=-4 */ /* X=126 point=-2 noeud=-4 */ /* X=127 point=-1 noeud=-4 */ /* */ /* X=128 point=+0 noeud=0 */ /* X=129 point=+1 noeud=0 */ /* X=130 point=+2 noeud=0 */ /* X=131 point=+3 noeud=0 */ /* */ /* X=132 point=+4 noeud=+3 */ /* X=133 point=+5 noeud=+3 */ /* X=134 point=+6 noeud=+3 */ /* X=135 point=+7 noeud=+3 */ /* */ /* X=136 point=+8 noeud=+7 */ /* (...) */ /* */ /* ainsi, les mailles ont d'une part toute la meme dimension (ici 4) sauf celle qui precede */ /* l'origine, et d'autre part le premier point d'une maille (par exemple +4) suit le noeud */ /* (par exemple +3), d'ou les fonctions 'SUC?(...)'... */ Bblock EGAL(fonction___au_point_uUvV ,COND(IL_FAUT(aleat_2_____visualiser_les_mailles__avec__borne_inferieure) ,borne_inferieure ,aleat_2_____visualiser_les_mailles__avec__une_valeur_donnee ) ); /* Lorsqu'il faut visualiser le maillage, on force 'borne_inferieure' comme valeur de la */ /* fonction. On notera l'aspect non optimise de cela, puisque la fonction vient d'etre */ /* calculee, et qu'on ignore cette valeur... */ /* */ /* Le 20111019100232 fut introduite la possibilite de visualiser les mailles avec une */ /* valeur donnee unique et arbitraire... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes INCR(niveau_courant ,MUL2(ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,fonction___au_point_uUvV ) ); /* Cumul de la contribution du niveau courant a la fonction fractale... */ Eblock EDoI storeF_point(niveau_courant,champ_fractal,X,Y); /* Et enfin, memorisation de la somme fractale ponderee au point {X,Y}. */ Eblock end_image Test(IL_FAUT(IFfractal_2D_precises_____renormaliser_le_champ_automatiquement)) /* Test introduit le 20090303102818... */ Bblock BDEFV(imageF,champ_fractal_renormalise); /* Champ fractal Resultat renormalise... */ CALS(IFnormalisation_automatique(champ_fractal_renormalise,champ_fractal)); /* Et renormalisation... */ CALS(IFmove(champ_fractal,champ_fractal_renormalise)); EDEFV(imageF,champ_fractal_renormalise); /* Champ fractal Resultat renormalise... */ Eblock ATes Bblock Eblock ETes RETIF(champ_fractal); Eblock EFonctionF #undef COORDONNEE_1_V #undef COORDONNEE_V_0 #undef COORDONNEE_1_U #undef COORDONNEE_U_0 #undef CENTRAGE_FRACTAL_OY #undef CENTRAGE_FRACTAL_OX #undef INTERPOLATION_FRACTALE_2D_Y #undef INTERPOLATION_FRACTALE_2D_X #undef INTERPOLATION_FRACTALE_2D #undef CALCUL_NOEUD_2D_COURANT_DILATE #undef CALCUL_NOEUD_2D_COURANT #undef RDN_FRACTAL_2D #undef REPLIEMENT_2D #undef REPLIEMENT_OY #undef REPLIEMENT_OX #undef TRANSFORMATION_OY #undef TRANSFORMATION_OX #undef REDUCTION_PONDERATION #undef REDUCTION_OY #undef REDUCTION_OX /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H A M P F R A C T A L " S T A N D A R D " S P A T I A L E M E N T B I - D I M E N S I O N N E L : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ifractal_2D(imageR ,X_puissance_de_reduction ,Y_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,ARGUMENT_POINTERs(facteur_d_echelle) ,ARGUMENT_POINTERs(translation2) ,ARGUMENT_POINTERs(origine_du_repliement) ,ARGUMENT_POINTERs(extremite_du_repliement) ,ARGUMENT_POINTERs(maille_initiale) ,il_y_a_une_source_aleatoire ,ARGUMENT_FACULTATIF(source_aleatoire) ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR[X][Y]=fractal(X,Y). */ DEFV(Argument,DEFV(Float,X_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OX pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Y_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OY pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,P_puissance_de_reduction)); /* Puissance a laquelle est elevee un coefficient de ponderation pour le reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Int,dernier_niveau_de_recursion_demande)); /* Niveau de recursion demande, c'est-a-dire le nombre de recursions */ /* recursives realisees. */ DEFV(Argument,DEFV(Int,graine)); /* Graine arbitraire dont depend la generation. */ DEFV(Argument,DEFV(Float,borne_inferieure)); /* Borne inferieure du generateur ; 'NOIR' est une bonne valeur. */ DEFV(Argument,DEFV(Float,borne_superieure)); /* Borne superieure du generateur ; 'BLANC' est une bonne valeur. */ DEFV(Argument,DEFV(coeffF_2D,POINTERs(facteur_d_echelle))); /* Facteur d'echelle du champ suivant les deux dimensions. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation2))); /* Translation du champ exprimee dans des unites telles que l'unite represente */ /* respectivement [Xmin,Xmax] et [Ymin,Ymax]. */ DEFV(Argument,DEFV(pointF_2D,POINTERs(origine_du_repliement))); /* Origine du champ afin de pouvoir generer le champ sur un 2D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Voir de plus le commentaire suivant... */ DEFV(Argument,DEFV(pointF_2D,POINTERs(extremite_du_repliement))); /* Extremite du champ afin de pouvoir generer le champ sur un 2D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Mais ATTENTION : lorsque le mode repliement */ /* d'un champ sur un tore, la reduction du maillage ne se fait plus par une */ /* exponentielle (voir 'puissance_de_reduction'), mais par une dichotomie */ /* (divisions par 2 successives) ; de plus, la maille initiale doit etre */ /* une puissance de 2 (pour la dichotomie) et diviser exactement la longueur */ /* du tore (ceci etant valable pour les deux directions 'X' et 'Y' simulta- */ /* nement). */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(maille_initiale))); /* Definition de la maille de base qui sera ensuite reduite recursivement ; elle */ /* est exprime dans des unites telles que l'unite represente */ /* respectivement 'dimX' et 'dimY'. Voir de plus le commentaire precedent. */ /* */ /* ATTENTION, en cas d'utilisation de tres grandes valeurs (par rapport a 1) pour la */ /* maille initiale, il pourra etre necessaire d'augmenter correlativement la valeur du */ /* parametre 'rdnF2D_etendu_____extension' defini dans 'v $ximf/aleatoires$FON'. */ DEFV(Argument,DEFV(Logical,il_y_a_une_source_aleatoire)); /* Cet indicateur precise si l'on doit generer les valeurs aleatoires avec un generateur */ /* aleatoire ('FAUX') ou bien en prelevant les valeurs dans une image ('VRAI') dont la */ /* valeur suit. Mais ATTENTION : si l'on se trouve dans les conditions suivantes : */ /* */ /* EST_VRAI(il_y_a_une_source_aleatoire) */ /* */ /* et */ /* */ /* IFEQ(dernier_niveau_de_recursion_demande,FIRST_NIVEAU_DE_RECURSION) */ /* */ /* alors l'image calculee n'est pas renormalisee, ce qui est tres utile lorsque cette */ /* fonction est utilisee pour un lissage... */ DEFV(Argument,DEFV(image,source_aleatoire)); /* Image dans laquelle prendre les valeurs aleatoires ; son acces est conditionne par */ /* la valeur de la variable de controle 'il_y_a_une_source_aleatoire'. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock BDEFV(imageF,champ_fractal); /* Champ fractal flottant, tel que : champ[X][Y]=fractal(X,Y). */ /*..............................................................................................................................*/ CALS(IFfractal_2D_precises(champ_fractal ,X_puissance_de_reduction ,Y_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,facteur_d_echelle ,translation2 ,origine_du_repliement ,extremite_du_repliement ,maille_initiale ,il_y_a_une_source_aleatoire ,ARGUMENT_FACULTATIF(source_aleatoire) ) ); /* Generation du champ fractal bidimensionnel avec toute la precision possible... */ Test(IFET(EST_VRAI(il_y_a_une_source_aleatoire) ,IFEQ(dernier_niveau_de_recursion_demande,FIRST_NIVEAU_DE_RECURSION) ) ) Bblock DEFV(genere_Float,INIT(niveau_minimum,FLOT__NIVEAU_UNDEF)); DEFV(genere_Float,INIT(niveau_maximum,FLOT__NIVEAU_UNDEF)); /* Afin de rechercher les niveaux minimal et maximal de 'champ_fractal'. */ CALS(IFnivo_extrema(champ_fractal ,ADRESSE(niveau_minimum) ,ADRESSE(niveau_maximum) ) ); /* Recherche des extrema de 'champ_fractal' : en effet, si l'interpolation bi-cubique est */ /* est utilisee, elle peut introduire des niveaux inferieurs a NOIR ou superieurs a BLANC, */ /* il suffit pour s'en rendre compte de regarder la courbe d'interpolation dans le fichier */ /* 'v $xiii/aleat.2$vv$DEF' pour voir que son extremum peut etre en-dessous du minimum ou */ /* au-dessus dumaximum... */ EGAL(niveau_minimum ,MIN2(niveau_minimum ,MUL2(ITb1(coefficients_de_ponderation,INDX(FIRST_NIVEAU_DE_RECURSION,FIRST_NIVEAU_DE_RECURSION)) ,CONVERSION_NIVEAU_RDN(NOIR) ) ) ); EGAL(niveau_maximum ,MAX2(niveau_maximum ,MUL2(ITb1(coefficients_de_ponderation,INDX(FIRST_NIVEAU_DE_RECURSION,FIRST_NIVEAU_DE_RECURSION)) ,CONVERSION_NIVEAU_RDN(BLANC) ) ) ); /* Enfin, on prend le minimum minimurum et le maximum maximurum... */ CALS(Ifloat_std(imageR,champ_fractal,niveau_minimum,niveau_maximum)); /* Et enfin, conversion du champ flottant en une image sans renormalisation, car en effet, */ /* il s'agit fort probablement d'une operation de lissage... */ Eblock ATes Bblock CALS(Ifloat_std_avec_renormalisation(imageR,champ_fractal)); /* Et enfin, conversion du champ flottant en une image avec renormalisation... */ Eblock ETes EDEFV(imageF,champ_fractal); /* Champ fractal flottant, tel que : champ[X][Y]=fractal(X,Y). */ RETI(imageR); Eblock EFonctionP #undef CONVERSION_NIVEAU_RDN /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N D E L A R E D U C T I O N R E C U R S I V E T R I D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Float,ZINT(aleat_2_____X_epsilon_de_reduction_3D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des mailles le long de 'OX'. */ #define REDUCTION_OX(x0) \ ARRI_FRACTAL_MAILLE(FONCTION_GENERALE_DE_REDUCTION(x0 \ ,niveau \ ,X_puissance_de_reduction \ ,aleat_2_____X_epsilon_de_reduction_3D \ ) \ ) \ /* Reduction recursive d'une longueur selon l'axe 'OX'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Y_epsilon_de_reduction_3D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des mailles le long de 'OY'. */ #define REDUCTION_OY(y0) \ ARRI_FRACTAL_MAILLE(FONCTION_GENERALE_DE_REDUCTION(y0 \ ,niveau \ ,Y_puissance_de_reduction \ ,aleat_2_____Y_epsilon_de_reduction_3D \ ) \ ) \ /* Reduction recursive d'une longueur selon l'axe 'OY'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Z_epsilon_de_reduction_3D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des mailles le long de 'OZ'. */ #define REDUCTION_OZ(z0) \ ARRI_FRACTAL_MAILLE(FONCTION_GENERALE_DE_REDUCTION(z0 \ ,niveau \ ,Z_puissance_de_reduction \ ,aleat_2_____Z_epsilon_de_reduction_3D \ ) \ ) \ /* Reduction recursive d'une longueur selon l'axe 'OZ'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____P_epsilon_de_reduction_3D,GRO1(FRA10(FU))))); /* Parametre definissant la "vitesse" de decroissance des ponderation des mailles. */ #define REDUCTION_PONDERATION(p0) \ FONCTION_GENERALE_DE_REDUCTION(p0 \ ,niveau \ ,P_puissance_de_reduction \ ,aleat_2_____P_epsilon_de_reduction_3D \ ) \ /* Reduction recursive d'une ponderation. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T R A N S F O R M A T I O N S G E O M E T R I Q U E S T R I D I M E N S I O N N E L L E S : */ /* */ /* */ /* Note sur les 'TRANSFORMATION_GEOMETRIQUE_3D_F?' : */ /* */ /* Grace aux 'TRANSFORMATION_GEOMETRIQUE_3D_F?', */ /* et en particulier aux 'ROTATION_*' qu'elles */ /* permettent, il est possible de faire tourner */ /* de facon continue le champ fractal genere. */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Float,ZINT(aleat_2_____X_translation1_3D,FZERO))); /* Parametre definissant la premiere translation du reseau le long de 'OX'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Y_translation1_3D,FZERO))); /* Parametre definissant la premiere translation du reseau le long de 'OY'. */ DEFV(Common,DEFV(Float,ZINT(aleat_2_____Z_translation1_3D,FZERO))); /* Parametre definissant la premiere translation du reseau le long de 'OY'. */ #define TRANSFORMATION_OX(x,y,z,fx,fy,fz,translation) \ AXPB(INVE(fx) \ ,TRANSFORMATION_GEOMETRIQUE_3D_Fx(x \ ,y \ ,z \ ,aleat_2_____X_translation1_3D \ ) \ ,ASD1(translation,dx) \ ) \ /* Transformation de la coordonnee 'x' le long de l'axe 'OX'. */ #define TRANSFORMATION_OY(x,y,z,fx,fy,fz,translation) \ AXPB(INVE(fy) \ ,TRANSFORMATION_GEOMETRIQUE_3D_Fy(x \ ,y \ ,z \ ,aleat_2_____Y_translation1_3D \ ) \ ,ASD1(translation,dy) \ ) \ /* Transformation de la coordonnee 'y' le long de l'axe 'OY'. */ #define TRANSFORMATION_OZ(x,y,z,fx,fy,fz,translation) \ AXPB(INVE(fz) \ ,TRANSFORMATION_GEOMETRIQUE_3D_Fz(x \ ,y \ ,z \ ,aleat_2_____Z_translation1_3D \ ) \ ,ASD1(translation,dz) \ ) \ /* Transformation de la coordonnee 'z' le long de l'axe 'OZ'. */ #define REPLIEMENT_OX(Cx,Cy,Cz) \ Fmise_sur_un_tore(Cx \ ,ASD1(veritable_origine_du_repliement,x) \ ,ASD1(veritable_extremite_du_repliement,x) \ ,on_est_sur_un_tore \ ) \ /* Definition du repliement de la coordonnee 'Cx' le long de l'axe 'OX'. */ #define REPLIEMENT_OY(Cx,Cy,Cz) \ Fmise_sur_un_tore(Cy \ ,ASD1(veritable_origine_du_repliement,y) \ ,ASD1(veritable_extremite_du_repliement,y) \ ,on_est_sur_un_tore \ ) \ /* Definition du repliement de la coordonnee 'Cy' le long de l'axe 'OY'. */ #define REPLIEMENT_OZ(Cx,Cy,Cz) \ Fmise_sur_un_tore(Cz \ ,ASD1(veritable_origine_du_repliement,z) \ ,ASD1(veritable_extremite_du_repliement,z) \ ,on_est_sur_un_tore \ ) \ /* Definition du repliement de la coordonnee 'Cz' le long de l'axe 'OZ'. */ #define REPLIEMENT_3D(noeud2,noeud1) \ Bblock \ INITIALISATION_POINT_3D(noeud2 \ ,REPLIEMENT_OX(ASD1(noeud1,x),ASD1(noeud1,y),ASD1(noeud1,z)) \ ,REPLIEMENT_OY(ASD1(noeud1,x),ASD1(noeud1,y),ASD1(noeud1,z)) \ ,REPLIEMENT_OZ(ASD1(noeud1,x),ASD1(noeud1,y),ASD1(noeud1,z)) \ ); \ Eblock \ /* Definition du repliement tri-dimensionnel d'un 'noeud1' sur un 'noeud2'. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T E U R A L E A T O I R E T R I D I M E N S I O N N E L : */ /* */ /*************************************************************************************************************************************/ #define RDN_FRACTAL_3D(noeud_courant) \ rdnF3D_etendu(ADRESSE(noeud_courant) \ ,OUEX(graine,niveau_modulo) \ ,RDN_GENERE \ ,FLOT__ARGUMENT_ABSENT \ ,FLOT__ARGUMENT_ABSENT \ ) \ /* Calcul d'une valeur aleatoire fonction de : */ \ /* */ \ /* 1 - le noeud courant, */ \ /* 2 - le niveau de recursion courant "modulo", */ \ /* 3 - la graine argument. */ \ /* */ #define CALCUL_NOEUD_3D_COURANT(valeur_du_noeud,noeud_courant) \ Bblock \ REPLIEMENT_3D(noeud_eventuellement_replie,noeud_courant); \ \ INITIALISATION_POINT_3D(noeud_eventuellement_replie \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE_NOEUD(ASD1(noeud_eventuellement_replie,x)) \ ,X_maille(niveau_modulo) \ ,X_centre_du_champ \ ) \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE_NOEUD(ASD1(noeud_eventuellement_replie,y)) \ ,Y_maille(niveau_modulo) \ ,Y_centre_du_champ \ ) \ ,CALCUL_D_UN_NOEUD(ARRI_FRACTAL_COORDONNEE_NOEUD(ASD1(noeud_eventuellement_replie,z)) \ ,Z_maille(niveau_modulo) \ ,Z_centre_du_champ \ ) \ ); \ \ EGAL(valeur_du_noeud,RDN_FRACTAL_3D(noeud_eventuellement_replie)); \ \ Test(IL_FAUT(aleat_2_____editer_les_noeuds_et_les_valeurs_aleatoires)) \ Bblock \ CAL3(Prme6("Niveau=%d/%d Noeud=(%+.17f,%+.17f,%+.17f) ValeurAleatoire=%+.17f\n" \ ,niveau \ ,profondeur \ ,ASD1(noeud_eventuellement_replie,x) \ ,ASD1(noeud_eventuellement_replie,y) \ ,ASD1(noeud_eventuellement_replie,z) \ ,valeur_du_noeud \ ) \ ); \ /* Possibilite introduite le 20220111093529... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Calcul de la valeur de la fonction aleatoire au noeud courant. */ #define CALCUL_NOEUD_3D_COURANT_DILATE(valeur_du_noeud) \ Bblock \ CALCUL_NOEUD_3D_COURANT(valeur_du_noeud,noeud_courant_du_reseau_eventuellement_dilate); \ Eblock \ /* Calcul de la valeur de la fonction aleatoire au noeud courant du reseau dilate. */ #define INTERPOLATION_FRACTALE_3D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ COND(IL_FAUT(IFfractal_3D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) \ ,INTERPOLATION_CUBIQUE(fonction_origine,derivee_origine \ ,fonction_extremite,derivee_extremite \ ,lambda \ ) \ ,INTERPOLATION_LINEAIRE(fonction_origine \ ,fonction_extremite \ ,lambda \ ) \ ) #define INTERPOLATION_FRACTALE_3D_X(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ INTERPOLATION_FRACTALE_3D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) #define INTERPOLATION_FRACTALE_3D_Y(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ INTERPOLATION_FRACTALE_3D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) #define INTERPOLATION_FRACTALE_3D_Z(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) \ INTERPOLATION_FRACTALE_3D(fonction_origine,derivee_origine,fonction_extremite,derivee_extremite,lambda) /* Definition de la fonction d'interpolation a utiliser : il s'agit d'une interpolation */ /* cubique, dont on fera le "produit avec elle-meme" pour les 2 et 3 dimensions... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O N T R O L E D U C E N T R A G E D E S C O O R D O N N E E S : */ /* */ /*************************************************************************************************************************************/ #define CENTRAGE_FRACTAL_OX(coordonnee) \ COND(IL_FAUT(IFfractal_3D_precises_____centrer_les_coordonnees),CENTRAGE_OX(coordonnee),NEUT(coordonnee)) #define CENTRAGE_FRACTAL_OY(coordonnee) \ COND(IL_FAUT(IFfractal_3D_precises_____centrer_les_coordonnees),CENTRAGE_OY(coordonnee),NEUT(coordonnee)) #define CENTRAGE_FRACTAL_OZ(coordonnee) \ COND(IL_FAUT(IFfractal_3D_precises_____centrer_les_coordonnees),CENTRAGE_OZ(coordonnee),NEUT(coordonnee)) /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C O O R D O N N E E S B A R Y C E N T R I Q U E S T R I D I M E N S I O N N E L L E S : */ /* */ /*************************************************************************************************************************************/ #define COORDONNEE_U_0(u,v,w) \ NEUT(u) #define COORDONNEE_1_U(u,v,w) \ COMP(u) #define COORDONNEE_V_0(u,v,w) \ NEUT(v) #define COORDONNEE_1_V(u,v,w) \ COMP(v) #define COORDONNEE_W_0(u,v,w) \ NEUT(w) #define COORDONNEE_1_W(u,v,w) \ COMP(w) /* Definition des coordonnees barycentriques {u,1-u,v,1-v,w,1-w}. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H A M P F R A C T A L " P R E C I S " S P A T I A L E M E N T T R I - D I M E N S I O N N E L */ /* O U S P A T I A L E M E N T B I - D I M E N S I O N N E L E T V A R I A B L E D A N S L E T E M P S : */ /* */ /* */ /* . . . */ /* */ /* . . . */ /* */ /* Z+3*pZ ----------------------------------------------------------------- ------* */ /* | | * pZ (pas) */ /* Z+2*pZ ---------------------------------------------------------------- | --* */ /* | | | */ /* Z+1*pZ --------------------------------------------------------------- | | */ /* | | | | */ /* Z+0*pZ -------------------------------------------------------------- | | | */ /* |*****@@@@****@@*****...............*...**.....................| | | | */ /* |********************..........................................| | | | */ /* |*****************....... ................................| | | | */ /* |***************........ ...............................| | | | */ /* |*********............ ...............*....***....*| | | | */ /* |*******............ ..............***************| | | | */ /* |******.............. . ............*******.*....***| | | | */ /* |*****............... ... .............******........**| | | | */ /* |***........... .... .... ...........*******.*....****| | | | */ /* |**.......... .. .... .....................*.....*****| | | | */ /* |***....... ...... .........................*****| | | | */ /* |......... ........ ..........................******| | | | */ /* |................... ... ...........................*****| | | | */ /* |................... ............. .........******| | | | */ /* |.................... ............ . .......*******| | | | */ /* |...................... . .... .... .. .......******.| | | | */ /* |...........***........................... ...........**...| | | | */ /* |......................................... .. ..............| | | | */ /* |.........********..*..**................... ........ .........| | | | */ /* |****..************************................................| | | | */ /* |*******************************.****.****.....................| | | | . */ /* |*******************************************...................| | | | */ /* |******@@@@@@@@@@@*@********@@**************...................| | | | . */ /* |**@*@@@@@@*@@@@@@@@@@@@@@@@@@@****************................| | | | */ /* |*@@@@@@@@@@*@@@@@@@@@@@@@@@@********************..............| | |--- */ /* |***@@@@@@@@@@@@@@@@@@@@@@@@@@********************.............| | | */ /* |*****@@@@@@@@@@@@@@@@@@@@@**************************........**| |--- */ /* |***@@@@@@@@@@@@@@@@@@@@@******@@*************@**********...***| | */ /* |***@*****@@@@@@@@@@@@@@@@@***@@@@@@@@@************************|--- */ /* |**********@@@@@@@@@@@@@@***@***@@@@@@@************************| */ /* -------------------------------------------------------------- */ /* */ /* */ /* comme pour la version bi-dimensionnelle, il existe une version periodique... */ /* */ /*************************************************************************************************************************************/ BFonctionF DEFV(Common,DEFV(Logical,SINT(IFfractal_3D_precises_____compatibilite_20191108,FAUX))); /* Afin d'assurer la compatibilite anterieure au 20191108135531... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_3D_precises_____centrer_les_coordonnees,VRAI))); /* Indicateur controlant le centrage des coordonnees (introduit le 20220113180147), la */ /* valeur par defaut assurant la compatibilite anterieure... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_3D_precises_____valider_les_coordonnees_barycentriques,VRAI))); /* Faut-il valider les coordonnees barycentriques ('VRAI') ou pas ('FAUX'). Ceci fut */ /* introduit le 20140625121516. */ DEFV(Common,DEFV(Logical,SINT(IFfractal_3D_precises_____utiliser_l_INTERPOLATION_CUBIQUE,VRAI))); /* Cet indicateur permet de choisir entre 'INTERPOLATION_CUBIQUE(...)' ('VRAI') et */ /* 'INTERPOLATION_LINEAIRE(...)' ('FAUX') dans 'IFfractal_3D_precises(...)'. */ /* */ /* On notera qu'on utilisera en general simultanement : */ /* */ /* IL_NE_FAUT_PAS(IFfractal_3D_precises_____utiliser_l_INTERPOLATION_CUBIQUE) */ /* */ /* et : */ /* */ /* IL_FAUT(IFfractal_____transformer_les_coordonnees_barycentriques) */ /* */ /* mais que cela n'est pas obligatoire... */ DEFV(Common,DEFV(Logical,SINT(IFfractal_3D_precises_____renormaliser_le_champ_automatiquement,FAUX))); /* Doit-on renormaliser le champ automatiquement ('VRAI') ou pas ('FAUX'). Ceci fut */ /* introduit le 20090307114051. */ DEFV(Common,DEFV(FonctionF,POINTERF(IFfractal_3D_precises(champ_fractal ,Zf ,X_puissance_de_reduction ,Y_puissance_de_reduction ,Z_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,ARGUMENT_POINTERs(facteur_d_echelle) ,ARGUMENT_POINTERs(translation2) ,ARGUMENT_POINTERs(origine_du_repliement) ,ARGUMENT_POINTERs(extremite_du_repliement) ,ARGUMENT_POINTERs(maille_initiale) ) ) ) ) DEFV(Argument,DEFV(imageF,champ_fractal)); /* Image Resultat, telle que : champ_fractal[X][Y]=fractal(X,Y). */ DEFV(Argument,DEFV(Float,Zf)); /* Coordonnee 'Z' flottante donnant dans un segment du type [0,1] la tranche */ /* verticale dans laquelle on genere la coupe bi-dimensionnelle du champ */ /* fractal tri-dimensionnel ou spatio-temporel. */ DEFV(Argument,DEFV(Float,X_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OX pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Y_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OY pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Z_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OZ pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,P_puissance_de_reduction)); /* Puissance a laquelle est elevee un coefficient de ponderation pour le reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Int,dernier_niveau_de_recursion_demande)); /* Niveau de recursion demande, c'est-a-dire le nombre de reductions */ /* recursives realisees. */ DEFV(Argument,DEFV(Int,graine)); /* Graine arbitraire dont depend la generation. */ DEFV(Argument,DEFV(Float,borne_inferieure)); /* Borne inferieure du generateur ; 'NOIR' est une bonne valeur. */ DEFV(Argument,DEFV(Float,borne_superieure)); /* Borne superieure du generateur ; 'BLANC' est une bonne valeur. */ DEFV(Argument,DEFV(coeffF_3D,POINTERs(facteur_d_echelle))); /* Facteur d'echelle du champ suivant les trois dimensions. */ DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation2))); /* Translation du champ exprimee dans des unites telles que l'unite represente */ /* respectivement [Xmin,Xmax], [Ymin,Ymax] et [Zmin,Zmax]. */ DEFV(Argument,DEFV(pointF_3D,POINTERs(origine_du_repliement))); /* Origine du champ afin de pouvoir generer le champ sur un 3D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Voir de plus le commentaire suivant... */ DEFV(Argument,DEFV(pointF_3D,POINTERs(extremite_du_repliement))); /* Extremite du champ afin de pouvoir generer le champ sur un 3D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Mais ATTENTION : lorsque le mode repliement */ /* d'un champ sur un tore, la reduction du maillage ne se fait plus par une */ /* exponentielle (voir 'puissance_de_reduction'), mais par une dichotomie */ /* (divisions par 2 successives) ; de plus, la maille initiale doit etre */ /* une puissance de 2 (pour la dichotomie) et diviser exactement la longueur */ /* du tore (ceci etant valable pour les trois directions 'X', 'Y' et 'Z' */ /* simultanement). */ DEFV(Argument,DEFV(deltaF_3D,POINTERs(maille_initiale))); /* Definition de la maille de base qui sera ensuite reduite recursivement ; elle */ /* est exprime dans des unites telles que l'unite represente */ /* respectivement 'dimX', 'dimY' et 'dimZ'. Voir de plus le commentaire precedent. */ /* */ /* ATTENTION, en cas d'utilisation de tres grandes valeurs (par rapport a 1) pour la */ /* maille initiale, il pourra etre necessaire d'augmenter correlativement la valeur du */ /* parametre 'rdnF3D_etendu_____extension' defini dans 'v $ximf/aleatoires$FON'. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock DEFV(Logical,INIT(on_est_sur_un_tore,FAUX)); /* Cet indicateur precise si l'on est sur un tore ('VRAI') ou pas ('FAUX') ; dans */ /* ce dernier cas au moins un des couples (origine,extremite) pour l'une des */ /* coordonnees est different de (TORE_PLAT_INFERIEUR,TORE_PLAT_SUPERIEUR). */ /* */ /* ATTENTION, l'indicateur 'on_est_sur_un_tore' porte simultanement sur les axes 'OX'. 'OY' */ /* et 'OZ', meme si un seul d'entre eux est "torique"... */ DEFV(Int,INIT(profondeur ,COND(IL_FAUT(IFfractal_2D_precises_____compatibilite_20191108) ,FIRST_NIVEAU_DE_RECURSION ,PRED(FIRST_NIVEAU_DE_RECURSION) ) ) ); /* Niveau reel de recursion qui sera utilise dans le calcul, tel qu'il n'y ait pas de */ /* mailles plus petites qu'un point. Il est initialise par 'FIRST_NIVEAU_DE_RECURSION' */ /* au cas ou les tests de son calcul seraient toujours faux... */ /* */ /* La nouvelle valeur par defaut introduite le 20191108140604 permet de garantir que l'on */ /* ne fait rien si l'argument 'dernier_niveau_de_recursion_demande' est negatif ou nul... */ DEFV(deltaF_3D,tore_plat_inferieur); DEFV(deltaF_3D,tore_plat_superieur); /* Ceci a ete introduit le 20001229164219 car, en l'absence de ces structures et donc en */ /* utilisant directement les composantes avec lesquelles on les definit, on observait sur */ /* 'SYSTEME_APC_...' ('$LACT14' ou encore '$CMAP27') un curieux phenomene. En effet, meme */ /* si l'on avait, a l'appel de la fonction 'IFfractal_3D_precises(...)' : */ /* */ /* origine_du_repliement = TORE_PLAT_INFERIEUR */ /* extremite_du_repliement = TORE_PLAT_SUPERIEUR */ /* */ /* ou le couple {TORE_PLAT_INFERIEUR,TORE_PLAT_SUPERIEUR} est destine a indiquer que */ /* l'on n'est pas sur un tore, le test ci-apres, destine a positionner l'indicateur */ /* 'on_est_sur_un_tore', determinait, par erreur, que l'on etait malgre tout sur un tore. */ /* L'introduction de ces structures intermediaires a resolu ce probleme... */ DEFV(pointF_3D,veritable_origine_du_repliement); DEFV(pointF_3D,veritable_extremite_du_repliement); /* Origine et extremite du champ reellement utilisees apres mise a l'echelle... */ DEFV(deltaF_3D,translation_neutre); /* Les origine et extremite des tores n'ont pas a etre translatees, de meme que le centre */ /* du champ... */ DEFV(deltaF_3D,translation_dans_le_champ); /* Translation dans le champ. */ DEFV(pointF_3D,centre_du_champ); /* Centre du champ. */ DEFV(pointF_3D,noeud_courant_du_reseau_a_l_echelle); /* Noeud courant du reseau a l'echelle. */ DEFV(pointF_3D,noeud_courant_du_reseau_eventuellement_dilate); /* Noeud courant du reseau eventuellement dilate. */ DEFV(pointF_3D,noeud_eventuellement_replie); /* Noeud obtenu par repliement eventuel du noeud courant du reseau eventuellement dilate. */ DEFV(pointF_3D,barycentre); DEFV(pointF_3D,barycentre_transforme); /* Pour calculer les coordonnees barycentriques d'un point dans une maille et sa version */ /* eventuellement transformee par 'TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(...)'. */ DEFV(deltaF_3D,maille_courante_a_l_echelle); /* Maille courante a l'echelle. */ DEFV(deltaF_3D,DTb1(maille,NIVEAU_DE_RECURSION)); /* Liste des mailles reduites recursivement a partir de 'maille_initiale'. */ DEFV(Float,INIT(ponderation_courante,FLOT__UNDEF)); /* Coefficient courant de ponderation ; il est en fait egale a */ /* l'aire de la maille initiale ; mais il faut noter que sa 'NORMALISATION' */ /* est obligatoire, de facon que la ponderation courante soit superieure */ /* a 1, afin que 'coefficients_de_ponderation' soit une suite decroissante. */ DEFV(Int,INIT(niveau,UNDEF)); /* Niveau de recursion courant. */ DEFV(Float,INIT(fonction___au_noeud_u0v0w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=0,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u1v0w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=0,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u0v1w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u1v1w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u0v0w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=0,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u1v0w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=0,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u0v1w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+1,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u1v1w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+1,w=+1). */ DEFV(Float,INIT(fonction___au_noeud_u9v0w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=0,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u2v0w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=0,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u9v1w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=+1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u2v1w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=+1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u9v0w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=0,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u2v0w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=0,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u9v1w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=-1,v=+1,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u2v1w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+2,v=+1,w=+1). */ DEFV(Float,INIT(fonction___au_noeud_u0v9w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=-1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u1v9w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=-1,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u0v2w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+2,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u1v2w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+2,w=0), */ DEFV(Float,INIT(fonction___au_noeud_u0v9w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=-1,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u1v9w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=-1,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u0v2w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+2,w=+1), */ DEFV(Float,INIT(fonction___au_noeud_u1v2w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+2,w=+1). */ DEFV(Float,INIT(fonction___au_noeud_u0v0w9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=0,w=-1), */ DEFV(Float,INIT(fonction___au_noeud_u1v0w9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=0,w=-1), */ DEFV(Float,INIT(fonction___au_noeud_u0v1w9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+1,w=-1), */ DEFV(Float,INIT(fonction___au_noeud_u1v1w9,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+1,w=-1), */ DEFV(Float,INIT(fonction___au_noeud_u0v0w2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=0,w=+2), */ DEFV(Float,INIT(fonction___au_noeud_u1v0w2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=0,w=+2), */ DEFV(Float,INIT(fonction___au_noeud_u0v1w2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=0,v=+1,w=+2), */ DEFV(Float,INIT(fonction___au_noeud_u1v1w2,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=+1,v=+1,w=+2). */ DEFV(Float,INIT(fonction___au_point_uUv0w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=0,w=0), */ DEFV(Float,INIT(fonction___au_point_uUv1w0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=+1,w=0), */ DEFV(Float,INIT(fonction___au_point_uUv0w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=0,w=+1), */ DEFV(Float,INIT(fonction___au_point_uUv1w1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=+1,w=+1), */ DEFV(Float,INIT(fonction___au_point_uUvVw0,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=V,w=0), */ DEFV(Float,INIT(fonction___au_point_uUvVw1,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=V,w=+1). */ DEFV(Float,INIT(fonction___au_point_uUvVwW,FLOT__UNDEF)); /* Valeur de la fonction aleatoire au noeud (u=U,v=V,w=W). */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=0,w=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=0,w=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=+1,w=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=+1,w=0), */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=0,w=+1), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=0,w=+1), */ DEFV(Float,INIT(derivee_Du_au_noeud_u0v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=0,v=+1,w=+1), */ DEFV(Float,INIT(derivee_Du_au_noeud_u1v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'u' de la fonction aleatoire au noeud (u=+1,v=+1,w=+1). */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=0,w=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=0,w=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u0v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=0,v=+1,w=+1), */ DEFV(Float,INIT(derivee_Dv_au_noeud_u1v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au noeud (u=+1,v=+1,w=+1). */ DEFV(Float,INIT(derivee_Dv_au_point_uUv0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=0,w=0), */ DEFV(Float,INIT(derivee_Dv_au_point_uUv1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dv_au_point_uUv0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dv_au_point_uUv1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'v' de la fonction aleatoire au point (u=U,v=+1,w=+1). */ DEFV(Float,INIT(derivee_Dw_au_noeud_u0v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=0,v=0,w=0), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u1v0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=+1,v=0,w=0), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u0v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=0,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u1v1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=+1,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u0v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=0,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u1v0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=+1,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u0v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=0,v=+1,w=+1), */ DEFV(Float,INIT(derivee_Dw_au_noeud_u1v1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au noeud (u=+1,v=+1,w=+1). */ DEFV(Float,INIT(derivee_Dw_au_point_uUv0w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=0,w=0), */ DEFV(Float,INIT(derivee_Dw_au_point_uUv1w0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=+1,w=0), */ DEFV(Float,INIT(derivee_Dw_au_point_uUv0w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=0,w=+1), */ DEFV(Float,INIT(derivee_Dw_au_point_uUv1w1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=+1,w=+1). */ DEFV(Float,INIT(derivee_Dw_au_point_uUvVw0,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=V,w=0), */ DEFV(Float,INIT(derivee_Dw_au_point_uUvVw1,FLOT__UNDEF)); /* Valeur de la derivee partielle en 'w' de la fonction aleatoire au point (u=U,v=V,w=+1). */ DEFV(Float,INIT(niveau_courant,FLOT__UNDEF)); /* Niveau flottant du point courant. */ /*..............................................................................................................................*/ INITIALISATION_ACCROISSEMENT_3D(tore_plat_inferieur ,_____cNORMALISE_OX(TORE_PLAT_INFERIEUR) ,_____cNORMALISE_OY(TORE_PLAT_INFERIEUR) ,_____cNORMALISE_OZ(TORE_PLAT_INFERIEUR) ); INITIALISATION_ACCROISSEMENT_3D(tore_plat_superieur ,_____cNORMALISE_OX(TORE_PLAT_SUPERIEUR) ,_____cNORMALISE_OY(TORE_PLAT_SUPERIEUR) ,_____cNORMALISE_OZ(TORE_PLAT_SUPERIEUR) ); PREPARATION_DE_L_UTILISATION_DES_LISTES_DE_SUBSTITUTION; /* Preparation de la liste de SUBSTITUTION courante et des trois listes de SUBSTITUTION */ /* {ROUGE,VERTE,BLEUE} au cas ou l'une d'entre-elles serait necessaire... */ gTRANSFERT_ACCROISSEMENT_3D(translation_dans_le_champ ,translation2 ,ASD1 ,ASI1 ); /* Translation dans le champ. */ INITIALISATION_ACCROISSEMENT_3D(translation_neutre ,FZERO ,FZERO ,FZERO ); /* Les origine et extremite des tores n'ont pas a etre translatees, de meme que le centre */ /* du champ... */ INITIALISATION_TRANSFORMATION; /* Au cas ou... */ Test(I3OU(IZLE(X_facteur_d_echelle) ,IZLE(Y_facteur_d_echelle) ,IZLE(Z_facteur_d_echelle) ) ) Bblock PRINT_ERREUR("le facteur d'echelle est incorrect"); Eblock ATes Bblock Eblock ETes Test(IFOU(I3OU(IFGT(ASI1(origine_du_repliement,x),ASD1(tore_plat_inferieur,dx)) ,IFGT(ASI1(origine_du_repliement,y),ASD1(tore_plat_inferieur,dy)) ,IFGT(ASI1(origine_du_repliement,z),ASD1(tore_plat_inferieur,dz)) ) ,I3OU(IFLT(ASI1(extremite_du_repliement,x),ASD1(tore_plat_superieur,dx)) ,IFLT(ASI1(extremite_du_repliement,y),ASD1(tore_plat_superieur,dy)) ,IFLT(ASI1(extremite_du_repliement,z),ASD1(tore_plat_superieur,dz)) ) ) ) Bblock Test(I3OU(IFGE(ASI1(origine_du_repliement,x),ASI1(extremite_du_repliement,x)) ,IFGE(ASI1(origine_du_repliement,y),ASI1(extremite_du_repliement,y)) ,IFGE(ASI1(origine_du_repliement,z),ASI1(extremite_du_repliement,z)) ) ) Bblock PRINT_ERREUR("la definition du tore de repliement est incorrecte"); CAL1(Prer3("origine..=(%+.17f,%+.17f,%+.17f)\n" ,ASI1(origine_du_repliement,x),ASI1(origine_du_repliement,y),ASI1(origine_du_repliement,z) ) ); CAL1(Prer3("extremite=(%+.17f,%+.17f,%+.17f)\n" ,ASI1(extremite_du_repliement,x),ASI1(extremite_du_repliement,y),ASI1(extremite_du_repliement,z) ) ); Eblock ATes Bblock EGAL(on_est_sur_un_tore,VRAI); /* Lorsque la definition du tore de repliement est correcte, on l'adopte... */ Eblock ETes Eblock ATes Bblock Eblock ETes Test(EST_FAUX(on_est_sur_un_tore)) Bblock INITIALISATION_POINT_3D(veritable_origine_du_repliement ,ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,ASI1(origine_du_repliement,z) ); INITIALISATION_POINT_3D(veritable_extremite_du_repliement ,ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,ASI1(extremite_du_repliement,z) ); Eblock ATes Bblock INITIALISATION_POINT_3D(veritable_origine_du_repliement ,TRANSFORMATION_OX(ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,ASI1(origine_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,ASI1(origine_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OZ(ASI1(origine_du_repliement,x) ,ASI1(origine_du_repliement,y) ,ASI1(origine_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ); INITIALISATION_POINT_3D(veritable_extremite_du_repliement ,TRANSFORMATION_OX(ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,ASI1(extremite_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,ASI1(extremite_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OZ(ASI1(extremite_du_repliement,x) ,ASI1(extremite_du_repliement,y) ,ASI1(extremite_du_repliement,z) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ); /* Et mise en place des veritables origine et extremite... */ INITIALISATION_ACCROISSEMENT_3D(translation_dans_le_champ ,TRANSLATION_TORIQUE(translation_dans_le_champ,dx ,veritable_origine_du_repliement,veritable_extremite_du_repliement,x ) ,TRANSLATION_TORIQUE(translation_dans_le_champ,dy ,veritable_origine_du_repliement,veritable_extremite_du_repliement,y ) ,TRANSLATION_TORIQUE(translation_dans_le_champ,dz ,veritable_origine_du_repliement,veritable_extremite_du_repliement,z ) ); /* Aux environs du 20090918084309, j'ai decouvert qu'en mode "torique" la translation des */ /* champs fonctionnait bien si elle etait negative. Par 'TRANSLATION_TORIQUE(...)' toute */ /* translation positive est donc ramenee a une translation negative. Ce probleme semble */ /* venir de la fonction 'Fcalcul_d_un_noeud_relativement_au_centre(...)' sans que cela soit */ /* une certitude... */ Eblock ETes Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme2("tore OX=(%+.17f,%+.17f)\n" ,ASD1(veritable_origine_du_repliement,x),ASD1(veritable_extremite_du_repliement,x) ) ); CAL3(Prme2("tore OY=(%+.17f,%+.17f)\n" ,ASD1(veritable_origine_du_repliement,y),ASD1(veritable_extremite_du_repliement,y) ) ); CAL3(Prme2("tore OZ=(%+.17f,%+.17f)\n" ,ASD1(veritable_origine_du_repliement,z),ASD1(veritable_extremite_du_repliement,z) ) ); Eblock ATes Bblock Eblock ETes INITIALISATION_POINT_3D(noeud_courant_du_reseau_eventuellement_dilate,Xmin,Ymin,Zmin); CALS(rdnF3D_etendu(ADRESSE(noeud_courant_du_reseau_eventuellement_dilate) ,UNDEF ,RDN_INIT ,borne_inferieure,borne_superieure ) ); /* Initialisation du generateur aleatoire. */ DoIn(niveau ,FIRST_NIVEAU_DE_RECURSION ,COND(IL_FAUT(IFfractal_3D_precises_____compatibilite_20191108) ,TRON(dernier_niveau_de_recursion_demande,FIRST_NIVEAU_DE_RECURSION,NIVEAU_DE_RECURSION) ,dernier_niveau_de_recursion_demande ) ,I ) /* La modification du 20191108135531 permet de ne pas faire d'iterations et d'alors */ /* renvoyer le champ initial (en general uniforme et meme nul...). */ Bblock INITIALISATION_ACCROISSEMENT_3D(ITb1(maille,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,REDUCTION_OX(ASI1(maille_initiale,dx)) ,REDUCTION_OY(ASI1(maille_initiale,dy)) ,REDUCTION_OZ(ASI1(maille_initiale,dz)) ); INITIALISATION_ACCROISSEMENT_3D(maille_courante_a_l_echelle ,REDUCTION_OX(MUL2(X_facteur_d_echelle,ASI1(maille_initiale,dx))) ,REDUCTION_OY(MUL2(Y_facteur_d_echelle,ASI1(maille_initiale,dy))) ,REDUCTION_OZ(MUL2(Z_facteur_d_echelle,ASI1(maille_initiale,dz))) ); /* Puis reduction recursive de la maille. */ EGAL(ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,REDUCTION_PONDERATION(RAC3(MUL3(ASI1(maille_initiale,dx),ASI1(maille_initiale,dy),ASI1(maille_initiale,dz)))) ); /* Generation de la liste des coefficients de ponderation. */ /* */ /* Le 20070227142652, 'PUIX(...,INVE(FLOT(TRI_DIMENSIONNEL))' fut remplace par 'RAC3(...)'. */ Test(IFET(I3OU(IFGT(F__lDENORMALISE_OX(ASD1(maille_courante_a_l_echelle,dx)) ,MUL2(aleat_2_____plus_petite_maille_significative,FLOT(INTER_POINT)) ) ,IFGT(F__lDENORMALISE_OY(ASD1(maille_courante_a_l_echelle,dy)) ,MUL2(aleat_2_____plus_petite_maille_significative,FLOT(INTER_POINT)) ) ,IFGT(F__lDENORMALISE_OZ(ASD1(maille_courante_a_l_echelle,dz)) ,MUL2(aleat_2_____plus_petite_maille_significative,FLOT(INTER_POINT)) ) ) ,IFOU(IFEQ(niveau,FIRST_NIVEAU_DE_RECURSION) ,IFET(IFGT(niveau,FIRST_NIVEAU_DE_RECURSION) ,I3OU(IFNE_a_peu_pres_relatif(ASD1(ITb1(maille,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)),dx) ,ASD1(ITb1(maille,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)),dx) ,aleat_2_____distance_relative_limite_des_mailles ) ,IFNE_a_peu_pres_relatif(ASD1(ITb1(maille,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)),dy) ,ASD1(ITb1(maille,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)),dy) ,aleat_2_____distance_relative_limite_des_mailles ) ,IFNE_a_peu_pres_relatif(ASD1(ITb1(maille,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)),dz) ,ASD1(ITb1(maille,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)),dz) ,aleat_2_____distance_relative_limite_des_mailles ) ) ) ) ) ) /* ATTENTION, le test d'arret sur la taille des mailles doit etre fait en coordonnees */ /* ecran ('INTER_POINT') et non pas l'inverse car il faut noter que, par exemple, en mode */ /* 'Pal' ou les images sont rectangulaires, si l'on definit des mailles initiales carrees */ /* c'est-a-dire ayant des valeurs de 'dx' et 'dy' egales, en fait visuellement elles */ /* ne seront pas carrees mais rectangulaires (dans le format 'Pal'), phenomene qui est */ /* completement masque par les coordonnees [0,1] et qui fausse donc le test d'arret... */ Bblock EGAL(profondeur,niveau); /* On calcule progressivement la valeur de recursion a utiliser reellement. */ VALIDATION_MAILLE_OX; VALIDATION_MAILLE_OY; VALIDATION_MAILLE_OZ; VALIDATION_PONDERATION; Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme5(" maille(%04d)=%+.17fx(%+.17f,%+.17f,%+.17f)" ,niveau ,ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,X_maille(niveau),Y_maille(niveau),Z_maille(niveau) ) ); Test(IFGT(niveau,FIRST_NIVEAU_DE_RECURSION)) Bblock CAL3(Prme3(" maille(%04d)/maille(%04d)=%+.17f" ,NEUT(niveau) ,PRED(niveau) ,DIVI(ITb1(coefficients_de_ponderation,INDX(NEUT(niveau),FIRST_NIVEAU_DE_RECURSION)) ,ITb1(coefficients_de_ponderation,INDX(PRED(niveau),FIRST_NIVEAU_DE_RECURSION)) ) ) ); Eblock ATes Bblock Eblock ETes CALS(Fsauts_de_lignes(UN)); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Eblock EDoI Test(IL_FAUT(aleat_2_____editer_les_mailles_et_les_ponderations)) Bblock CAL3(Prme1("profondeur=%d\n",profondeur)); /* Edition introduite le 20040107152646... */ Test(IL_FAUT(aleat_2_____aborter_apres_l_edition_des_mailles_et_des_ponderations)) Bblock Abort(OK); /* Sortie tres brutale introduite le 20180708114359 pour gagner du temps lors de tests... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes INITIALISATION_POINT_3D(centre_du_champ ,TRANSFORMATION_OX(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(Xcentre)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Ycentre)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(Zcentre)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OY(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(Xcentre)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Ycentre)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(Zcentre)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ,TRANSFORMATION_OZ(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(Xcentre)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Ycentre)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(Zcentre)) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_neutre ) ); /* Ce calcul est effectue systematiquement, alors qu'il n'a de sens que pour le calcul des */ /* noeuds 'CALCUL_DES_NEUDS_VERSION_02', afin de simplifier 'CALCUL_D_UN_NOEUD(...)' qui, */ /* sinon, n'aurait pas le meme nombre d'arguments d'une version a l'autre... */ begin_image Bblock DEFV(pointF_3D,point_courant_du_reseau_a_l_echelle); /* Point courant du reseau a l'echelle. */ DEFV(pointF_3D,point_courant_du_reseau_eventuellement_dilate); /* Point courant du reseau eventuellement dilate. */ Test(IL_FAUT(IFfractal_3D_precises_____compatibilite_20191108)) Bblock CLIR(niveau_courant); /* Nettoyage du cumul pour le point courant. */ Eblock ATes Bblock EGAL(niveau_courant,loadF_point(champ_fractal,X,Y)); /* Ceci permet de recuperer la valeur initiale du champ dans le cas ou il n'y a pas */ /* d'iterations (introduit le 20191108155047)... */ Eblock ETes INITIALISATION_POINT_3D(point_courant_du_reseau_a_l_echelle ,TRANSFORMATION_OX(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(X)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Y)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(_cDENORMALISE_OZ(Zf))) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_dans_le_champ ) ,TRANSFORMATION_OY(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(X)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Y)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(_cDENORMALISE_OZ(Zf))) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_dans_le_champ ) ,TRANSFORMATION_OZ(_____cNORMALISE_OX(CENTRAGE_FRACTAL_OX(X)) ,_____cNORMALISE_OY(CENTRAGE_FRACTAL_OY(Y)) ,_____cNORMALISE_OZ(CENTRAGE_FRACTAL_OZ(_cDENORMALISE_OZ(Zf))) ,X_facteur_d_echelle ,Y_facteur_d_echelle ,Z_facteur_d_echelle ,translation_dans_le_champ ) ); /* ATTENTION, jusqu'au 1996020700 'Zf' etait utilisee via 'NEUT(Zf)' et ne subissait donc */ /* pas le centrage comme les deux autres coordonnees 'X' et 'Y'... */ EGAL(X_point_courant_du_reseau_a_l_echelle,ARRI_FRACTAL_COORDONNEE(X_point_courant_du_reseau_a_l_echelle)); EGAL(Y_point_courant_du_reseau_a_l_echelle,ARRI_FRACTAL_COORDONNEE(Y_point_courant_du_reseau_a_l_echelle)); EGAL(Z_point_courant_du_reseau_a_l_echelle,ARRI_FRACTAL_COORDONNEE(Z_point_courant_du_reseau_a_l_echelle)); /* Et ce afin d'eviter des problemes de calcul. En procedant ainsi, on manipule les */ /* nombres flottats comme des nombres entiers dont l'unite ('1') ne serait plus '1' */ /* mais 'aleat_2_____epsilon_de_generation_fractale'... */ DoIn(niveau,aleat_2_____premier_niveau_de_recursion_a_utiliser,profondeur,I) Bblock DEFV(Int,INIT(niveau_modulo,MODS(niveau,FIRST_NIVEAU_DE_RECURSION,aleat_2_____borne_superieure_du_niveau_de_recursion))); /* Pour assurer l'interpolation d'echelle via les niveaux generes... */ INITIALISATION_POINT_3D(noeud_courant_du_reseau_a_l_echelle ,CALCUL_D_UN_NOEUD(X_point_courant_du_reseau_a_l_echelle,X_maille(niveau),X_centre_du_champ) ,CALCUL_D_UN_NOEUD(Y_point_courant_du_reseau_a_l_echelle,Y_maille(niveau),Y_centre_du_champ) ,CALCUL_D_UN_NOEUD(Z_point_courant_du_reseau_a_l_echelle,Z_maille(niveau),Z_centre_du_champ) ); /* Noeud courant du reseau avant "arrondi fractal". */ Test(IFEQ(niveau,niveau_modulo)) Bblock TRANSFERT_POINT_3D(point_courant_du_reseau_eventuellement_dilate,point_courant_du_reseau_a_l_echelle); /* Lorsque le 'niveau' et le 'niveau_modulo' coincident, le point courant et le point */ /* courant a l'echelle coincident aussi... */ TRANSFERT_POINT_3D(noeud_courant_du_reseau_eventuellement_dilate,noeud_courant_du_reseau_a_l_echelle); /* Lorsque le 'niveau' et le 'niveau_modulo' coincident, le noeud courant et le noeud */ /* courant a l'echelle coincident aussi... */ Eblock ATes Bblock INITIALISATION_POINT_3D(point_courant_du_reseau_eventuellement_dilate ,ARRI_FRACTAL_COORDONNEE(SCAL(X_point_courant_du_reseau_a_l_echelle ,X_maille(niveau) ,X_maille(niveau_modulo) ) ) ,ARRI_FRACTAL_COORDONNEE(SCAL(Y_point_courant_du_reseau_a_l_echelle ,Y_maille(niveau) ,Y_maille(niveau_modulo) ) ) ,ARRI_FRACTAL_COORDONNEE(SCAL(Z_point_courant_du_reseau_a_l_echelle ,Z_maille(niveau) ,Z_maille(niveau_modulo) ) ) ); /* Point courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'point_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ INITIALISATION_POINT_3D(noeud_courant_du_reseau_eventuellement_dilate ,CALCUL_D_UN_NOEUD(X_point_courant_du_reseau_eventuellement_dilate ,X_maille(niveau_modulo) ,X_centre_du_champ ) ,CALCUL_D_UN_NOEUD(Y_point_courant_du_reseau_eventuellement_dilate ,Y_maille(niveau_modulo) ,Y_centre_du_champ ) ,CALCUL_D_UN_NOEUD(Z_point_courant_du_reseau_eventuellement_dilate ,Z_maille(niveau_modulo) ,Z_centre_du_champ ) ); /* Noeud courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'noeud_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ Eblock ETes INITIALISATION_POINT_3D(barycentre ,DIVI(SOUS(X_point_courant_du_reseau_eventuellement_dilate ,X_noeud_courant_du_reseau_eventuellement_dilate ) ,X_maille(niveau_modulo) ) ,DIVI(SOUS(Y_point_courant_du_reseau_eventuellement_dilate ,Y_noeud_courant_du_reseau_eventuellement_dilate ) ,Y_maille(niveau_modulo) ) ,DIVI(SOUS(Z_point_courant_du_reseau_eventuellement_dilate ,Z_noeud_courant_du_reseau_eventuellement_dilate ) ,Z_maille(niveau_modulo) ) ); /* Calcul des coordonnees barycentriques (u,v,w) alias */ /* {ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)} du point {X,Y,Z} courant */ /* par rapport a la maille courante ; on n'oubliera pas que : */ /* */ /* [(1-u)*(1-v)*(1-w)] */ /* +[u*(1-v)*(1-w)] */ /* +[u*v*(1-w)] */ /* +[(1-u)*v*(1-w)] */ /* +[(1-u)*(1-v)*w] */ /* +[u*(1-v)*w] */ /* +[u*v*w] */ /* +[(1-u)*v*w] = 1. */ /* */ /* ATTENTION, on notera que le barycentre est evalue avant de faire l'"arrondi fractal" afin */ /* d'evaluer correctement la distance (par 'SOUS(...)') entre le point courant et le noeud */ /* courant. En effet, sinon, etant donne que 'ARRI_FRACTAL_COORDONNEE(...)' travaille par */ /* defaut, elle a tendance a eloigner artificiellement le noeud du point courant ; donc, */ /* dans certains cas, cela peut donner des coordonnees barycentriques superieures a 1. */ /* Enfin, cela fait que le barycentre est evalue systematiquement et donc meme s'il n'est */ /* pas utile par la suite... */ INITIALISATION_POINT_3D(barycentre_transforme ,TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(ASD1(barycentre,x) ,liste_de_substitution_X_DANS_IFfractal ) ,TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(ASD1(barycentre,y) ,liste_de_substitution_Y_DANS_IFfractal ) ,TRANSFORMATION_COORDONNEE_BARYCENTRIQUE(ASD1(barycentre,z) ,liste_de_substitution_Z_DANS_IFfractal ) ); /* Et transformation eventuelle... */ INITIALISATION_POINT_3D(noeud_courant_du_reseau_a_l_echelle ,ARRI_FRACTAL_COORDONNEE(X_noeud_courant_du_reseau_a_l_echelle) ,ARRI_FRACTAL_COORDONNEE(Y_noeud_courant_du_reseau_a_l_echelle) ,ARRI_FRACTAL_COORDONNEE(Z_noeud_courant_du_reseau_a_l_echelle) ); /* Noeud courant du reseau apres "arrondi fractal". Cette operation doit imperativement */ /* etre effectuee ici, et non pas dans le test sur le niveau qui precede car, en effet, */ /* le calcul du barycentre demande un noeud courant n'ayant pas subi encore l'"arrondi */ /* fractal", or le noeud courant du reseau a l'echelle a pu servir a initialiser le noeud */ /* courant du reseau eventuellement dilate (voir le test qui precede...). */ INITIALISATION_POINT_3D(noeud_courant_du_reseau_eventuellement_dilate ,ARRI_FRACTAL_COORDONNEE(X_noeud_courant_du_reseau_eventuellement_dilate) ,ARRI_FRACTAL_COORDONNEE(Y_noeud_courant_du_reseau_eventuellement_dilate) ,ARRI_FRACTAL_COORDONNEE(Z_noeud_courant_du_reseau_eventuellement_dilate) ); /* Noeud courant du reseau eventuellement dilate pour assurer l'interpolation d'echelle ; */ /* il est obtenu en dilatant le reseau defini par 'noeud_courant_du_reseau_a_l_echelle' */ /* dans le rapport des mailles 'niveau' et 'niveau_modulo'. */ Test(IL_FAUT(aleat_2_____editer_uniquement_les_noeuds)) Bblock Test(IFET(IFEQ(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,IFEQ(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ) ) /* Ce test bidimensionnel a ete mis en place le 20220114064137 suite a la remarque */ /* ci-apres ('v $xiii/aleat.2$vv$FON 20220113175029') qui explique que la coordonnee */ /* 'Z' est constante... */ Bblock CAL3(Prme5("Niveau=%d/%d Noeud=(%+.17f,%+.17f,%+.17f)\n" ,niveau ,profondeur ,CHOI(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,CHOI(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ,CHOI(Y_point_courant_du_reseau_a_l_echelle,Z_noeud_courant_du_reseau_a_l_echelle) ) ); /* Possibilite introduite le 20220113173832... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes Test(I3ET(IFEQ(X_point_courant_du_reseau_a_l_echelle,X_noeud_courant_du_reseau_a_l_echelle) ,IFEQ(Y_point_courant_du_reseau_a_l_echelle,Y_noeud_courant_du_reseau_a_l_echelle) ,IFEQ(Z_point_courant_du_reseau_a_l_echelle,Z_noeud_courant_du_reseau_a_l_echelle) ) ) /* Je note le 20220113175029 que l'on doit passer ici tres rarement, voire jamais, car en */ /* effet, dans la fonction 'IFfractal_3D_precises(...)' la coordonnee 'Z' ne varie pas et */ /* est egale a l'argument 'Zf'... */ /* */ /* C'est ce qui explique que l'edition des noeuds uniquement a ete sorti de ce test et */ /* mis avant le 20220114064137... */ Bblock CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_point_uUvVwW); /* Lorsque l'on est exactement sur l'un des noeuds du maillage courant, */ /* il n'y a pas d'interpolation a realiser. */ Eblock ATes Bblock Test(IL_FAUT(IFfractal_3D_precises_____valider_les_coordonnees_barycentriques)) Bblock Test(I3OU(NINCff(COORDONNEE_U_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ,COORDONNEE_BARYCENTRIQUE_MINIMALE ,COORDONNEE_BARYCENTRIQUE_MAXIMALE ) ,NINCff(COORDONNEE_V_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ,COORDONNEE_BARYCENTRIQUE_MINIMALE ,COORDONNEE_BARYCENTRIQUE_MAXIMALE ) ,NINCff(COORDONNEE_W_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ,COORDONNEE_BARYCENTRIQUE_MINIMALE ,COORDONNEE_BARYCENTRIQUE_MAXIMALE ) ) ) Bblock PRINT_ERREUR("au moins une des coordonnees barycentriques (u,v,w) est hors [0,1]"); CAL1(Prer3("point.={%+.17f,%+.17f,%+.17f}\n" ,X_point_courant_du_reseau_a_l_echelle ,Y_point_courant_du_reseau_a_l_echelle ,Z_point_courant_du_reseau_a_l_echelle ) ); CAL1(Prer3("noeud.={%+.17f,%+.17f,%+.17f}\n" ,X_noeud_courant_du_reseau_a_l_echelle ,Y_noeud_courant_du_reseau_a_l_echelle ,Z_noeud_courant_du_reseau_a_l_echelle ) ); CAL1(Prer3("maille={%+.17f,%+.17f,%+.17f}\n" ,X_maille(niveau) ,Y_maille(niveau) ,Z_maille(niveau) ) ); CAL1(Prer3("{u,v,w}={%+.17f,%+.17f,%+.17f}\n" ,COORDONNEE_U_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ,COORDONNEE_V_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ,COORDONNEE_W_0(ASD1(barycentre,x),ASD1(barycentre,y),ASD1(barycentre,z)) ) ); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v0w0); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v0w0); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v1w0); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v1w0); NOEUD_AVANT(Y); NOEUD_APRES(Z); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v0w1); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v0w1); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v1w1); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v1w1); NOEUD_AVANT(Y); NOEUD_AVANT(Z); NOEUD_AVANT(Z); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v0w9); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v0w9); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v1w9); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v1w9); NOEUD_AVANT(Y); NOEUD_APRES(Z); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u9v0w0); NOEUD_APRES(X); NOEUD_AVANT(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v9w0); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v9w0); NOEUD_APRES(X); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u2v0w0); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u2v1w0); NOEUD_AVANT(X); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v2w0); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v2w0); NOEUD_AVANT(X); NOEUD_AVANT(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u9v1w0); NOEUD_AVANT(Y); NOEUD_APRES(Z); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u9v0w1); NOEUD_APRES(X); NOEUD_AVANT(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v9w1); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v9w1); NOEUD_APRES(X); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u2v0w1); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u2v1w1); NOEUD_AVANT(X); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v2w1); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v2w1); NOEUD_AVANT(X); NOEUD_AVANT(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u9v1w1); NOEUD_AVANT(Y); NOEUD_APRES(Z); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v0w2); NOEUD_APRES(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v0w2); NOEUD_APRES(Y); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u1v1w2); NOEUD_AVANT(X); CALCUL_NOEUD_3D_COURANT_DILATE(fonction___au_noeud_u0v1w2); NOEUD_AVANT(Y); NOEUD_AVANT(Z); NOEUD_AVANT(Z); /* Calcul des valeurs de la fonction aux noeuds entourant le cube de base, afin de pouvoir */ /* calculer ci-apres les derivees partielles en chacun de ses noeuds par des differences */ /* finies... */ DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v0w0 ,fonction___au_noeud_u9v0w0 ,fonction___au_noeud_u1v0w0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v0w0 ,fonction___au_noeud_u0v0w0 ,fonction___au_noeud_u2v0w0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v1w0 ,fonction___au_noeud_u0v1w0 ,fonction___au_noeud_u2v1w0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v1w0 ,fonction___au_noeud_u9v1w0 ,fonction___au_noeud_u1v1w0 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v0w1 ,fonction___au_noeud_u9v0w1 ,fonction___au_noeud_u1v0w1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v0w1 ,fonction___au_noeud_u0v0w1 ,fonction___au_noeud_u2v0w1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u1v1w1 ,fonction___au_noeud_u0v1w1 ,fonction___au_noeud_u2v1w1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Du_au_noeud_u0v1w1 ,fonction___au_noeud_u9v1w1 ,fonction___au_noeud_u1v1w1 ,X_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v0w0 ,fonction___au_noeud_u0v9w0 ,fonction___au_noeud_u0v1w0 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v0w0 ,fonction___au_noeud_u1v9w0 ,fonction___au_noeud_u1v1w0 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v1w0 ,fonction___au_noeud_u1v0w0 ,fonction___au_noeud_u1v2w0 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v1w0 ,fonction___au_noeud_u0v0w0 ,fonction___au_noeud_u0v2w0 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v0w1 ,fonction___au_noeud_u0v9w1 ,fonction___au_noeud_u0v1w1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v0w1 ,fonction___au_noeud_u1v9w1 ,fonction___au_noeud_u1v1w1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u1v1w1 ,fonction___au_noeud_u1v0w1 ,fonction___au_noeud_u1v2w1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dv_au_noeud_u0v1w1 ,fonction___au_noeud_u0v0w1 ,fonction___au_noeud_u0v2w1 ,Y_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u0v0w0 ,fonction___au_noeud_u0v0w9 ,fonction___au_noeud_u0v0w1 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u1v0w0 ,fonction___au_noeud_u1v0w9 ,fonction___au_noeud_u1v0w1 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u1v1w0 ,fonction___au_noeud_u1v1w9 ,fonction___au_noeud_u1v1w1 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u0v1w0 ,fonction___au_noeud_u0v1w9 ,fonction___au_noeud_u0v1w1 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u0v0w1 ,fonction___au_noeud_u0v0w0 ,fonction___au_noeud_u0v0w2 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u1v0w1 ,fonction___au_noeud_u1v0w0 ,fonction___au_noeud_u1v0w2 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u1v1w1 ,fonction___au_noeud_u1v1w0 ,fonction___au_noeud_u1v1w2 ,Z_maille(niveau_modulo) ); DERIVATION_NUMERIQUE(derivee_Dw_au_noeud_u0v1w1 ,fonction___au_noeud_u0v1w0 ,fonction___au_noeud_u0v1w2 ,Z_maille(niveau_modulo) ); /* Calcul des derivees partielles en 'u', 'v' et 'w' aux noeuds du cube de base par des */ /* differences finies a l'aide des differentes valeurs aux noeuds du maillage... */ EGAL(derivee_Dv_au_point_uUv0w0 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v0w0 ,derivee_Dv_au_noeud_u1v0w0 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dv_au_point_uUv1w0 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v1w0 ,derivee_Dv_au_noeud_u1v1w0 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dv_au_point_uUv0w1 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v0w1 ,derivee_Dv_au_noeud_u1v0w1 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dv_au_point_uUv1w1 ,INTERPOLATION_LINEAIRE(derivee_Dv_au_noeud_u0v1w1 ,derivee_Dv_au_noeud_u1v1w1 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dw_au_point_uUv0w0 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_noeud_u0v0w0 ,derivee_Dw_au_noeud_u1v0w0 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dw_au_point_uUv1w0 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_noeud_u0v1w0 ,derivee_Dw_au_noeud_u1v1w0 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dw_au_point_uUv0w1 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_noeud_u0v0w1 ,derivee_Dw_au_noeud_u1v0w1 ,ASD1(barycentre,x) ) ); EGAL(derivee_Dw_au_point_uUv1w1 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_noeud_u0v1w1 ,derivee_Dw_au_noeud_u1v1w1 ,ASD1(barycentre,x) ) ); /* Calcul des derivees partielles en 'u', 'v' et 'w' sur des aretes horizontales du cube de */ /* base par des interpolations lineaires a partir des sommets voisins (on notera que l'on */ /* ne peut utiliser d'interpolation cubique, puisqu'on ne connait pas encore les derivees). */ EGAL(derivee_Dw_au_point_uUvVw0 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_point_uUv0w0 ,derivee_Dw_au_point_uUv1w0 ,ASD1(barycentre,y) ) ); EGAL(derivee_Dw_au_point_uUvVw1 ,INTERPOLATION_LINEAIRE(derivee_Dw_au_point_uUv0w1 ,derivee_Dw_au_point_uUv1w1 ,ASD1(barycentre,y) ) ); /* Calcul des derivees partielles en 'u', 'v' et 'w' sur des segments verticaux du cube de */ /* base par des interpolations lineaires a partir des sommets voisins (on notera que l'on */ /* ne peut utiliser d'interpolation cubique, puisqu'on ne connait pas encore les derivees). */ EGAL(fonction___au_point_uUv0w0 ,INTERPOLATION_FRACTALE_3D_X(fonction___au_noeud_u0v0w0 ,derivee_Du_au_noeud_u0v0w0 ,fonction___au_noeud_u1v0w0 ,derivee_Du_au_noeud_u1v0w0 ,ASD1(barycentre_transforme,x) ) ); EGAL(fonction___au_point_uUv1w0 ,INTERPOLATION_FRACTALE_3D_X(fonction___au_noeud_u0v1w0 ,derivee_Du_au_noeud_u0v1w0 ,fonction___au_noeud_u1v1w0 ,derivee_Du_au_noeud_u1v1w0 ,ASD1(barycentre_transforme,x) ) ); EGAL(fonction___au_point_uUv0w1 ,INTERPOLATION_FRACTALE_3D_X(fonction___au_noeud_u0v0w1 ,derivee_Du_au_noeud_u0v0w1 ,fonction___au_noeud_u1v0w1 ,derivee_Du_au_noeud_u1v0w1 ,ASD1(barycentre_transforme,x) ) ); EGAL(fonction___au_point_uUv1w1 ,INTERPOLATION_FRACTALE_3D_X(fonction___au_noeud_u0v1w1 ,derivee_Du_au_noeud_u0v1w1 ,fonction___au_noeud_u1v1w1 ,derivee_Du_au_noeud_u1v1w1 ,ASD1(barycentre_transforme,x) ) ); /* Calcul de la valeur de la fonction sur des aretes horizontales du cube de base... */ EGAL(fonction___au_point_uUvVw0 ,INTERPOLATION_FRACTALE_3D_Y(fonction___au_point_uUv0w0 ,derivee_Dv_au_point_uUv0w0 ,fonction___au_point_uUv1w0 ,derivee_Dv_au_point_uUv1w0 ,ASD1(barycentre_transforme,y) ) ); EGAL(fonction___au_point_uUvVw1 ,INTERPOLATION_FRACTALE_3D_Y(fonction___au_point_uUv0w1 ,derivee_Dv_au_point_uUv0w1 ,fonction___au_point_uUv1w1 ,derivee_Dv_au_point_uUv1w1 ,ASD1(barycentre_transforme,y) ) ); /* Calcul de la valeur de la fonction sur des segments verticaux du cube de base... */ EGAL(fonction___au_point_uUvVwW ,INTERPOLATION_FRACTALE_3D_Z(fonction___au_point_uUvVw0 ,derivee_Dw_au_point_uUvVw0 ,fonction___au_point_uUvVw1 ,derivee_Dw_au_point_uUvVw1 ,ASD1(barycentre_transforme,z) ) ); /* Ordre des interpolations cubiques ('-1' est note '9') : */ /* */ /* */ /* v=1 012- - - - - - - -112 */ /* | (31) (30) | */ /* | | */ /* | | */ /* | | */ /* w=2 | | */ /* | | */ /* | | */ /* | | */ /* | (28) (29) | */ /* v=0 002- - - - - - - -102 */ /* */ /* u=0 u=1 */ /* */ /* */ /* v=2 - - - - - - - -021- - - - - - - -121- - - - - - - - */ /* | /| (26) (25) |\ | */ /* / \ */ /* | / | | \ | */ /* / \ */ /* | / | | \ | */ /* / \ */ /* | / | | \ | */ /* / [1] \ */ /* |/ | | \| */ /* v=1 911- - - - - - - -011---------U11---111- - - - - - - -211 */ /* | (27) | (07) .(06) | (24) | */ /* | . | */ /* | | . | | */ /* | . | */ /* w=1 | | . | | */ /* | [2] UV1 | --> UV1 */ /* | | . | | . */ /* | . | . */ /* | (20) | (04) .(05) | (23) | . */ /* v=0 901- - - - - - - -001---------U01---101- - - - - - - -201 . */ /* |\ | | /| . */ /* \ [1] / . */ /* | \ | | / | . */ /* \ / . */ /* | \ | | / | . */ /* \ / . */ /* | \ | | / | . */ /* \ / . */ /* | \| (21) (22) |/ | . */ /* v=-1 - - - - - - - -091- - - - - - - -191- - - - - - - - . */ /* . */ /* u=-1 u=0 u=1 u=2 . */ /* . */ /* . */ /* v=2 - - - - - - - -020- - - - - - - -120- - - - - - - - . */ /* | /| (18) (17) |\ | . */ /* / \ . */ /* | / | | \ | [3] UVW */ /* / \ . */ /* | / | | \ | . */ /* / \ . */ /* | / | | \ | . */ /* / [1] \ . */ /* |/ | | \| . */ /* v=1 910- - - - - - - -010---------U10---110- - - - - - - -210 . */ /* | (19) | (03) .(02) | (16) | . */ /* | . | . */ /* | | . | | . */ /* | . | . */ /* w=0 | | . | | . */ /* | [2] UV0 | --> UV0 */ /* | | . | | */ /* | . | */ /* | (12) | (00) .(01) | (15) | */ /* v=0 900- - - - - - - -000---------U00---100- - - - - - - -200 */ /* |\ | | /| */ /* \ [1] / */ /* | \ | | / | */ /* \ / */ /* | \ | | / | */ /* \ / */ /* | \ | | / | */ /* \ / */ /* | \| (13) (14) |/ | */ /* v=-1 - - - - - - - -090- - - - - - - -190- - - - - - - - */ /* */ /* u=-1 u=0 u=1 u=2 */ /* */ /* */ /* v=1 019- - - - - - - -119 */ /* | (11) (10) | */ /* | | */ /* | | */ /* | | */ /* w=-1 | | */ /* | | */ /* | | */ /* | | */ /* | (08) (09) | */ /* v=0 009- - - - - - - -109 */ /* */ /* u=0 u=1 */ /* */ /* */ /* v ^ w */ /* | / */ /* |/ */ /* O----> */ /* u */ /* */ /* (on trouve entre parentheses sous la forme 'mn' le numero d'acces a ce noeud de '00' */ /* -le premier traite- a '31' -le dernier-). */ Eblock ETes Test(IL_FAUT(aleat_2_____visualiser_les_mailles)) Bblock Test(IFOU(IFLE(SOUA(NEUT(_cDENORMALISE_OX(X_point_courant_du_reseau_a_l_echelle)) ,SUCX(_cDENORMALISE_OX(X_noeud_courant_du_reseau_a_l_echelle)) ) ,aleat_2_____epaisseur_de_visualisation_des_mailles ) ,IFLE(SOUA(NEUT(_cDENORMALISE_OY(Y_point_courant_du_reseau_a_l_echelle)) ,SUCY(_cDENORMALISE_OY(Y_noeud_courant_du_reseau_a_l_echelle)) ) ,aleat_2_____epaisseur_de_visualisation_des_mailles ) ) ) /* L'utilisation des fonctions '_?DENORMALISE_O?(...)' est destinee a rendre positif des */ /* tests qui ne le seraient pas, et a cause d'une petite difference "epsilonnesque"... */ /* De plus, l'absence d'un test sur les coordonnees 'Z' est logique car s'il etait fait */ /* on pourrait se trouver de temps en temps dans un plan 'Z' correspondant a un plan de */ /* type "noeud" et donc, tous les points {X,Y} seraient mis a 'borne_inferieure'... */ /* */ /* ATTENTION, l'utilisation des fonctions 'SUC?(...)' vient du phenomene suivant vu en */ /* editant, par exemple, les abscisses avec les parametres d'appels : */ /* */ /* premier=18 niveau=18 */ /* */ /* avec '$xci/fract_3D.01$X' en mode 'Sud'. On a donc : */ /* */ /* (...) */ /* X=120 point=-8 noeud=-12 */ /* */ /* X=121 point=-7 noeud=-8 */ /* X=122 point=-6 noeud=-8 */ /* X=123 point=-5 noeud=-8 */ /* X=124 point=-4 noeud=-8 */ /* */ /* X=125 point=-3 noeud=-4 */ /* X=126 point=-2 noeud=-4 */ /* X=127 point=-1 noeud=-4 */ /* */ /* X=128 point=+0 noeud=0 */ /* X=129 point=+1 noeud=0 */ /* X=130 point=+2 noeud=0 */ /* X=131 point=+3 noeud=0 */ /* */ /* X=132 point=+4 noeud=+3 */ /* X=133 point=+5 noeud=+3 */ /* X=134 point=+6 noeud=+3 */ /* X=135 point=+7 noeud=+3 */ /* */ /* X=136 point=+8 noeud=+7 */ /* (...) */ /* */ /* ainsi, les mailles ont d'une part toute la meme dimension (ici 4) sauf celle qui precede */ /* l'origine, et d'autre part le premier point d'une maille (par exemple +4) suit le noeud */ /* (par exemple +3), d'ou les fonctions 'SUC?(...)'... */ Bblock EGAL(fonction___au_point_uUvVwW ,COND(IL_FAUT(aleat_2_____visualiser_les_mailles__avec__borne_inferieure) ,borne_inferieure ,aleat_2_____visualiser_les_mailles__avec__une_valeur_donnee ) ); /* Lorsqu'il faut visualiser le maillage, on force 'borne_inferieure' comme valeur de la */ /* fonction. On notera l'aspect non optimise de cela, puisque la fonction vient d'etre */ /* calculee, et qu'on ignore cette valeur... */ /* */ /* Le 20111019100232 fut introduite la possibilite de visualiser les mailles avec une */ /* valeur donnee unique et arbitraire... */ Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes INCR(niveau_courant ,MUL2(ITb1(coefficients_de_ponderation,INDX(niveau,FIRST_NIVEAU_DE_RECURSION)) ,fonction___au_point_uUvVwW ) ); /* Cumul de la contribution du niveau courant a la fonction fractale... */ Eblock EDoI storeF_point(niveau_courant,champ_fractal,X,Y); /* Et enfin, memorisation bi-dimensionnelle de la somme fractale tri-dimensionnelle */ /* ponderee au point {X,Y,Z}. */ Eblock end_image Test(IL_FAUT(IFfractal_3D_precises_____renormaliser_le_champ_automatiquement)) /* Test introduit le 20090303102818... */ Bblock BDEFV(imageF,champ_fractal_renormalise); /* Champ fractal Resultat renormalise... */ CALS(IFnormalisation_automatique(champ_fractal_renormalise,champ_fractal)); /* Et renormalisation... */ CALS(IFmove(champ_fractal,champ_fractal_renormalise)); EDEFV(imageF,champ_fractal_renormalise); /* Champ fractal Resultat renormalise... */ Eblock ATes Bblock Eblock ETes RETIF(champ_fractal); Eblock EFonctionF #undef COORDONNEE_1_W #undef COORDONNEE_W_0 #undef COORDONNEE_1_V #undef COORDONNEE_V_0 #undef COORDONNEE_1_U #undef COORDONNEE_U_0 #undef CENTRAGE_FRACTAL_OZ #undef CENTRAGE_FRACTAL_OY #undef CENTRAGE_FRACTAL_OX #undef INTERPOLATION_FRACTALE_3D_Z #undef INTERPOLATION_FRACTALE_3D_Y #undef INTERPOLATION_FRACTALE_3D_X #undef INTERPOLATION_FRACTALE_3D #undef CALCUL_NOEUD_3D_COURANT_DILATE #undef CALCUL_NOEUD_3D_COURANT #undef RDN_FRACTAL_3D #undef REPLIEMENT_3D #undef REPLIEMENT_OZ #undef REPLIEMENT_OY #undef REPLIEMENT_OX #undef TRANSFORMATION_OZ #undef TRANSFORMATION_OY #undef TRANSFORMATION_OX #undef REDUCTION_PONDERATION #undef REDUCTION_OZ #undef REDUCTION_OY #undef REDUCTION_OX /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H A M P F R A C T A L " S T A N D A R D " S P A T I A L E M E N T T R I - D I M E N S I O N N E L */ /* O U S P A T I A L E M E N T B I - D I M E N S I O N N E L E T V A R I A B L E D A N S L E T E M P S : */ /* */ /*************************************************************************************************************************************/ BFonctionP DEFV(Common,DEFV(FonctionP,POINTERp(Ifractal_3D(imageR ,Zf ,X_puissance_de_reduction ,Y_puissance_de_reduction ,Z_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,ARGUMENT_POINTERs(facteur_d_echelle) ,ARGUMENT_POINTERs(translation2) ,ARGUMENT_POINTERs(origine_du_repliement) ,ARGUMENT_POINTERs(extremite_du_repliement) ,ARGUMENT_POINTERs(maille_initiale) ) ) ) ) DEFV(Argument,DEFV(image,imageR)); /* Image Resultat, telle que : imageR[X][Y]=fractal(X,Y). */ DEFV(Argument,DEFV(Float,Zf)); /* Coordonnee 'Z' flottante donnant dans un segment du type [0,1] la tranche */ /* verticale dans laquelle on genere la coupe bi-dimensionnelle du champ */ /* fractal tri-dimensionnel ou spatio-temporel. */ DEFV(Argument,DEFV(Float,X_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OX pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Y_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OY pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,Z_puissance_de_reduction)); /* Puissance a laquelle est elevee une longueur sur l'axe OZ pour la reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Float,P_puissance_de_reduction)); /* Puissance a laquelle est elevee un coefficient de ponderation pour le reduire */ /* recursivement (0.9 est une bonne valeur...). */ DEFV(Argument,DEFV(Int,dernier_niveau_de_recursion_demande)); /* Niveau de recursion demande, c'est-a-dire le nombre de reductions */ /* recursives realisees. */ DEFV(Argument,DEFV(Int,graine)); /* Graine arbitraire dont depend la generation. */ DEFV(Argument,DEFV(Float,borne_inferieure)); /* Borne inferieure du generateur ; 'NOIR' est une bonne valeur. */ DEFV(Argument,DEFV(Float,borne_superieure)); /* Borne superieure du generateur ; 'BLANC' est une bonne valeur. */ DEFV(Argument,DEFV(coeffF_3D,POINTERs(facteur_d_echelle))); /* Facteur d'echelle du champ suivant les trois dimensions. */ DEFV(Argument,DEFV(deltaF_3D,POINTERs(translation2))); /* Translation du champ exprimee dans des unites telles que l'unite represente */ /* respectivement [Xmin,Xmax], [Ymin,Ymax] et [Zmin,Zmax]. */ DEFV(Argument,DEFV(pointF_3D,POINTERs(origine_du_repliement))); /* Origine du champ afin de pouvoir generer le champ sur un 3D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Voir de plus le commentaire suivant... */ DEFV(Argument,DEFV(pointF_3D,POINTERs(extremite_du_repliement))); /* Extremite du champ afin de pouvoir generer le champ sur un 3D-tore ; elle est */ /* exprimee dans des unites telles que l'unite represente respectivement */ /* [Xmin,Xmax] et [Ymin,Ymax]. Mais ATTENTION : lorsque le mode repliement */ /* d'un champ sur un tore, la reduction du maillage ne se fait plus par une */ /* exponentielle (voir 'puissance_de_reduction'), mais par une dichotomie */ /* (divisions par 2 successives) ; de plus, la maille initiale doit etre */ /* une puissance de 2 (pour la dichotomie) et diviser exactement la longueur */ /* du tore (ceci etant valable pour les trois directions 'X', 'Y' et 'Z' */ /* simultanement). */ DEFV(Argument,DEFV(deltaF_3D,POINTERs(maille_initiale))); /* Definition de la maille de base qui sera ensuite reduite recursivement ; elle */ /* est exprime dans des unites telles que l'unite represente */ /* respectivement 'dimX', 'dimY' et 'dimZ'. Voir de plus le commentaire precedent. */ /* */ /* ATTENTION, en cas d'utilisation de tres grandes valeurs (par rapport a 1) pour la */ /* maille initiale, il pourra etre necessaire d'augmenter correlativement la valeur du */ /* parametre 'rdnF3D_etendu_____extension' defini dans 'v $ximf/aleatoires$FON'. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock BDEFV(imageF,champ_fractal); /* Champ fractal flottant, tel que : champ[X][Y]=fractal(X,Y). */ /*..............................................................................................................................*/ CALS(IFfractal_3D_precises(champ_fractal ,Zf ,X_puissance_de_reduction ,Y_puissance_de_reduction ,Z_puissance_de_reduction ,P_puissance_de_reduction ,dernier_niveau_de_recursion_demande ,graine,borne_inferieure,borne_superieure ,facteur_d_echelle ,translation2 ,origine_du_repliement ,extremite_du_repliement ,maille_initiale ) ); /* Generation du champ fractal tridimensionnel avec toute la precision possible... */ CALS(Ifloat_std_avec_renormalisation(imageR,champ_fractal)); /* Et enfin, conversion du champ flottant en une image... */ EDEFV(imageF,champ_fractal); /* Champ fractal flottant, tel que : champ[X][Y]=fractal(X,Y). */ RETI(imageR); Eblock EFonctionP #undef NOEUD_AVANT #undef NOEUD_APRES #undef MOVE_NOEUD #undef DETECTEUR_DE_BOUCLAGE_DE_MOVE_NOEUD #undef Z_point_courant_du_reseau_minimal #undef Y_point_courant_du_reseau_minimal #undef X_point_courant_du_reseau_minimal #undef Z_point_courant_du_reseau_eventuellement_dilate #undef Y_point_courant_du_reseau_eventuellement_dilate #undef X_point_courant_du_reseau_eventuellement_dilate #undef Z_point_courant_du_reseau_a_l_echelle #undef Y_point_courant_du_reseau_a_l_echelle #undef X_point_courant_du_reseau_a_l_echelle %undef Z_noeud_courant_du_reseau_eventuellement_dilate %undef Y_noeud_courant_du_reseau_eventuellement_dilate %undef X_noeud_courant_du_reseau_eventuellement_dilate #undef Z_noeud_courant_du_reseau_a_l_echelle #undef Y_noeud_courant_du_reseau_a_l_echelle #undef X_noeud_courant_du_reseau_a_l_echelle %undef Z_centre_du_champ %undef Y_centre_du_champ %undef X_centre_du_champ %undef Z_maille %undef Y_maille %undef X_maille #undef VALIDATION_PONDERATION #undef VALIDATION_MAILLE_OZ #undef VALIDATION_MAILLE_OY #undef VALIDATION_MAILLE_OX #ifdef CALCUL_DES_NEUDS_VERSION_02 # undef CALCUL_D_UN_NOEUD #Aifdef CALCUL_DES_NEUDS_VERSION_02 #Eifdef CALCUL_DES_NEUDS_VERSION_02 #ifdef CALCUL_DES_NEUDS_VERSION_01 # undef CALCUL_D_UN_NOEUD #Aifdef CALCUL_DES_NEUDS_VERSION_01 #Eifdef CALCUL_DES_NEUDS_VERSION_01 #undef CALCUL_DES_NEUDS_VERSION_02 #undef FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_21_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_11_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_04_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_03_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_02_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef COMPOSANTE_01_DE_LA_FONCTION_GENERALE_DE_REDUCTION #undef INVERSE_DE_L_EXPOSANT #undef EPSILON #undef PREPARATION_DE_L_UTILISATION_DES_LISTES_DE_SUBSTITUTION #undef PREPARATION_DE_L_UTILISATION_D_UNE_LISTE_DE_SUBSTITUTION #undef liste_de_substitution_Z_DANS_IFfractal #undef liste_de_substitution_Y_DANS_IFfractal #undef liste_de_substitution_X_DANS_IFfractal #undef TRANSFORMATION_COORDONNEE_BARYCENTRIQUE #undef ARRI_FRACTAL_MAILLE #undef ARRI_FRACTAL_COORDONNEE_NOEUD #undef ARRI_FRACTAL_COORDONNEE #undef ARRI_FRACTAL #undef LAST_NIVEAU_DE_RECURSION #undef NIVEAU_DE_RECURSION #undef Z_facteur_d_echelle #undef Y_facteur_d_echelle #undef X_facteur_d_echelle #undef TRANSLATION_TORIQUE #undef DIMENSION_D_UN_TORE #undef DERIVATION_NUMERIQUE #undef NORMALISATION_DES_FONCTIONS_A_DERIVER _______________________________________________________________________________________________________________________________________