/*************************************************************************************************************************************/ /* */ /* C O N S T R U C T I O N D ' U N E C O U R B E F R A C T A L E A L E A T O I R E D A N S L E P L A N : */ /* */ /* */ /* Author of '$xtc/FracCurve.11$c' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, AAAAMMJJhhmmss). */ /* */ /*************************************************************************************************************************************/ #include "INCLUDES.01.I" /* Introduit le 20051116094022... */ extern void *malloc(); extern int atoi(); extern char *getenv(); extern double sqrt(); extern double cos(); extern double sin(); extern double drand48(); #define AVEUGLE 5646 #define RANDOM(minimum,maximum) \ ((minimum) + (((maximum)-(minimum))*drand48())) \ /* Generation d'une valeur aleatoire dans [minimum,maximum]. */ #define XG (0.00) #define XD (1.00) /* Extremites Gauche et Droite sur l'axe des 'X'. */ #define YB (0.00) #define YH (1.00) /* Extremites Bas et Haut sur l'axe des 'Y'. */ static int dimX=0; #define Xmin 0 #define Xmax (Xmin + (dimX-1)) /* Definition des abscisses. */ static int dimY=0; #define Ymin 0 #define Ymax (Ymin + (dimY-1)) /* Definition des ordonnees. */ unsigned char *image; /* Definition de l'image a generer... */ #define Xnormalise(x) \ ((int)((x-XG)/(XD-XG)*dimX)) #define Ynormalise(y) \ ((int)((y-YB)/(YH-YB)*dimY)) /* Mise des coordonnees {x,y} dans [Xmin,Xmax]x[Ymin,Ymax]. */ #define IMAGE(x,y) \ (*(image + ((int)(((y-Ymin)*dimX) + (x-Xmin))))) \ /* Acces a un point de l'image. */ #define NIVEAU_MINIMAL \ (NOIR+1) #define NIVEAU_MAXIMAL \ (BLANC) /* Definition des niveaux aleatoires. */ #define store(n,x,y) \ { \ if (((x>=Xmin) && (x<=Xmax)) && ((y>=Ymin) && (y<=Ymax))) \ { \ IMAGE(x,y) = (int)(n); \ } \ else \ { \ } \ } \ /* Rangement d'un point valide d'une image. */ #define PRECIS double \ /* Precision des calculs. */ typedef struct complexe { PRECIS reelle; PRECIS imaginaire; } complexe; #define Reelle(z) (z.reelle) #define Imaginaire(z) (z.imaginaire) /* Definition et acces aux composantes d'un nombre complexe... */ #define Cinit(z,x1,y1) \ { \ Reelle(z) = x1; \ Imaginaire(z) = y1; \ } #define Cegal(z,z1) \ { \ Cinit(z,Reelle(z1),Imaginaire(z1)); \ } #define Csomme(z,z1,z2) \ { \ complexe zT; \ Reelle(zT) = Reelle(z1) + Reelle(z2); \ Imaginaire(zT) = Imaginaire(z1) + Imaginaire(z2); \ Cegal(z,zT); \ } #define Cdifference(z,z1,z2) \ { \ complexe zT; \ Reelle(zT) = Reelle(z1) - Reelle(z2); \ Imaginaire(zT) = Imaginaire(z1) - Imaginaire(z2); \ Cegal(z,zT); \ } #define Cproduit(z,z1,z2) \ { \ complexe zT; \ Reelle(zT) = (Reelle(z1)*Reelle(z2)) - (Imaginaire(z1)*Imaginaire(z2)); \ Imaginaire(zT) = (Reelle(z2)*Imaginaire(z1)) + (Reelle(z1)*Imaginaire(z2)); \ Cegal(z,zT); \ } #define Crotation(z,z1,rho,theta) \ { \ complexe zR; \ Cinit(zR,rho*cos(theta),rho*sin(theta)); \ Cproduit(z,z1,zR); \ } #define Cmodule2(z) \ ((Reelle(z)*Reelle(z)) + (Imaginaire(z)*Imaginaire(z))) #define NOMBRE_MINIMAL_D_ANGLES \ 4 #define NOMBRE_MAXIMAL_D_ANGLES \ 8 #define ANGLE_MINIMAL \ (-PI/2) #define ANGLE_MAXIMAL \ (+PI/2) int nombre_d_angles; PRECIS *angles; /* Definition de la liste des angles aleatoires. */ PRECIS seuil=0.002; /* Definition du seuil d'arret. */ #define RAPPORT_MINIMAL \ 2.0 #define RAPPORT_MAXIMAL \ 3.0 PRECIS rapport=4.0; /* Definition du rapport de reduction aleatoire. */ #define rotation_et_construction(theta) \ { \ Cegal(zGs3,zDs3); \ Crotation(difference_reduite,difference_reduite,1.0,theta); \ Csomme(zDs3,zGs3,difference_reduite); \ construction(zGs3,zDs3); \ } construction(zG,zD) complexe zG,zD; { complexe difference; Cdifference(difference,zD,zG); if (sqrt(Cmodule2(difference)) < seuil) { store(RANDOM(NIVEAU_MINIMAL,NIVEAU_MAXIMAL),Xnormalise(Reelle(zG)),Ynormalise(Imaginaire(zG))); store(RANDOM(NIVEAU_MINIMAL,NIVEAU_MAXIMAL),Xnormalise(Reelle(zD)),Ynormalise(Imaginaire(zD))); /* Marquage et arret de la recursivite... */ } else { int angle; complexe zGs3,zDs3; complexe difference_reduite; Cegal(zDs3,zG); Crotation(difference_reduite,difference,1.0/rapport,0.0); for (angle=0 ; angle<nombre_d_angles ; angle++) { rotation_et_construction(*(angles+angle)); } } return(OK); } main() { complexe zG,zD; /* Definition des extremites de la courbe. */ int x,y; /* Definition des coordonnees d'initialisation de l'image. */ int aveugle; int angle; /* Index de la liste des angles. */ for (aveugle=0 ; aveugle<AVEUGLE ; aveugle++) { PRECIS random=drand48(); /* Pour faire comme s'il on injectait une graine dans le generateur aleatoire... */ } Get(dimX,"dimX"); Get(dimY,"dimY"); /* Recuperation des dimensions en 'X' et en 'Y' de l'image a generer. */ image=malloc(dimY*dimX); /* Definition de l'image a generer... */ for (y=Ymin ; y<=Ymax ; y++) { for (x=Xmin ; x<=Xmax ; x++) { store(NOIR,x,y); /* Initialisation de l'image finale... */ } } rapport = RANDOM(RAPPORT_MINIMAL,RAPPORT_MAXIMAL); /* Generation du rapport de reduction aleatoire. */ nombre_d_angles = RANDOM(NOMBRE_MINIMAL_D_ANGLES,NOMBRE_MAXIMAL_D_ANGLES); angles = malloc(nombre_d_angles*sizeof(PRECIS)); for (angle=0 ; angle<nombre_d_angles ; angle++) { *(angles+angle) = RANDOM(ANGLE_MINIMAL,ANGLE_MAXIMAL); /* Generation de la liste des angles aleatoires. */ } Cinit(zG,XG,(YB+YH)/2); Cinit(zD,XD,(YB+YH)/2); /* Initialisation des extremites de la courbe. */ construction(zG,zD); /* Construction de la courbe. */ write(1,image,dimX*dimY); /* Sortie de l'image... */ fprintf(stderr,"\n rapport de reduction=%f",rapport); fprintf(stderr,"\n nombre d'angles utilises=%d",nombre_d_angles); for (angle=0 ; angle<nombre_d_angles ; angle++) { fprintf(stderr,"\n angle(%d)=%+f",angle,*(angles+angle)); /* Edition des angles utilises... */ } fprintf(stderr,"\n"); fprintf(stderr,"\nrapport=%f ",rapport); for (angle=0 ; angle<nombre_d_angles ; angle++) { fprintf(stderr,"c%02d=VRAI a%02d=%+f ",angle,angle,*(angles+angle)); /* Edition des angles utilises... */ } fprintf(stderr,"\n"); }