/*************************************************************************************************************************************/ /* */ /* C A L C U L G E N E R A 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 P L A N 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... */ /* */ /* */ /* Author of '$xrc/julia.02$K' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, 1988??????????). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 GENERER_LES_GET_ARGUMENTS_DE_CONTROLE_DE_L_ARITHMETIQUE_ETENDUE_DES_NOMBRES_FLOTTANTS /* Introduit le 20070129112458... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* 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 20190321131841. */ #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_NOMBRE_D_ITERATIONS \ QUAR(COULEURS) \ /* Nombre d'iterations demandees pour le calcul de l'ensemble de Mandelbrot. */ #define SEUIL \ 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 20120212101505, 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 20120212101505, 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 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 calcul des ensembles de Julia. */ #define J_NOMBRE_D_ITERATIONS \ COND(IZEQ(NOMBRE_DE_CONTOURS),QUAR(COULEURS),COULEURS) \ /* Nombre d'iterations demandees pour le calcul des ensembles de Julia ; */ \ /* ce nombre varie suivant qu'on est a l'exterieur ('QUAR(COULEURS)') */ \ /* ou bien a l'interieur ('COULEURS'). */ #define VISUALISATION_ARGUMENTS_DE_SORTIE \ FAUX \ /* Faut-il visualiser l'argument de sortie ('VRAI') ou les equipotentielles ('FAUX'). */ #define PREMIERE_TRAJECTOIRE \ SUCC(NOIR) \ /* Premier niveau de marquage de la trajectoire, */ #define DERNIERE_TRAJECTOIRE \ PRED(CONTOUR) \ /* Premier niveau de marquage de la trajectoire, */ #include xci/sequence.01.I" #redefine DERNIERE_IMAGE \ INFINI \ /* Numero de la derniere image a generer : ce parametre permet de s'arreter en cours de */ \ /* route... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M A C R O S U T I L E S : */ /* */ /*************************************************************************************************************************************/ #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,I) \ Bblock \ EGAL(ITb1(exterieur,INDX(niveau,NOIR)),logique1); \ EGAL(ITb1(interieur,INDX(niveau,NOIR)),logique2); \ Eblock \ EBoI \ BoIn(niveau,SUCC(SEUIL),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. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C A L C U L G E N E R A 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 P L A N 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 20190321131841. */ DEFV(complexe,M_coin_bas_gauche); /* Definition du point situe en bas a gauche de la fenetre courante, */ DEFV(complexe,M_coin_haut_droite); /* Definition du point situe en haut a droite de la fenetre courante, */ /* pour le calcul de 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(pas_de_calcul,PAS_DE_CALCUL)); /* Permet de ne calculer qu'un ensemble partiel de Mandelbrot sur 'pas_de_calcul'. */ DEFV(Int,INIT(saut_des_calculs,CALCUL)); /* Permet de ne calculer qu'un ensemble partiel de Mandelbrot sur 'pas_de_calcul'. */ DEFV(Logical,INIT(visualisation_arguments_de_sortie,VISUALISATION_ARGUMENTS_DE_SORTIE)); /* Indicateur de choix entre la visualisation du nombre d'iterations ('FAUX'), */ /* et l'argument de sortie ('VRAI'). */ DEFV(complexe,J_coin_bas_gauche); /* Definition du point situe en bas a gauche de la fenetre courante, */ DEFV(complexe,J_coin_haut_droite); /* Definition du point situe en haut a droite de la fenetre courante, */ /* pour le calcul de l'ensemble de Julia. */ DEFV(complexe,point_argument); /* Nombre complexe generateur. */ DEFV(Positive,INIT(J_nombre_maximal_d_iterations,J_NOMBRE_D_ITERATIONS)); /* Nombre maximal d'iterations a effectuer pour le calcul de l'ensemble de Julia. */ 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(numero_d_image,PREMIERE_IMAGE_ABSOLUE)); /* Numero de l'image courante (celle-ci n'est pas necessairement generee : voir */ /* le parametre 'PREMIERE_IMAGE'). */ DEFV(CHAR,INIC(POINTERc(nom_imageR),NOM_PIPE)); /* Nom de la sequence a generer. */ DEFV(Int,INIT(nombre_de_chiffres,NOMBRE_DE_CHIFFRES)); /* Nombre de chiffres codant le numero des images de la sequence a generer. */ DEFV(CHAR,INIC(POINTERc(nom_imageRC),NOM_PIPE)); DEFV(CHAR,INIC(POINTERc(nom_imageRE),NOM_PIPE)); DEFV(CHAR,INIC(POINTERc(nom_imageRM),NOM_PIPE)); DEFV(CHAR,INIC(POINTERc(nom_imageRT),NOM_PIPE)); /* Nom des images resultantes. */ DEFV(CHAR,INIT(POINTERc(nom_image),NOM_UNDEF)); /* Nom courant des images. */ /*..............................................................................................................................*/ 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. */ GET_ARGUMENTSv(nombre_d_arguments ,BLOC(GET_ARGUMENT_L("compatibilite_20190321=",compatibilite_20190321); /* Argument introduit le 20190321131841... */ GET_ARGUMENT_C("imageR=""R=",nom_imageR); GET_ARGUMENT_I("chiffres=",nombre_de_chiffres); GET_ARGUMENT_C("imageRC=""RC=",nom_imageRC); GET_ARGUMENT_C("imageRE=""RE=",nom_imageRE); GET_ARGUMENT_C("imageRM=""RM=",nom_imageRM); GET_ARGUMENT_C("imageRT=""RT=",nom_imageRT); GET_ARGUMENT_L("arguments=",visualisation_arguments_de_sortie); GET_ARGUMENT_I("pas=",pas_de_calcul); GET_ARGUMENT_F("exposantJ=",Ijulia_dans_C_____exposant); GET_ARGUMENT_F("exposantM=",Imandelbrot_dans_C_____exposant); /* Arguments introduits le 20091118122011... */ /* */ /* Le 20100608132121, passage de 'GET_ARGUMENT_I(...)' a 'GET_ARGUMENT_F(...)'. */ GET_ARGUMENT_F("seuilJ=",Ijulia_dans_C_____seuil_du_carre_du_module); GET_ARGUMENT_F("seuilM=",Imandelbrot_dans_C_____seuil_du_carre_du_module); /* Arguments introduits le 20091118183752... */ CONTROLE_DE_L_ARITHMETIQUE_ETENDUE_DES_NOMBRES_COMPLEXES; /* Cette extension a ete introduite le 20070129112458... */ ) ); 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); CALS(Imandelbrot_dans_C(ImageA1 ,ADRESSE(M_coin_bas_gauche),ADRESSE(M_coin_haut_droite) ,M_nombre_maximal_d_iterations ,FAUX ) ); /* Calcul de l'ensemble de Mandelbrot dont on va extraire une equipotentielle. */ SET_FILTRAGE(INACTIF); CALi(Iupdate_image(nom_imageRM,ImageA1)); /* Et on stocke l'ensemble de Mandelbrot... */ DEFINE_CONTOUR(VRAI,FAUX); /* Definition de l'interieur et de l'exterieur du contour... */ CALS(Idelete_image(nom_imageRE)); Test(IFLE(niveau_de_marquage_du_contour,SUCC(SEUIL))) 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 ) ); /* Extraction de l'equipotentielle choisie. */ /* */ /* La valeur 'NoProcess' a ete introduite le 20040619185544... */ CALi(Istore_image(nom_imageRE,ImageA2)); /* Et on stocke l'equipotentielle... */ CALS(Imove(ImageA1,ImageA2)); 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 ) ); /* Extraction du contour courant interieur a l'equipotentielle. */ /* */ /* La valeur 'NoProcess' a ete introduite le 20040619185544... */ CALS(Imove(ImageA1,ImageA2)); /* De facon a extraire le contour interieur du contour courant... */ Eblock ERep Eblock ATes Bblock Eblock ETes Eblock ETes CALi(Inoir(Image_VERTE)); /* Nettoyage du futur contour pour le processus 'Pextraction', et du */ /* marquage des points ou l'on calcule l'ensemble partiel de Mandelbrot pour le */ /* processus courant (le "pere")... */ 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(Image_VERTE ,ImageA1 ,ADRESSE(point_de_depart) ,exterieur,interieur ,niveau_de_marquage_du_contour ,emission_des_points ,ADRESSE(Pextraction) ) ); /* La valeur 'NoProcess' a ete introduite le 20040619185544... */ CALi(Iupdate_image(nom_imageRC,Image_VERTE)); /* Et on stocke le contour... */ ) ,Pextraction ); /* Envoi en parallele de l'extraction du contour, c'est-a-dire de */ /* l'equipotentielle numero 'SEUIL'. */ 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. */ 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 20091126090519 car, en effet, il manquait en notant que la valeur 'VRAI' */ /* assure la compatibilite anterieure... */ Cinitialisation(point_argument ,GENERATEUR_REEL ,GENERATEUR_IMAGINAIRE ); CALS(Ijulia_dans_C(ImageR ,ADRESSE(J_coin_bas_gauche),ADRESSE(J_coin_haut_droite) ,ADRESSE(point_argument) ,J_nombre_maximal_d_iterations ,visualisation_arguments_de_sortie ) ); 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); /* Et on stocke l'image... */ Eblock ATes Bblock Eblock ETes store_point(MODU(numero_d_image,PREMIERE_TRAJECTOIRE,DERNIERE_TRAJECTOIRE) ,Image_VERTE ,_cDENORMALISE_OX(ASD1(point_courant_extrait,x)),_cDENORMALISE_OY(ASD1(point_courant_extrait,y)) ,FVARIABLE ); /* Et marquage du point ou a lieu le calcul avec un niveau fonction */ /* du numero de l'image ; cette mise a jour a lieu meme si les calculs */ /* precedents ne sont pas effectues afin que l'image 'nom_imageRT' */ /* soit toujours correcte, meme lorsque l'on fait une reprise... */ 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 CALi(Iupdate_image(nom_imageRT,Image_VERTE)); /* Et on stocke la trajectoire... */ RETU_Commande; Eblock ECommande