/*************************************************************************************************************************************/
/* */
/* C A L C U L D E L ' E N S E M B L E D E J U L I A */
/* S U I V A N T U N E E Q U I P O T E N T I E L L E D E */
/* L ' E N S E M B L E D E M A N D E L B R O T */
/* D A N S L ' E S P A C E H Y P E R - C O M P L E X E : */
/* */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * ** * * * * * ** * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * ** * * * * * ** */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* */
/* ATTENTION : */
/* */
/* Ce programme, avant le 19970206000000, */
/* ne calculait en fait correctement que */
/* des images au format carre ('Std' par */
/* exemple). Il a fallu introduire les */
/* fonction 'CHANGEMENT_HOMOTHETIQUE...(...)' */
/* pour corriger cette anomalie... */
/* */
/* */
/* Note sur la generation de couples stereoscopiques : */
/* */
/* Pour generer un couple stereoscopique, il */
/* suffit de faire deux fois l'accumulation, */
/* c'est-a-dire une fois pour chaque oeil, avec */
/* les parametres suivants : */
/* */
/* $DROITE : translation_quelconque=VRAI try=0 trx=+2.0e-4 */
/* $GAUCHE : translation_quelconque=VRAI try=0 trx=-2.0e-4 */
/* */
/* lorsque l'on empile d'arriere en avant. Il faut noter que pour */
/* generer la vue de l'oeil '$DROITE' il faut decaler a gauche, alors */
/* que pour generer celle de l'oeil '$GAUCHE', il faut decaler a droite. */
/* Les signes de "trx=" sont inverses, car en effet, la variable */
/* 'RRtranslation' evolue a coup de 'DECR(...)', d'ou l'inversion des */
/* signes de "trx=". De plus, et dans ces conditions, il faudra faire */
/* tres ATTENTION au parametre "inverser=" (c'est-a-dire a la variable */
/* 'inverser_l_ordre_de_recuperation_des_images') qui alors a pour effet */
/* de permuter les vues des deux yeux. On notera enfin que la translation */
/* implicite 'trx' vaut : */
/* */
/* 1 -4 -4 */
/* ----- = 9.765625 x 10 ~ 10 x 10 */
/* 512 */
/* */
/* la translation 'trx' utilisee est donc choisie egale au cinquieme de */
/* cette valeur (d'ou le "2.0e-4"). */
/* */
/* */
/* Author of '$xrc/julia.42$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1992??????????). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
@define PRAGMA_CL_____MODULE_NON_OPTIMISABLE
#define GENERER_LES_GET_ARGUMENTS_DE_CONTROLE_DE_L_ARITHMETIQUE_ETENDUE_DES_NOMBRES_FLOTTANTS
/* Introduit le 20070129112806... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_BASE
#include image_image_CONTOURS_EXT
#include maths_compl_fonct_ITERATIONS_EXT
#include image_image_QUAD_IMAGE_EXT
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D E B A S E E T U N I V E R S E L L E S : */
/* */
/*************************************************************************************************************************************/
#define NOMBRE_DE_PERIODES_DE_LA_SIMULATION \
UN \
/* Definition du nombre de periodes pour '$xrq/nucleon.L3$I'. */
#define EDITER_UNIQUEMENT_LES_POINTS_DU_CONTOUR \
FAUX \
/* Indique si l'on ne fait qu'editer les points du contour ('VRAI') ou bien si l'on calcule */ \
/* evidemment les images ('FAUX'). Cela fut introduit le 20190321094653... */
#include xrk/attractor.11.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define COMPATIBILITE_20190321 \
FAUX \
/* Permet de proceder a des generations compatibles a celles qui furent effectues */ \
/* anterieurement au 20190321131310. */
#define M_FENETRE_GAUCHE \
PARE(-2.0)
#define M_FENETRE_DROITE \
PARE(0.5)
#define vM_FENETRE_GAUCHE \
CHANGEMENT_HOMOTHETIQUE_D_ABSCISSE_GAUCHE(M_FENETRE_GAUCHE,M_FENETRE_DROITE)
#define vM_FENETRE_DROITE \
CHANGEMENT_HOMOTHETIQUE_D_ABSCISSE_DROITE(M_FENETRE_GAUCHE,M_FENETRE_DROITE)
#define M_FENETRE_GD \
SOUS(vM_FENETRE_DROITE,vM_FENETRE_GAUCHE)
#define M_FENETRE_BAS \
PARE(-1.25)
#define M_FENETRE_HAUT \
PARE(1.25)
#define vM_FENETRE_BAS \
CHANGEMENT_HOMOTHETIQUE_D_ORDONNEE_BAS(M_FENETRE_BAS,M_FENETRE_HAUT)
#define vM_FENETRE_HAUT \
CHANGEMENT_HOMOTHETIQUE_D_ORDONNEE_HAUT(M_FENETRE_BAS,M_FENETRE_HAUT)
#define M_FENETRE_BH \
SOUS(vM_FENETRE_HAUT,vM_FENETRE_BAS)
/* Definition de la fenetre de calcul de l'ensemble de Mandelbrot. */
#define M_COMPOSANTE_J \
FZERO
#define M_COMPOSANTE_K \
FZERO
/* Definition des composantes 'J' et 'K' des quaternions pour l'ensemble de Mandelbrot. */
#define M_NOMBRE_D_ITERATIONS \
QUAR(COULEURS) \
/* Nombre d'iterations demandees pour le calcul de l'ensemble de Mandelbrot. */
#define SEUIL_D_EXTRACTION_DU_CONTOUR \
GENP(MUL2(FLOT(PRED(PRED(PRED(PRED(PRED(MOIT(GRIS_1))))))) \
,DIVI(FLOT__BLANC,FLOT(M_NOMBRE_D_ITERATIONS)) \
) \
) \
/* Seuil d'extraction du contour, c'est-a-dire numero de l'equipotentielle. */
#define E_DEPART_X \
_____cNORMALISE_OX(COND(IL_FAUT(compatibilite_20190321),I_cHOMOTHETIE_Std_OX(Xmin),Xmin))
#define E_DEPART_Y \
_____cNORMALISE_OY(COND(IL_FAUT(compatibilite_20190321),I_cHOMOTHETIE_Std_OY(Ymin),Ymin))
/* Point de depart de l'extraction de l'equipotentielle. */
/* */
/* Le 20120212101315, les 'I_cHOMOTHETIE_Std_O?(...)'s furent introduits... */
#define NOMBRE_DE_CONTOURS \
HUIT \
/* Nombre de contours interieurs a l'equipotentielle a extraire pour definir */ \
/* le vrai contour que l'on va suivre ; s'il est nul, on prend directement */ \
/* equipotentielle... */
#define C_DEPART_X \
_____cNORMALISE_OX(COND(IL_FAUT(compatibilite_20190321),I_cHOMOTHETIE_Std_OX(Xcentre),Xcentre))
#define C_DEPART_Y \
_____cNORMALISE_OY(COND(IL_FAUT(compatibilite_20190321),I_cHOMOTHETIE_Std_OY(Ycentre),Ycentre))
/* Point de depart de l'extraction de contour. */
/* */
/* Le 20120212101315, les 'I_cHOMOTHETIE_Std_O?(...)'s furent introduits... */
#define CONTOUR \
BLANC \
/* Niveau de marquage du contour... */
#define CALCUL \
ZERO \
/* Lorsque 'sauts_des_calculs' vaut 'CALCUL', l'image courante est */ \
/* generee ; en fait, on ne calcule qu'une image sur 'pas_de_calcul'... */
#define PAS_DE_CALCUL \
PAR0(QUATORZE) \
/* Pour une image calculee, on en saute 'pas_de_calcul'-1 ; ce nombre doit */ \
/* etre pair afin de limiter au maximum les effets de saccades (en marches */ \
/* d'escalier) lors du suivi des obliques du contour. */
#define FAIRE_LES_ACCUMULATIONS \
VRAI \
/* Faut-il faire les accumulations ('VRAI') ou bien se contenter de generer les differentes */ \
/* couches ('FAUX') ? Cela a ete introduit le 20100208133743 a cause du produit non */ \
/* theorique... */
#define J_FENETRE_GAUCHE \
PARE(-1.0)
#define J_FENETRE_DROITE \
PARE(1.0)
#define vJ_FENETRE_GAUCHE \
CHANGEMENT_HOMOTHETIQUE_D_ABSCISSE_GAUCHE(J_FENETRE_GAUCHE,J_FENETRE_DROITE)
#define vJ_FENETRE_DROITE \
CHANGEMENT_HOMOTHETIQUE_D_ABSCISSE_DROITE(J_FENETRE_GAUCHE,J_FENETRE_DROITE)
#define J_FENETRE_BAS \
PARE(-1.0)
#define J_FENETRE_HAUT \
PARE(1.0)
#define vJ_FENETRE_BAS \
CHANGEMENT_HOMOTHETIQUE_D_ORDONNEE_BAS(J_FENETRE_BAS,J_FENETRE_HAUT)
#define vJ_FENETRE_HAUT \
CHANGEMENT_HOMOTHETIQUE_D_ORDONNEE_HAUT(J_FENETRE_BAS,J_FENETRE_HAUT)
/* Definition de la fenetre de depart des ensembles de Julia. */
#define J_COMPOSANTE_J \
FZERO
#define J_COMPOSANTE_K \
FZERO
/* Definition des composantes 'J' et 'K' des quaternions pour les ensembles de Julia. */
#define J_NOMBRE_D_ITERATIONS \
SOIXANTE_QUATRE \
/* Nombre d'iterations demandees pour les ensembles de Julia. */
#define VISUALISATION_ARGUMENTS_DE_SORTIE \
FAUX
#define PONDERATION_ARGUMENTT \
FU
#define PONDERATION_ARGUMENTP \
FZERO
#define PONDERATION_ARGUMENTA \
FZERO
/* Faut-il visualiser les arguments de sortie ('VRAI'), auquel cas les trois parametres */
/* suivants sont les ponderations des 3 angles {T,P,A}, ou les equipotentielles ('FAUX'). */
#define NOMBRE_DE_COUCHES_BIDIMENSIONNELLES \
CENT_VINGT_HUIT \
/* Nombre de couches bidimensionnelles a empiler... */
#define PREMIERE_IMAGE_ABSOLUE_J \
NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION \
/* Premiere image de la sequence ; en fait il se peut qu'elle ne */ \
/* soit pas generee (voir 'PREMIERE_IMAGE'). */
#define PREMIERE_IMAGE \
PREMIERE_IMAGE_ABSOLUE_J \
/* Numero de la premiere image a generer : ce parametre permet de faire une reprise sur une */ \
/* sequence interrompue. On notera qu'habituellement sa valeur est 'PREMIERE_IMAGE_ABSOLUE', */ \
/* mais que pour des raisons de compatibilite avec les differents modules inclus dans ce */ \
/* programme, on lui substitue 'NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION' partout... */
#define DERNIERE_IMAGE \
INFINI \
/* Numero de la derniere image a generer : ce parametre permet de s'arreter en cours de */ \
/* route... */
#define premiere_couche \
NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION
#define derniere_couche \
LSTX(NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION,nombre_de_couches_bidimensionnelles)
/* Pour des raisons de compatibilite... */
#define INVERSER_L_ORDRE_DE_RECUPERATION_DES_IMAGES \
FAUX \
/* Indique s'il faut inverser l'ordre de parcours de l'ensemble des images. On a : */ \
/* */ \
/* FAUX : l'image d'arriere-plan est la premiere de la liste, */ \
/* VRAI : l'image d'arriere-plan est la derniere de la liste. */ \
/* */
#define ACCUMULER_PAR_TRANSPARENCE \
FAUX \
/* Faut-il faire une accumulation de type '$xci/accumule.01$K' ('VRAI') ou bien de type */ \
/* '$xci/accumule.02$K' ('FAUX') ? */
#define FACTEUR_D_ATTENUATION \
FU \
/* Facteur destine a attenuer (eventuellement) les images, la premiere etant en general */ \
/* plus attenuee que la derniere, car elle correspond dans une sequence temporelle a un */ \
/* instant plus ancien (la valeur 'FU' correspond a l'absence...). On notera que si ce */ \
/* facteur est nul, il est alors calcule automatiquement de facon que : */ \
/* */ \
/* (derniere_couche - premiere_couche + 1) */ \
/* BLANC.(facteur_d_attenuation) = 1. */ \
/* */ \
/* ce qui permet d'exploiter au mieux la dynamique des niveaux de gris, la derniere image */ \
/* se trouvant tres pres du NOIR. A titre d'exemple, lors d'un calcul portant sur 128 */ \
/* images, on a : */ \
/* */ \
/* facteur_d_attenuation = 0.957633 */ \
/* */
#define FACTEUR_A \
FU
#define FACTEUR_B \
FZERO
/* Facteurs destines a transformer lineairement le numero de couche (A.n + B). */
#define PRENDRE_UNE_DYNAMIQUE_LOGARITHMIQUE \
FAUX \
/* Faut-il prendre une dynamique logarithmique ('VRAI') ou laisser les accumulations telles */ \
/* qu'elles ont ete calculees ('FAUX') ? ATTENTION, ceci n'a de sens que lorsque l'on */ \
/* procede par cumul arithmetique (voir 'RECHERCHE_DU_MAXIMUM'), et de plus, lorsque le */ \
/* logarithme est utilise, la renormalisation est forcee... */
#define RECHERCHE_DU_MAXIMUM \
FAUX \
/* Faut-il rechercher le maximum ('VRAI') ou proceder par cumul arithmetique ('FAUX') ? */
#define IL_FAUT_RENORMALISER_LES_IMAGES \
VRAI \
/* Faut-il renormaliser l'image ? */
#define CALCULER_LE_SEUIL_DE_MASQUAGE \
FAUX \
/* Faut-il calculer automatiquement ('VRAI') le seuil de masquage a l'aide de l'histogramme */ \
/* "cumule" ou bien le fixer a priori ('FAUX'). */
#define FRACTION_DE_POINTS_POUR_CALCULER_LE_SEUIL_DE_MASQUAGE \
FRA10(FU) \
/* Lorsqu'il faut calculer le seuil de masquage ce parametre donne le pourcentage des */ \
/* points a prendre en compte pour le masque. */
#define SEUIL_DE_MASQUAGE \
GRIS_6 \
/* Seuil de masquage. */
#define BINARISER_LES_IMAGES \
VRAI \
/* Indicateur precisant s'il faut ('VRAI') ou pas ('FAUX') binariser les images. */
#define PREMIERE_TRANCHE_VERTICALE \
Zmin \
/* Premiere tranche verticale, */
#define DERNIERE_TRANCHE_VERTICALE \
Zmax \
/* Derniere tranche verticale. */
#include xci/accumule.01.I"
#define PAS_HORIZONTAL \
_____lNORMALISE_OX(I_lHOMOTHETIE_Std_OX(PasX))
#define PAS_VERTICAL \
_____lNORMALISE_OY(I_lHOMOTHETIE_Std_OY(PasY))
/* Pas de decalage des differentes images... */
/* */
/* Le 20120212101315, les 'I_lHOMOTHETIE_Std_O?(...)'s furent introduits... */
#define EDITER_LE_NOMBRE_ARGUMENT_DES_JULIAS \
FAUX \
/* Indique s'il faut editer pour chaque calcul d'un ensemble de Julia le quaternion */ \
/* argument ('VRAI') ou pas ('FAUX'). */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#include xrc/ITERATION.11.I"
/* Introduit le 20091120123304... */
#define GENERATEUR_REEL \
AXPB(M_FENETRE_GD,ASD1(point_courant_extrait,x),vM_FENETRE_GAUCHE)
#define GENERATEUR_IMAGINAIRE \
AXPB(M_FENETRE_BH,ASD1(point_courant_extrait,y),vM_FENETRE_BAS)
/* Definition du generateur de l'ensemble de Julia. */
#define DEFINE_CONTOUR(logique1,logique2) \
Bblock \
BoIn(niveau,NOIR,SEUIL_D_EXTRACTION_DU_CONTOUR,I) \
Bblock \
EGAL(ITb1(exterieur,INDX(niveau,NOIR)),logique1); \
EGAL(ITb1(interieur,INDX(niveau,NOIR)),logique2); \
Eblock \
EBoI \
BoIn(niveau,SUCC(SEUIL_D_EXTRACTION_DU_CONTOUR),BLANC,I) \
Bblock \
EGAL(ITb1(exterieur,INDX(niveau,NOIR)),logique2); \
EGAL(ITb1(interieur,INDX(niveau,NOIR)),logique1); \
Eblock \
EBoI \
Eblock \
/* Definition de l'interieur et de l'exterieur d'un contour. */
#define NUMERO_DE_LA_COUCHE \
COND(IL_NE_FAUT_PAS(inverser_l_ordre_de_recuperation_des_images) \
,numero_de_la_couche \
,SOUS(derniere_couche,SOUS(numero_de_la_couche,premiere_couche)) \
) \
/* Fonction de calcul du numero de l'image courante lors de l'accumulation des images de */ \
/* manoeuvre. */
#include xci/accumule.02.I"
#define ATTENUATION_DE_LA_COUCHE_COURANTE(a,x,b) \
COND(IZEQ(x) \
,x \
,AXPB(a,x,b) \
) \
/* Definition de la transformation du numero d'image 'x' : c'est 'AXPB(a,x,b)' sauf si 'x' */ \
/* est nul, auquel cas la forme lineaire est nulle... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D E S R O T A T I O N S T R I D I M E N S I O N N E L L E S : */
/* */
/*************************************************************************************************************************************/
#include xrc/julia.41.I"
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E F I N I T I O N S D E L ' I N T E R P O L A T I O N D E S P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
dfTRANSFORMAT_31(liste_J_COMPOSANTE_J,fichier_J_COMPOSANTE_J,J_COMPOSANTE_J_IMPLICITE,J_COMPOSANTE_J)
dfTRANSFORMAT_31(liste_J_COMPOSANTE_K,fichier_J_COMPOSANTE_K,J_COMPOSANTE_K_IMPLICITE,J_COMPOSANTE_K)
/* Definition du fichier des composantes 'J' et 'K' des quaternions. */
#define sJ_COMPOSANTE_J(numero_de_la_periode) \
sTRANSFORMAT_31(numero_de_la_periode,liste_J_COMPOSANTE_J)
#define sJ_COMPOSANTE_K(numero_de_la_periode) \
sTRANSFORMAT_31(numero_de_la_periode,liste_J_COMPOSANTE_K)
/* Formule generale definissant les variations des composantes 'J' et 'K' des quaternions. */
#define nombre_de_periodes_de_la_simulation \
nombre_de_couches_bidimensionnelles \
/* Pour assurer la compatibilite avec '$xrq/nucleon.Lf.2.I'... */
/* ATTENTION, autrefois, il y avait ici : */
/* */
/* #define numero_de_la_periode_courante \ */
/* numero_de_la_couche */
/* */
/* mais depuis l'introduction de 'CHANGEMENT_DU_POINT_DE_VUE_GEOMETRIQUE' qui lui a besoin */
/* du "vrai" 'numero_de_la_periode_courante' valant systematiquement la valeur */
/* 'NUMERO_DE_LA_PREMIERE_PERIODE', il est imperatif de mettre ces definitions apres... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* C A L C U L D E L ' E N S E M B L E D E J U L I A */
/* S U I V A N T U N E E Q U I P O T E N T I E L L E D E */
/* L ' E N S E M B L E D E M A N D E L B R O T */
/* D A N S L ' E S P A C E H Y P E R - C O M P L E X E : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Logical,INIT(compatibilite_20190321,COMPATIBILITE_20190321));
/* Permet de proceder a des generations compatibles a celles qui furent effectues */
/* anterieurement au 20190321131310. */
DEFV(Logical,INIT(editer_uniquement_les_points_du_contour,EDITER_UNIQUEMENT_LES_POINTS_DU_CONTOUR));
/* Indique si l'on ne fait qu'editer les points du contour ('VRAI') ou bien si l'on calcule */
/* evidemment les images ('FAUX'). Cela fut introduit le 20190321094653... */
DEFV(complexe,M_coin_bas_gauche);
DEFV(complexe,M_coin_haut_droite);
/* Definition de la fenetre de calcul de l'ensemble de Mandelbrot. */
DEFV(Float,INIT(M_composante_J,M_COMPOSANTE_J));
DEFV(Float,INIT(M_composante_K,M_COMPOSANTE_K));
/* Definition des composantes 'J' et 'K' des quaternions pour l'ensemble de Mandelbrot. */
DEFV(Positive,INIT(M_nombre_maximal_d_iterations,M_NOMBRE_D_ITERATIONS));
/* Nombre maximal d'iterations a effectuer pour le calcul de l'ensemble de Mandelbrot. */
DEFV(Int,INIT(saut_des_calculs,CALCUL));
/* Permet de ne calculer qu'un ensemble partiel de Mandelbrot sur 'pas_de_calcul'. */
DEFV(Int,INIT(pas_de_calcul,PAS_DE_CALCUL));
/* Pour une image calculee, on en saute 'pas_de_calcul'-1 ; ce nombre doit */
/* etre pair afin de limiter au maximum les effets de saccades (en marches */
/* d'escalier) lors du suivi des obliques du contour. */
DEFV(Logical,INIT(faire_les_accumulations,FAIRE_LES_ACCUMULATIONS));
/* Faut-il faire les accumulations ('VRAI') ou bien se contenter de generer les differentes */
/* couches ('FAUX') ? Cela a ete introduit le 20100208133743 a cause du produit non */
/* theorique... */
DEFV(complexe,J_coin_bas_gauche);
DEFV(complexe,J_coin_haut_droite);
/* Definition de la fenetre de calcul des ensembles de Julia. */
DEFV(Float,INIT(J_composante_J,J_COMPOSANTE_J));
DEFV(Float,INIT(J_composante_K,J_COMPOSANTE_K));
/* Definition des composantes 'J' et 'K' des quaternions pour les ensembles de Julia. */
DEFV(hyper_complexe,point_argument);
/* Nombre hyper-complexe generateur des ensembles de Julia. */
DEFV(Logical,INIT(editer_le_nombre_argument_des_julias,EDITER_LE_NOMBRE_ARGUMENT_DES_JULIAS));
/* Indique s'il faut editer pour chaque calcul d'un ensemble de Julia le quaternion */
/* argument ('VRAI') ou pas ('FAUX'). */
DEFV(Positive,INIT(J_nombre_d_iterations,J_NOMBRE_D_ITERATIONS));
/* Nombre maximal d'iterations a effectuer pour le calcul des ensembles de Julia. */
DEFV(Logical,INIT(visualisation_arguments_de_sortie,VISUALISATION_ARGUMENTS_DE_SORTIE));
DEFV(Float,INIT(ponderation_argumentT,PONDERATION_ARGUMENTT));
DEFV(Float,INIT(ponderation_argumentP,PONDERATION_ARGUMENTP));
DEFV(Float,INIT(ponderation_argumentA,PONDERATION_ARGUMENTA));
/* Faut-il visualiser les arguments de sortie ('VRAI'), auquel cas les trois parametres */
/* suivants sont les ponderations des 3 angles {T,P,A}, ou les equipotentielles ('FAUX'). */
DEFV(processus,Pextraction);
/* Processus d'extraction du contour. */
DEFV(Logical,DTb1(exterieur,COULEURS));
/* Definition de l'exterieur, */
DEFV(Logical,DTb1(interieur,COULEURS));
/* Et de l'interieur. */
DEFV(pointF_2D,point_de_depart);
/* Point de depart de l'extraction de contour. */
DEFV(Logical,INIT(fin_de_contour,FAUX));
/* Afin de connaitre le dernier point du contour, mais on n'y est pas encore... */
DEFV(pointF_2D,point_courant_extrait);
/* Point courant extrait du contour dans [0,1]. */
DEFV(genere_p,INIT(niveau_de_marquage_du_contour,CONTOUR));
/* Niveau de marquage du contour extrait. */
DEFV(Logical,INIT(emission_des_points,VRAI));
/* Afin de transmettre les points du contour... */
DEFV(Int,INIT(nombre_de_couches_bidimensionnelles,NOMBRE_DE_COUCHES_BIDIMENSIONNELLES));
/* Nombre de couches d'ensemble de Julia a empiler. */
DEFV(Logical,INIT(inverser_l_ordre_de_recuperation_des_images,INVERSER_L_ORDRE_DE_RECUPERATION_DES_IMAGES));
/* Indique s'il faut inverser l'ordre de parcours de l'ensemble des images. On a : */
/* */
/* FAUX : l'image d'arriere-plan est la premiere de la liste, */
/* VRAI : l'image d'arriere-plan est la derniere de la liste. */
/* */
DEFV(Int,INIT(premiere_image,PREMIERE_IMAGE));
/* Numero de la premiere image a generer : ce parametre permet de faire une reprise sur une */
/* sequence interrompue. On notera qu'habituellement sa valeur est 'PREMIERE_IMAGE_ABSOLUE', */
/* mais que pour des raisons de compatibilite avec les differents modules inclus dans ce */
/* programme, on lui substitue 'NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION' partout... */
DEFV(Int,INIT(derniere_image,DERNIERE_IMAGE));
/* Numero de la derniere image a generer : ce parametre permet de s'arreter en cours de */
/* route... */
DEFV(Int,INIT(numero_de_la_couche,NUMERO_DE_LA_PREMIERE_PERIODE_DE_LA_SIMULATION));
/* Numero de l'image courante (celle-ci n'est pas necessairement generee : voir */
/* le parametre 'PREMIERE_IMAGE'). */
DEFV(Logical,INIT(accumuler_par_transparence,ACCUMULER_PAR_TRANSPARENCE));
/* Faut-il faire une accumulation de type '$xci/accumule.01$K' ('VRAI') ou bien de type */
/* '$xci/accumule.02$K' ('FAUX') ? */
DEFV(Logical,INIT(prendre_une_dynamique_logarithmique,PRENDRE_UNE_DYNAMIQUE_LOGARITHMIQUE));
/* Faut-il prendre une dynamique logarithmique ('VRAI') ou laisser les accumulations telles */
/* qu'elles ont ete calculees ('FAUX') ? ATTENTION, ceci n'a de sens que lorsque l'on */
/* procede par cumul arithmetique (voir 'RECHERCHE_DU_MAXIMUM'), et de plus, lorsque le */
/* logarithme est utilise, la renormalisation est forcee... */
DEFV(Logical,INIT(rechercher_le_maximum,RECHERCHE_DU_MAXIMUM));
/* Faut-il rechercher le maximum ('VRAI') ou proceder par cumul arithmetique ('FAUX') ? */
DEFV(Float,INIT(facteur_d_attenuation,FACTEUR_D_ATTENUATION));
/* Facteur destine a attenuer (eventuellement) les images, la premiere etant en general */
/* plus attenuee que la derniere, car elle correspond dans une sequence temporelle a un */
/* instant plus ancien (la valeur 'FU' correspond a l'absence...). On notera que si ce */
/* facteur est nul, il est alors calcule automatiquement de facon que : */
/* */
/* (derniere_couche - premiere_couche + 1) */
/* BLANC.(facteur_d_attenuation) = 1. */
/* */
/* ce qui permet d'exploiter au mieux la dynamique des niveaux de gris, la derniere image */
/* se trouvant tres pres du NOIR. A titre d'exemple, lors d'un calcul portant sur 128 */
/* images, on a : */
/* */
/* facteur_d_attenuation = 0.957633 */
/* */
DEFV(Float,INIT(facteur_A,FACTEUR_A));
DEFV(Float,INIT(facteur_B,FACTEUR_B));
/* Facteurs destines a transformer lineairement le numero de couche (A.n + B). */
DEFV(Float,INIT(facteur_d_attenuation_courant,FLOT__UNDEF));
/* Facteur d'attenuation de la couche courante qui vaut 'facteur_d_attenuation' eleve a */
/* une puissance qui est le rang de cette couche... */
DEFV(Float,INIT(attenuation_globale,FLOT__UNDEF));
/* Cumul des 'facteur_d_attenuation_courant's afin de calculer l'image finale lorsqu'il */
/* n'y a pas de renormalisation automatique... */
DEFV(Logical,INIT(calculer_le_seuil_de_masquage,CALCULER_LE_SEUIL_DE_MASQUAGE));
/* Faut-il calculer automatiquement ('VRAI') le seuil de masquage a l'aide de l'histogramme */
/* "cumule" ou bien le fixer a priori ('FAUX'). */
DEFV(Float,INIT(fraction_de_points_pour_calculer_le_seuil_de_masquage
,FRACTION_DE_POINTS_POUR_CALCULER_LE_SEUIL_DE_MASQUAGE
)
);
/* Lorsqu'il faut calculer le seuil de masquage ce parametre donne le pourcentage des */
/* points a prendre en compte pour le masque. */
DEFV(genere_p,INIT(seuil_de_masquage,SEUIL_DE_MASQUAGE));
/* Seuil de masquage des differentes couches. */
DEFV(genere_p,INIT(seuil_de_masquage_utilise,NIVEAU_UNDEF));
/* Seuil de masquage reellement utilise. */
DEFV(Logical,INIT(binariser_les_images,BINARISER_LES_IMAGES));
/* Indicateur precisant s'il faut ('VRAI') ou pas ('FAUX') binariser les couches. */
DEFV(Int,INIT(premiere_tranche_verticale,PREMIERE_TRANCHE_VERTICALE));
/* Premiere tranche verticale, */
DEFV(Int,INIT(derniere_tranche_verticale,DERNIERE_TRANCHE_VERTICALE));
/* Derniere tranche verticale. */
DEFV(Int,INIT(tranche_verticale_courante,UNDEF));
/* Tranche verticale courante. */
DEFV(deltaF_2D,Atranslation);
DEFV(deltaF_2D,RAtranslation);
DEFV(deltaF_2D,RRtranslation);
/* Translation verticale d'empilement des couches... */
DEFV(Logical,INIT(translation_quelconque,TRANSLATION_QUELCONQUE));
/* Choix de la methode de translation de passage d'une couche a l'autre : */
/* */
/* FAUX : on utilise 'Itranslation(...)' qui est plus rapide, */
/* VRAI : on utilise 'Irotation_image(...)' qui est plus lent, mais presente l'avantage de */
/* permettre de faire une translation quelconque, et en particulier d'une fraction */
/* de point, ce qui autorise la production de couples stereoscopiques... */
/* */
/* ATTENTION, dans la mesure ou 'Irotation_image(...)' procede a une renormalisation des */
/* images, cette derniere ne sera pas malheureusement homogene d'une image a l'autre a */
/* l'interieur d'une meme sequence ; des artefacts seront peut-etre alors introduits... */
/* */
DEFV(Float,INIT(pas_horizontal,FLOT__UNDEF));
DEFV(Float,INIT(pas_vertical,FLOT__UNDEF));
/* Pas de variation de la translation verticale d'empilement des couches. */
DEFV(Float,INIT(facteur_stereoscopique,FACTEUR_STEREOSCOPIQUE));
/* Facteur destine a simplifier la production de couples stereoscopiques. En general, trois */
/* valeurs seront utiles : */
/* */
/* FZERO */
/* NEUT(FU) */
/* NEGA(FU) */
/* */
DEFV(Int,INIT(z_depth_cueing,UNDEF));
/* Coordonnee de "depth-cueing"... */
DEFV(CHAR,INIC(POINTERc(nom_imageR),NOM_PIPE));
/* Nom de la sequence d'images a generer. */
DEFV(CHAR,INIC(POINTERc(nom_imageM),NOM_PIPE));
/* Nom de la sequence d'images de manoeuvre a accumuler. */
DEFV(Int,INIT(nombre_de_chiffres,NOMBRE_DE_CHIFFRES));
/* Nombre de chiffres codant le numero des images de la sequence a generer. */
DEFV(CHAR,INIT(POINTERc(nom_image),NOM_UNDEF));
/* Nom courant des images. */
DEFV(Int,INIT(numero_d_image,PREMIERE_IMAGE_ABSOLUE));
/* Numero de l'image courante (celle-ci n'est pas necessairement generee : voir */
/* le parametre 'PREMIERE_IMAGE'). */
/*..............................................................................................................................*/
Cinitialisation(M_coin_bas_gauche,M_FENETRE_GAUCHE,M_FENETRE_BAS);
Cinitialisation(M_coin_haut_droite,M_FENETRE_DROITE,M_FENETRE_HAUT);
/* Definition de la fenetre de calcul de l'ensemble de Mandelbrot. */
Cinitialisation(J_coin_bas_gauche,J_FENETRE_GAUCHE,J_FENETRE_BAS);
Cinitialisation(J_coin_haut_droite,J_FENETRE_DROITE,J_FENETRE_HAUT);
/* Definition de la fenetre de calcul de l'ensemble de Julia. */
DEBUT_DE_L_INITIALISATION_DES_INTERPOLATIONS;
FIN_DE_L_INITIALISATION_DES_INTERPOLATIONS;
/* Initialisations generales pour l'interpolation des rotations... */
iTRANSFORMAT_31(liste_J_COMPOSANTE_J,J_COMPOSANTE_J_IMPLICITE);
iTRANSFORMAT_31(liste_J_COMPOSANTE_K,J_COMPOSANTE_K_IMPLICITE);
/* Initialisation des composantes 'J' et 'K' des quaternions. */
EGAL(les_images_standards_sont_a_renormaliser,IL_FAUT_RENORMALISER_LES_IMAGES);
/* Faut-il renormaliser l'image ? */
GET_ARGUMENTSi(nombre_d_arguments
,BLOC(GET_ARGUMENT_L("compatibilite_20190321=",compatibilite_20190321);
/* Argument introduit le 20190321131310... */
GET_ARGUMENT_L("editer_uniquement_contour=""euc=",editer_uniquement_les_points_du_contour);
/* Argument introduit le 20190321094653... */
PROCESS_ARGUMENT_I("n=""couches=""N=",nombre_de_couches_bidimensionnelles
,BLOC(VIDE;)
,BLOC(PRINT_AVERTISSEMENT("'n=''couches=''N=' doit etre avant toute entree de fichiers");)
);
PROCESS_ARGUMENTS_GEOMETRIQUES_DE_ROTATION;
PROCESS_ARGUMENTS_GEOMETRIQUES_DE_ROTATION_2_HC;
/* Introduit le 20091222140206... */
PROCESS_ARGUMENT_FICHIER("J_COMPOSANTE_J="
,fichier_J_COMPOSANTE_J
,liste_J_COMPOSANTE_J
,J_COMPOSANTE_J_IMPLICITE
,gTRANSFORMAT_31
);
PROCESS_ARGUMENT_FICHIER("J_COMPOSANTE_K="
,fichier_J_COMPOSANTE_K
,liste_J_COMPOSANTE_K
,J_COMPOSANTE_K_IMPLICITE
,gTRANSFORMAT_31
);
GET_ARGUMENT_C("imageR=""R=",nom_imageR);
GET_ARGUMENT_I("saut=",pas_de_calcul);
GET_ARGUMENT_C("imageM=""M=",nom_imageM);
/* Je rappelle le 20181114153004 que les images 'imageM' sont en fait des images temporaires */
/* (de Manoeuvre) destinees a stocker les differentes couches d'un ensemble de Julia avant */
/* leur accumulation (qui donnera alors une image de type 'imageR'...). */
GET_ARGUMENT_I("chiffres=",nombre_de_chiffres);
GET_ARGUMENT_L("accumulations=",faire_les_accumulations);
/* Argument introduit le 20100208133743... */
GET_ARGUMENT_I("iterations=",J_nombre_d_iterations);
GET_ARGUMENT_F("exposantJ=""exposant=",Ijulia_dans_HC_____exposant);
GET_ARGUMENT_F("exposantM=",Imandelbrot_dans_HC_____exposant);
/* Arguments introduits le 20091118120830... */
/* */
/* Le 20100608132303, passage de 'GET_ARGUMENT_I(...)' a 'GET_ARGUMENT_F(...)'. */
GET_ARGUMENT_F("seuilJ=",Ijulia_dans_HC_____seuil_du_carre_du_module);
GET_ARGUMENT_F("seuilM=",Imandelbrot_dans_HC_____seuil_du_carre_du_module);
/* Arguments introduits le 20091118183328... */
GET_ARGUMENT_F("xbgd=""xbgD=",Reelle(J_coin_bas_gauche));
GET_ARGUMENT_F("ybgd=""ybgD=",Imaginaire(J_coin_bas_gauche));
GET_ARGUMENT_F("xhdd=""xhdD=",Reelle(J_coin_haut_droite));
GET_ARGUMENT_F("yhdd=""yhdD=",Imaginaire(J_coin_haut_droite));
GET_ARGUMENT_F("MJ=",M_composante_J);
GET_ARGUMENT_F("MK=",M_composante_K);
GET_ARGUMENT_F("JJ=",J_composante_J);
GET_ARGUMENT_F("JK=",J_composante_K);
GET_ARGUMENT_L("arguments=",visualisation_arguments_de_sortie);
GET_ARGUMENT_F("ponderationT=",ponderation_argumentT);
GET_ARGUMENT_F("ponderationP=",ponderation_argumentP);
GET_ARGUMENT_F("ponderationA=",ponderation_argumentA);
GET_ARGUMENT_L("rotation_rijk=""Rrijk=""RA="
,Ijulia_dans_HC_____faire_la_rotation_de__nombre_argument
);
/* Arguments introduits le 20100303082652... */
GET_ARGUMENT_L("editer=",editer_le_nombre_argument_des_julias);
GET_ARGUMENT_L("inverser=",inverser_l_ordre_de_recuperation_des_images);
GET_ARGUMENT_I("premiere=",premiere_image);
GET_ARGUMENT_I("derniere=",derniere_image);
GET_ARGUMENT_L("transparence=",accumuler_par_transparence);
GET_ARGUMENT_F("fa=""attenuation=""a=",facteur_d_attenuation);
GET_ARGUMENT_F("fA=""A=",facteur_A);
GET_ARGUMENT_F("fB=""B=",facteur_B);
GET_ARGUMENT_L("logarithmique=""log=",prendre_une_dynamique_logarithmique);
GET_ARGUMENT_L("rechercher_maximum=""m=",rechercher_le_maximum);
/* Le 20091120134239 a cause de 'v $xrc/ITERATION.11$I maximum="' l'argument "maximum=" */
/* a ete remplace par "rechercher_maximum="... */
GET_ARGUMENT_L("renormaliser=""r=",les_images_standards_sont_a_renormaliser);
GET_ARGUMENT_L("calculer_le_seuil=""calculer=",calculer_le_seuil_de_masquage);
GET_ARGUMENT_F("fraction=",fraction_de_points_pour_calculer_le_seuil_de_masquage);
GET_ARGUMENT_P("seuil=""masque=",seuil_de_masquage);
GET_ARGUMENT_L("binariser=",binariser_les_images);
GET_ARGUMENT_I("zmin=",premiere_tranche_verticale);
GET_ARGUMENT_I("zmax=",derniere_tranche_verticale);
GET_ARGUMENT_L("translation_quelconque=""translation=""quelconque=",translation_quelconque);
GIT_ARGUMENT_F("trx=",pas_horizontal,PAS_HORIZONTAL);
GIT_ARGUMENT_F("try=",pas_vertical,PAS_VERTICAL);
GET_ARGUMENT_F("stereo=""facteur=",facteur_stereoscopique);
GET_ARGUMENT_L("interpolation_cubique=""cubique=",Irotation_image_____interpolation_cubique);
GET_ARGUMENT_N("interpolation_lineaire=""lineaire=",Irotation_image_____interpolation_cubique);
/* Arguments introduits le 20131230130738... */
PROCESS_ARGUMENTS_DE_PARAMETRAGE_DES_ITERATIONS_1;
/* Introduit le 20091120122745... */
GET_ARGUMENT_L("F_ITERATION_DANS_HC_____compatibilite_20110825=""compatibilite_20110825="
,F_ITERATION_DANS_HC_____compatibilite_20110825
);
/* Introduit le 20110826123016. */
CONTROLE_DE_L_ARITHMETIQUE_FOLKLORIQUE_DES_NOMBRES_COMPLEXES;
/* Cette extension a ete introduite le 20181211112149... */
CONTROLE_DE_L_ARITHMETIQUE_ETENDUE_DES_NOMBRES_HYPER_COMPLEXES;
/* Cette extension a ete introduite le 20070129112806... */
CONTROLE_DE_LA_TRANFORMATION_DE_LA_SUITE_DE_POINTS_DANS_HC;
/* Cette extension a ete introduite le 20100513181645, meme si elle n'a pas beaucoup de */
/* sens ici... */
)
);
/* ATTENTION, il y avait autrefois : */
/* */
/* GET_ARGUMENT_I("Zmin=",premiere_tranche_verticale); */
/* GET_ARGUMENT_I("Zmax=",derniere_tranche_verticale); */
/* */
/* mais cela rentrait en conflit avec : */
/* */
/* GET_ARGUMENT_I("Zmin=",Zmin); \ */
/* GET_ARGUMENT_I("Zmax=",Zmax); \ */
/* */
/* dans '$xig/fonct$vv$DEF' ; donc, */
/* */
/* "zmin=" */
/* "zmax=" */
/* */
/* et : */
/* */
/* "Zmin=" */
/* "Zmax=" */
/* */
/* ne doivent pas etre confondus... */
Test(IFLT(nombre_de_couches_bidimensionnelles,DEUX))
Bblock
PRINT_ATTENTION("le nombre de couches bidimensionnelles doit au moins etre egal a 2 (valeur qui est donc forcee)");
EGAL(nombre_de_couches_bidimensionnelles,DEUX);
/* Introduit le 20181211115345 car, en effet donner "N=1" provoquait l'erreur : */
/* */
/* Floating exception (core dumped) */
/* */
/* et ce a cause des 'MOIT(FLOT(nombre_de_couches_bidimensionnelles))'s qui suivent afin */
/* de determiner 'RRtranslation'... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IFEXff(fraction_de_points_pour_calculer_le_seuil_de_masquage
,COORDONNEE_BARYCENTRIQUE_MINIMALE
,COORDONNEE_BARYCENTRIQUE_MAXIMALE
)
)
Bblock
PRINT_ATTENTION("la fraction de points pour calculer le seuil de masquage n'est pas dans [0,1]");
Eblock
ATes
Bblock
Eblock
ETes
EGAL(seuil_de_masquage_utilise,seuil_de_masquage);
/* A priori... */
SET_FILTRAGE(ACTIF);
/* Afin d'acceder aux listes de substitutions... */
MODIFICATION_LISTE_DE_SUBSTITUTION(BLANC,PRED(PRED(BLANC)));
MODIFICATION_LISTE_DE_SUBSTITUTION(PRED(BLANC),PRED(PRED(BLANC)));
/* Afin de reserver le blanc pour le contour et les pointilles... */
SUBSTITUTION(L_SUBSTITUTION_VARIABLE);
BSaveModifyVariable(Logical,FHCproduit_____utiliser_la_definition_theorique_du_produit,VRAI);
/* Introduit le 20100208135856 afin de garantir le "bon" ensemble de Mandelbrot... */
CALS(Imandelbrot_dans_HC(ImageA1
,ADRESSE(M_coin_bas_gauche),ADRESSE(M_coin_haut_droite)
,M_composante_J
,M_composante_K
,M_nombre_maximal_d_iterations
,FAUX
,FLOT__UNDEF,FLOT__UNDEF,FLOT__UNDEF
)
);
/* A1 = ensemble de Mandelbrot dont on va extraire une equipotentielle. */
ESaveModifyVariable(Logical,FHCproduit_____utiliser_la_definition_theorique_du_produit);
/* Introduit le 20100208135856 afin de garantir le "bon" ensemble de Mandelbrot... */
CHANGEMENT_DU_POINT_DE_VUE_GEOMETRIQUE;
/* Mise en place des rotations tridimensionnelles dans les Quaternions apres le calcul */
/* de l'ensemble de Mandelbrot, et avant tout autre chose a cause des '#define' qui */
/* suivent et qu'on veut faire le plutot possible... */
/* */
/* ATTENTION aux commentaires relatifs a 'numero_de_la_periode_courante'... */
#define numero_de_la_periode_courante \
numero_de_la_couche \
/* Pour assurer la compatibilite avec '$xrq/nucleon.Lf.2.I'... */
/* Depuis l'introduction de 'CHANGEMENT_DU_POINT_DE_VUE_GEOMETRIQUE' qui lui a besoin */
/* du "vrai" 'numero_de_la_periode_courante' valant systematiquement la valeur */
/* 'NUMERO_DE_LA_PREMIERE_PERIODE', il est imperatif de mettre ces definitions apres... */
SET_FILTRAGE(INACTIF);
DEFINE_CONTOUR(VRAI,FAUX);
/* Definition de l'interieur et de l'exterieur du contour... */
Test(IFLE(niveau_de_marquage_du_contour,SUCC(SEUIL_D_EXTRACTION_DU_CONTOUR)))
Bblock
PRINT_ERREUR("les niveaux de gestion des contours sont incoherents");
Eblock
ATes
Bblock
Test(IZNE(NOMBRE_DE_CONTOURS))
Bblock
INITIALISATION_POINT_2D(point_de_depart,E_DEPART_X,E_DEPART_Y);
/* Choix du point de depart de l'extraction de l'equipotentielle. */
CALi(Inoir(ImageA2));
/* Nettoyage de l'image ou mettre les contours interieurs. */
CALS(Iextraction_contour(ImageA2
,ImageA1
,ADRESSE(point_de_depart)
,exterieur,interieur
,niveau_de_marquage_du_contour
,FAUX,NoProcess
)
);
/* A2 = equipotentielle choisie de l'ensemble de Mandelbrot. */
/* */
/* La valeur 'NoProcess' a ete introduite le 20040619185059... */
CALS(Imove(ImageA1,ImageA2));
/* A1 = equipotentielle choisie de l'ensemble de Mandelbrot. */
INITIALISATION_POINT_2D(point_de_depart,C_DEPART_X,C_DEPART_Y);
/* Choix du point de depart de l'extraction de contour. */
Repe(NOMBRE_DE_CONTOURS)
Bblock
CALi(Inoir(ImageA2));
/* Nettoyage de l'image ou mettre les contours interieurs. */
CALS(Iextraction_contour(ImageA2
,ImageA1
,ADRESSE(point_de_depart)
,exterieur,interieur
,niveau_de_marquage_du_contour
,FAUX,NoProcess
)
);
/* A2 = contour courant interieur a l'equipotentielle de l'ensemble de Mandelbrot. */
/* */
/* La valeur 'NoProcess' a ete introduite le 20040619185059... */
CALS(Imove(ImageA1,ImageA2));
/* A1 = contour courant interieur a l'equipotentielle de l'ensemble de Mandelbrot (de facon */
/* a extraire le contour interieur du contour courant...). */
Eblock
ERep
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
CALi(Inoir(ImageA3));
/* Nettoyage du futur contour pour le processus 'Pextraction'. */
iPARALLELE(BLOC(INITIALISATION_POINT_2D(point_de_depart,E_DEPART_X,E_DEPART_Y);
/* Choix du point de depart de l'extraction de contour. */
CALS(Iextraction_contour(ImageA3
,ImageA1
,ADRESSE(point_de_depart)
,exterieur,interieur
,niveau_de_marquage_du_contour
,emission_des_points
,ADRESSE(Pextraction)
)
);
)
,Pextraction
);
/* Envoi en parallele de l'extraction du contour, c'est-a-dire de */
/* l'equipotentielle numero 'SEUIL_D_EXTRACTION_DU_CONTOUR'. */
/* */
/* La valeur 'NoProcess' a ete introduite le 20040619185059... */
Tant(EST_FAUX(fin_de_contour))
Bblock
RECEIVE_F(Pextraction,ASD1(point_courant_extrait,x));
RECEIVE_F(Pextraction,ASD1(point_courant_extrait,y));
/* Recuperation du point courant du contour, */
RECEIVE_L(Pextraction,fin_de_contour);
/* Et de l'indicateur de fin... */
Test(IFOU(IFEQ(saut_des_calculs,CALCUL)
,EST_VRAI(fin_de_contour)
)
)
Bblock
/* On ne fait les calculs que lorsque 'saut_des_calculs' est nul, ou */
/* bien pour le dernier point (afin de "refermer" le contour). */
Test(IFINff(numero_d_image,premiere_image,derniere_image))
/* Afin de se positionner dans la sequence... */
Bblock
gVARIABLES_RELATIVES_A_LA_NECESSITE_D_HOMOTHETIE(VRAI);
/* Introduit le 20091126090705 car, en effet, il manquait en notant que la valeur 'VRAI' */
/* assure la compatibilite anterieure... */
HCinitialisation(point_argument
,GENERATEUR_REEL
,GENERATEUR_IMAGINAIRE
,M_composante_J
,M_composante_K
);
/* Calcul du nombre argument de l'ensemble de Julia courant. */
Test(IL_FAUT(editer_le_nombre_argument_des_julias))
Bblock
CAL2(Prin5("image %04d : quaternion=(%+.^^^,%+.^^^,%+.^^^,%+.^^^)\n"
,numero_d_image
,HReelle(point_argument)
,HImaginaire(point_argument)
,HJmaginaire(point_argument)
,HKmaginaire(point_argument)
)
);
/* Le 20060106160816, le format "16f" est passe a "^^f" pour plus de souplesse... */
/* */
/* Le 20091123123409, le format "^^g" est passe a "^^^" pour plus de souplesse... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IL_FAUT(editer_uniquement_les_points_du_contour))
/* Test introduit le 20190321094653... */
Bblock
Eblock
ATes
Bblock
DoIn(numero_de_la_couche
,premiere_couche
,derniere_couche
,I
)
Bblock
CALi(Inoir(ImageA));
/* Initialisation des images de manoeuvre... */
vTRANSFORMAT_31(J_composante_J,sJ_COMPOSANTE_J,numero_de_la_periode_courante,fichier_J_COMPOSANTE_J);
/* Calcul de la composante 'J' des quaternions lorsqu'elle est variable. */
vTRANSFORMAT_31(J_composante_K,sJ_COMPOSANTE_K,numero_de_la_periode_courante,fichier_J_COMPOSANTE_K);
/* Calcul de la composante 'K' des quaternions lorsqu'elle est variable. */
CALS(Ijulia_dans_HC(ImageA
,ADRESSE(J_coin_bas_gauche)
,ADRESSE(J_coin_haut_droite)
,J_composante_J
,J_composante_K
,ADRESSE(point_argument)
,J_nombre_d_iterations
,visualisation_arguments_de_sortie
,ponderation_argumentT,ponderation_argumentP,ponderation_argumentA
)
);
/* Calcul de l'ensemble de Julia dans l'espace hyper-Complexe. */
Test(IL_FAUT(faire_les_accumulations))
/* Test introduit le 20100208133743... */
Bblock
EGAL(nom_image
,chain_Aconcaten2_sauf_nom_pipe(nom_imageM
,chain_numero(numero_de_la_couche,nombre_de_chiffres)
)
);
/* Cas ou les accumulations sont effectuees : les images sont destinees a etre exploitees */
/* tout de suite et les differentes couches de l'image finale de rang 'N' ecrasent celles */
/* de l'image 'N-1'... */
Eblock
ATes
Bblock
EGAL(nom_image
,chain_Aconcaten4_sauf_nom_pipe(nom_imageR
,chain_numero(numero_d_image,nombre_de_chiffres)
,cSEPARATEUR_DES_COMPOSANTES_D_UN_NOM
,chain_numero(numero_de_la_couche,nombre_de_chiffres)
)
);
/* Cas ou les accumulations ne sont pas effectuees : toutes les couches sont conservees... */
Eblock
ETes
CALi(Iupdate_image(nom_image,ImageA));
CALZ_FreCC(nom_image);
/* Generation des images de manoeuvre. */
Eblock
EDoI
Test(IL_FAUT(faire_les_accumulations))
/* Test introduit le 20100208133743... */
Bblock
begin_nouveau_block
Bblock
/* ATTENTION, les declarations suivantes ne peuvent etre faite conditionnellement par */
/* rapport a 'accumuler_par_transparence', alors qu'elles ne sont utiles que si l'effet */
/* de transparence est demande. Or on souhaite mettre une partie du code en commun entre */
/* les deux possibilites d'accumulation, d'ou l'impossibilite... */
BDEFV(imageF,cumul_des_couches);
/* Image flottante dans laquelle on cumule les differentes couches d'avant en arriere. */
BDEFV(imageF,couche_courante);
/* Image flottante dans laquelle on trouve la couche courante, puis a la fin le */
/* resultat renormalise par le nombre d'images... */
Test(IL_FAUT(accumuler_par_transparence))
Bblock
Test(IZEQ(facteur_d_attenuation))
Bblock
EGAL(facteur_d_attenuation
,PUIX(INVE(FLOT__BLANC),INVZ(FLOT(NBRE(premiere_couche,derniere_couche))))
);
/* Lorsque le facteur d'attenuation est nul, il est alors calcule automatiquement de */
/* facon que : */
/* */
/* (derniere_couche - premiere_couche + 1) */
/* BLANC.(facteur_d_attenuation) = 1. */
/* */
/* A titre d'exemple, lors d'un calcul portant sur 128 images, on a : */
/* */
/* facteur_d_attenuation = 0.957633 */
/* */
Eblock
ATes
Bblock
Eblock
ETes
CALi(IFinitialisation(cumul_des_couches,FZERO));
/* Nettoyage de l'image finale flottante... */
EGAL(attenuation_globale,FZERO);
/* Cumul des 'facteur_d_attenuation_courant's afin de calculer l'image finale lorsqu'il */
/* n'y a pas de renormalisation automatique... */
Eblock
ATes
Bblock
Eblock
ETes
CALi(Inoir(ImageR));
/* Initialisation de l'image Resultat. */
INITIALISATION_ACCROISSEMENT_2D(Atranslation
,FZERO
,FZERO
);
INITIALISATION_ACCROISSEMENT_2D(RAtranslation
,FZERO
,FZERO
);
INITIALISATION_ACCROISSEMENT_2D(RRtranslation
,NEUT(MUL2(VRAI_PAS_HORIZONTAL
,MOIT(FLOT(nombre_de_couches_bidimensionnelles))
)
)
,NEUT(MUL2(VRAI_PAS_VERTICAL
,MOIT(FLOT(nombre_de_couches_bidimensionnelles))
)
)
);
/* Definition de la translation d'empilement vertical des images. La valeur initiale de */
/* 'RRtranslation' est faite de facon a ce que le "centre" de l'objet tridimensionnel obtenu */
/* par accumulation tombe au centre de l'image... */
EGAL(tranche_verticale_courante,premiere_tranche_verticale);
/* Initialisation de la tranche verticale courante. */
DoIn(numero_de_la_couche
,premiere_couche
,derniere_couche
,I
)
Bblock
EGAL(nom_image
,chain_Aconcaten2_sauf_nom_pipe(nom_imageM
,chain_numero(NUMERO_DE_LA_COUCHE,nombre_de_chiffres)
)
);
Test(PAS_D_ERREUR(CODE_ERROR(Iload_image_and_delete(Masque,nom_image))))
Bblock
/* 'Masque' donne la couche a l'instant courant, que l'on detruit simultanement... */
Test(IL_FAUT(accumuler_par_transparence))
Bblock
EGAL(facteur_d_attenuation_courant
,PUIX(facteur_d_attenuation
,ATTENUATION_DE_LA_COUCHE_COURANTE(facteur_A
,SOUS(derniere_couche,numero_de_la_couche)
,facteur_B
)
)
);
/* Facteur d'attenuation de la couche courante qui vaut 'facteur_d_attenuation' eleve a */
/* une puissance qui est le rang de cette couche... */
CALi(Inoir(ImageA4));
/* Nettoyage systematique de 'ImageA4' a cause du fait que la translation peut etre non */
/* nulle (on risque alors de recuperer des morceaux du contenu anterieur de 'ImageA4'). */
Test(IFET(IL_NE_FAUT_PAS(translation_quelconque),IZEQ(facteur_stereoscopique)))
Bblock
CALS(Itranslation(ImageA4
,Masque
,ADRESSE(RRtranslation)
,FAUX
,FAUX
)
);
/* Et on decale l'image courante... */
Eblock
ATes
Bblock
CALS(Irotation_image(ImageA4
,Masque
,VRAI
,ADRESSE(RRtranslation)
,ADRESSE(RAtranslation)
,ADRESSE(Atranslation)
,FZERO
,VRAI
)
);
/* Et on decale l'image courante. ATTENTION, rappelons que 'Irotation_image(...)' fait */
/* appel a 'Ifloat_std(...)' ce qui peut creer des messages d'erreur lorsqu'une image que */
/* l'on va accumuler est 'NOIR' ; en effet, on trouve alors : */
/* */
/* ATTENTION : Ifloat_std : les niveaux 'minimal' et 'maximal' sont egaux... */
/* */
/* qui n'a rien a voir avec les appels suivants a 'Ifloat_std(...)'... */
Eblock
ETes
CALS(Istd_float(couche_courante
,FLOT__NOIR
,MUL2(facteur_d_attenuation_courant
,FLOT__BLANC
)
,ImageA4
)
);
/* Conversion flottante avec attenuation eventuelle... */
Test(IL_FAUT(rechercher_le_maximum))
Bblock
CALS(IFmaximum(cumul_des_couches,cumul_des_couches,couche_courante));
/* Et on cumule d'avant en arriere par recherche du maximum. */
Eblock
ATes
Bblock
CALS(IFaddition(cumul_des_couches,cumul_des_couches,couche_courante));
/* Et on cumule d'avant en arriere par addition arithmetique. */
Eblock
ETes
INCR(attenuation_globale,facteur_d_attenuation_courant);
/* Cumul des coefficients d'attenuation courants... */
Eblock
ATes
Bblock
EGAL(z_depth_cueing
,NIVA(__DENORMALISE_NIVEAU(_____lNORMALISE_OZ(COZR(tranche_verticale_courante))))
);
/* Afin de faire du "depth-cueing", la troisieme coordonnee 'z' suit les couleurs... */
Test(IL_FAUT(calculer_le_seuil_de_masquage))
Bblock
CALS(Ihistogramme(Masque));
/* Calcul de l'histogramme de l'image courante. */
EGAL(seuil_de_masquage_utilise,NOIR);
/* A priori... */
BoIn(niveau,NOIR,BLANC,PAS_COULEURS)
Bblock
Test(IFLT(ACCES_HISTOGRAMME_CUMULE___NORMALISE(niveau)
,COMP(fraction_de_points_pour_calculer_le_seuil_de_masquage)
)
)
Bblock
EGAL(seuil_de_masquage_utilise,niveau);
/* On prend comme le seuil le niveau qui correspond a peu pres au poucentage demande. */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
EBoI
EGAL(seuil_de_masquage_utilise
,MAX2(seuil_de_masquage_utilise,seuil_de_masquage)
);
/* On prend comme le seuil le niveau qui correspond a peu pres au poucentage demande, mais */
/* en faisant qu'il ne soit pas trop petit... */
Eblock
ATes
Bblock
Eblock
ETes
MASQUE_IMAGES(seuil_de_masquage_utilise);
/* Activation du masquage des images. */
BoIn(niveau,NOIR,BLANC,PAS_COULEURS)
Bblock
Test(IL_FAUT(binariser_les_images))
Bblock
MODIFICATION_LISTE_DE_SUBSTITUTION(niveau,GENP(z_depth_cueing));
/* La liste de substitution (associee au masque) est telle que tout ce qui */
/* est inferieur au seuil disparait, et que les autres sont materialises */
/* par le 'z' de depth-cueing... */
Eblock
ATes
Bblock
MODIFICATION_LISTE_DE_SUBSTITUTION(niveau
,MAX2(GENP(NIVA(SCAL(NIVR(niveau)
,NIVR(BLANC)
,NIVR(z_depth_cueing)
)
)
)
,NOIR_PLANCHER
)
);
/* La liste de substitution (associee au masque) est telle que tout ce qui */
/* est inferieur au seuil disparait, et que les autres sont materialises */
/* par une echelle allant de 'NOIR_PLANCHER' au 'z' de depth-cueing... */
Eblock
ETes
Eblock
EBoI
Test(IL_NE_FAUT_PAS(translation_quelconque))
Bblock
SUBSTITUTION(L_SUBSTITUTION_VARIABLE);
SET_FILTRAGE(ACTIF);
/* Activation du filtrage de "depth-cueing". */
CALS(Itranslation(ImageR
,Masque
,ADRESSE(RRtranslation)
,FAUX
,FAUX
)
);
/* Et on superpose les images. On notera que l'on pourrait utiliser 'Itranslation_3D(...)' */
/* avec 'z_depth_cueing' comme troisieme coordonnee. Mais en fait, je ne le */
/* programme pas provisoirement, car en effet, dans le cas ou une translation quelconque */
/* est demandee, il faudrait pouvoir disposer de la fonction 'Irotation_image_3D(...)' qui */
/* n'existe pas ("3D" signifiant "gestion du 'Z-Buffer'", et non pas rotation dans l'espace */
/* tridimensionnel...). */
SET_FILTRAGE(INACTIF);
/* Inhibition du filtrage... */
Eblock
ATes
Bblock
SUBSTITUTION(L_SUBSTITUTION_VARIABLE);
SET_FILTRAGE(ACTIF);
/* Activation du filtrage de "depth-cueing". */
DEMASQUE_IMAGES;
CALS(Imove(ImageA4,Masque));
MASQUE_IMAGES(seuil_de_masquage_utilise);
/* Filtrage de "depth-cueing" ; on notera qu'il est fait sur toute l'image afin d'eviter des */
/* problemes d'interpolation dans 'Irotation_image(...)' (en effet, les points "frontiere" */
/* ont une partie de leur voisin hors du masque, et ils sont utilises malgre tout lors de */
/* l'interpolation...). */
SET_FILTRAGE(INACTIF);
/* Inhibition du filtrage... */
CALS(Irotation_image(ImageR
,ImageA4
,FAUX
,ADRESSE(RRtranslation)
,ADRESSE(RAtranslation)
,ADRESSE(Atranslation)
,FZERO
,VRAI
)
);
/* Et on superpose les images (sans reinitialiser 'ImageR' a chaque iteration...). */
/* */
/* ATTENTION, dans la mesure ou 'Irotation_image(...)' procede a une renormalisation des */
/* images, cette derniere ne sera pas malheureusement homogene d'une image a l'autre a */
/* l'interieur d'une meme sequence ; des artefacts seront peut-etre alors introduits... */
/* */
Eblock
ETes
DEMASQUE_IMAGES;
/* Inhibition du masquage... */
INCR(tranche_verticale_courante
,DIVI(SOUS(derniere_tranche_verticale,premiere_tranche_verticale)
,SOUS(derniere_couche,premiere_couche)
)
);
/* Mise a jour de la tranche verticale courante. */
Eblock
ETes
DECR(ASD1(RRtranslation,dx),VRAI_PAS_HORIZONTAL);
DECR(ASD1(RRtranslation,dy),VRAI_PAS_VERTICAL);
/* Et on decale d'un cran de plus... */
Eblock
ATes
Bblock
Test__CODE_ERREUR__ERREUR07;
Eblock
ETes
CALZ_FreCC(nom_image);
Eblock
EDoI
Test(IL_FAUT(accumuler_par_transparence))
Bblock
Test(IL_FAUT(rechercher_le_maximum))
Bblock
CALS(Ifloat_std(ImageR,cumul_des_couches,FLOT__NOIR,FLOT__BLANC));
/* Enfin, on convertit en une image standard sans renormalisation puisque theoriquement */
/* la dynamique des images Arguments n'a pas change par la recherche du maximum... */
Eblock
ATes
Bblock
Test(IL_FAUT(prendre_une_dynamique_logarithmique))
Bblock
CALS(IFdynamique_logarithmique_avec_translation_dynamique(cumul_des_couches
,cumul_des_couches
)
);
/* S'il le faut, la dynamique des accumulations est reduite par application d'une fonction */
/* logarithme... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(EST_VRAI(les_images_standards_sont_a_renormaliser)
,IL_FAUT(prendre_une_dynamique_logarithmique)
)
)
Bblock
CALS(Ifloat_std_avec_renormalisation(ImageR,cumul_des_couches));
/* De temps en temps, il peut etre utile de renormaliser, de facon a beneficier de toute */
/* la dynamique dans [NOIR,BLANC]... */
Eblock
ATes
Bblock
CALS(IFscale(couche_courante
,INVZ(attenuation_globale)
,cumul_des_couches
,FZERO
)
);
/* Renormalisation en fonction du nombre d'images traitees. On notera l'usage de 'INVZ(...)' */
/* au cas ou il y aurait eu erreur sur toutes les images recuperees... */
CALS(Ifloat_std(ImageR,couche_courante,FLOT__NOIR,FLOT__BLANC));
/* Enfin, on convertit en une image standard sans renormalisation automatique, et ce de */
/* facon a conserver la dynamique des images Arguments... */
Eblock
ETes
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
/* ATTENTION, les declarations suivantes ne peuvent etre faite conditionnellement par */
/* rapport a 'accumuler_par_transparence', alors qu'elles ne sont utiles que si l'effet */
/* de transparence est demande. Or on souhaite mettre une partie du code en commun entre */
/* les deux possibilites d'accumulation, d'ou l'impossibilite... */
EDEFV(imageF,couche_courante);
/* Image flottante dans laquelle on trouve la couche courante, puis a la fin le */
/* resultat renormalise par le nombre d'images... */
EDEFV(imageF,cumul_des_couches);
/* Image flottante dans laquelle on cumule les differentes couches d'avant en arriere. */
Eblock
end_nouveau_block
EGAL(nom_image
,chain_Aconcaten2_sauf_nom_pipe(nom_imageR
,chain_numero(numero_d_image,nombre_de_chiffres)
)
);
CALi(Iupdate_image(nom_image,ImageR));
CALZ_FreCC(nom_image);
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Eblock
ATes
Bblock
Eblock
ETes
INCR(numero_d_image,I);
/* Numero de la prochaine image a generer. */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(saut_des_calculs
,MODU(SUCC(saut_des_calculs)
,CALCUL
,PRED(INTE(DIVI(FLOT(pas_de_calcul)
,MAX2(DIVI(FLOT(dimX_BASE),FLOT(dimX)),DIVI(FLOT(dimY_BASE),FLOT(dimY)))
)
)
)
)
);
/* Afin de determiner le point suivant de facon "homothetique", c'est-a-dire de facon a ce */
/* que le nombre de points extraits soit a peu pres independant de la taille de l'image... */
Eblock
ETan
RETU_Commande;
Eblock
ECommande