```/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        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...                                                                      */
}
}
```