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