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



Copyright © Jean-François Colonna, 2021-2023.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2021-2023.