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