/*************************************************************************************************************************************/ /* */ /* I N T E R S E C T I O N D ' U N E D R O I T E A V E C U N */ /* R E S E A U C A R R E D E C E R C L E S D E F A C O N */ /* A V O I R S I L ' O N P E U T G E N E R E R A I N S I D E S N O M B R E S A L E A T O I R E S : */ /* */ /* */ /* Author of '$xtc/MailleCer.01$c' : */ /* */ /* Jean-Francois COLONNA (LACTAMME, AAAAMMJJhhmmss). */ /* */ /*************************************************************************************************************************************/ #include "INCLUDES.01.I" /* Introduit le 20051116094648... */ extern void *malloc(); extern int atoi(); extern char *getenv(); #define Carre(x) \ ((x) * (x)) \ /* Procedure d'elevation au carre. */ 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. */ #define IMAGE(x,y) \ (*(image + (((y-Ymin)*dimX) + (x-Xmin)))) \ /* Acces a un point de l'image. */ #define store(n,x,y) \ { \ IMAGE(x,y) = n; \ \ x = x + 1; \ if (x > Xmax) \ { \ x = Xmin; \ y = y + 1; \ if (y > Ymax) \ { \ y = Ymin; \ /* Pour eviter des violations memoire au cas ou... */ \ } \ else \ { \ } \ } \ else \ { \ } \ } \ /* Rangement d'un point valide d'une image. */ extern double floor(); extern double sqrt(); #define ITERATIONS \ (dimX*dimY) \ /* Nombre d'iterations... */ #define SAUT \ 0 \ /* Nombre de nombres aleatoires a sauter. */ #define X_POINT_DE_DEPART \ 0.0 #define Y_POINT_DE_DEPART \ 0.0 #define COEFFICIENT_A \ 3.141592653589793 #define COEFFICIENT_B \ 0.0 #define PAS \ 0.1 /* Definition de la droite. */ #define RAYON \ 1.0 #define FRAYON \ 4.0 /* Definition du cercle. */ main() { int editer=1; /* =0 : editer les valeurs, =1 : generer une image. */ double Rayon=RAYON,Frayon=FRAYON; /* Afin de determiner le rayon effectif des cercles qui peut etre soit fixe (Frayon=0) */ /* soit module aleatoirement par 'random' de l'iteration precedente (Frayon#0). On notera */ /* que pour des valeurs superieures a 4, le champ 'image' obtenu semble bien aleatoire... */ double Xf=X_POINT_DE_DEPART,Yf=Y_POINT_DE_DEPART; /* Point courant. */ double Coefficient_A=COEFFICIENT_A,Coefficient_B=COEFFICIENT_B,Pas=PAS; /* Definition de la droite. */ int X=Xmin,Y=Ymin; unsigned char *image; /* Definition de l'image a generer eventuellement. */ double Xcp=-1.0e300,Ycp=-1.0e300; /* Centre du cercle precedent. */ double moyenne=0.0; int compteur=0; /* Pour calculer la moyenne et compter les points generes. */ int saut=SAUT; /* Nombre de nombres aleatoires a sauter. */ int une_fois_sur_deux=+1; /* Pour alterner le choix entre {Xr1,Xr2}... */ double random=0; /* Nombre aleatoire courant. */ Get(dimX,"dimX"); Get(dimY,"dimY"); /* Recuperation des dimensions en 'X' et en 'Y' de l'image a generer. */ if (editer == 0) { } else { image=malloc(ITERATIONS); /* Definition de l'image a generer... */ } while (compteur < (ITERATIONS*(SAUT+1))) { double Xcc,Ycc; /* Centre du cercle courant. */ Xcc = floor(Xf); Ycc = floor(Yf); /* Centre du cercle courant. */ if ((Xcc != Xcp) || (Ycc != Ycp)) { double A,B,C,Discriminant; /* Definition de l'equation du second degre donnant l'intersection entre le cercle */ /* courant et la droite... */ A = 1 + Carre(Coefficient_A); B = 2*((Coefficient_A*(Coefficient_B-Ycc)) - Xcc); C = Carre(Xcc) + Carre(Coefficient_B-Ycc) - Carre((Frayon*random) + Rayon); Discriminant = Carre(B) - (4*A*C); if (Discriminant < 0) { /* Lorsqu'il n'y a pas d'intersection, il n'y a rien de genere... */ } else { if (Discriminant == 0) { double Xr = -B / (2*A); random = Xr; /* L'intersection unique entre le cercle et la droite va generer 'random'. */ } else { double Xr1 = (-B - sqrt(Discriminant)) / (2*A); double Xr2 = (-B + sqrt(Discriminant)) / (2*A); if (une_fois_sur_deux > 0) { random = Xr1; /* L'intersection de gauche entre le cercle et la droite va generer 'random'. */ } else { random = Xr2; /* L'intersection de droite entre le cercle et la droite va generer 'random'. */ } une_fois_sur_deux = -une_fois_sur_deux; } random = random - floor(random); /* Ensuite, on ne garde que la partie decimale de 'random'. */ if (saut == 0) { if (editer == 0) { printf("\n random=%g",random); } else { store((unsigned char)(NOIR + (random*BLANC)),X,Y); } moyenne = moyenne + random; compteur = compteur + 1; /* Pour calculer la moyenne... */ saut = SAUT; } else { saut = saut - 1; } } Xcp = Xcc; Ycp = Ycc; } else { } Xf = Xf + Pas + random; Yf = (Coefficient_A*Xf) + Coefficient_B; /* Progression du point courant. On notera le '+random' sur le 'Pas' ; cela permet de */ /* rompre la pseudo-periodicite des resultats... */ } moyenne = moyenne / ((double)compteur); if (editer == 0) { printf("\n\n moyenne=%g",moyenne); } else { write(1,image,ITERATIONS); /* Sortie de l'image... */ } }