Listing 1

#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>       /* for use by randomize */

#define MAX_CIRCLES 150

double distance( double x, double y, int i);
void generate_circles();
void exit_if_kbhit();

typedef struct {
      int x;
      int y;
      int r;
      } circle_type;

circle_type c[ MAX_CIRCLES];

int N, rmax;

/**************************************************/

void generate_circles()

/* this function draws a series of circles at random */
/* positions, each one after the first touching the  */
/* nearest circle that has been previously drawn     */

{
  int xmax, ymax, x_pos, y_pos, radius;
  randomize();  /* initialize the random numbers   */
  xmax = getmaxx(); /* maximum x and y positions   */
  ymax = getmaxy(); /* that can be displayed       */

  rmax = max( xmax, ymax)/2;
        /* divisor of 2 can be changed to allow */
        /* different maximum radii              */

  /* select random position and draw first circle  */

  x_pos = rand() % xmax;
  y_pos = rand() % ymax;
  radius = rand() % rmax;
  c[0].x = x_pos;
  c[0].y = y_pos;
  c[0].r = radius;
  circle( x_pos, y_pos, radius);

  /* select and draw remaining randomly placed circles */
  /* each tangent to the nearest previously drawn      */
  /* circle                                            */

  for ( N = 1; N <= MAX_CIRCLES; N++)
     {
     do
         {
         exit_if_kbhit();
         x_pos = rand() % xmax;
         y_pos = rand() % ymax;
         radius = new_radius( x_pos, y_pos);
         } while (radius <= 0);
     radius = min( rmax, radius);
     circle( x_pos, y_pos, radius);
     c[N].x = x_pos;
     c[N].y = y_pos;
     c[N].r = radius;
     }
}

/**************************************************/

int new_radius( int x, int y)

/* returns the distance from the point x,y to the   */
/* nearest circle; aborts and returns the           */
/* calculated negative or zero distance if x,y lies */
/* on or inside another circle                      */

{
   int i, radius;
   radius = rmax;
   for ( i = 0; i <= N; i++)
      {
      radius = min( radius, (int)distance(x,y,i));
      if ( radius <= 0) return radius;
      }
   return radius;
}

/**************************************************/

double distance( double x, double y, int i)

/* returns the distance from the point x,y to     */
/* circle i; returns a negative or zero distance  */
/* if x,y is inside or on circle i                */

{
   double xdist, ydist, distancesq;
   xdist = x - c[i].x;
   ydist = y - c[i].y;
   distancesq = xdist*xdist + ydist*ydist;
   return ( sqrt( distancesq) - c[i].r);
}

/**************************************************/

int main(void)

/* initializes Borland Graphics Interface in      */
/* "audodetect" mode using default background     */
/* and foreground colors, checks for errors in    */
/* initialization, calls routine to draw circles, */
/* when finished waits for keystroke to erase     */
/* screen and exit                                */

{
   int gdriver = DETECT, gmode, errorcode;
   initgraph(&gdriver, &gmode, "");
   errorcode = graphresult();
   if (errorcode != grOk) /* an error occurred */
      {
      printf("Graphics error: %s\n",
                    grapherrormsg(errorcode));
      printf("Press any key to halt:");
      getch();
      exit(1);
      }
   generate_circles();
   getch();
   closegraph();
   return 0;
}

/**************************************************/

void exit_if_kbhit()

/* exits program if a key has been struck */
/* returns otherwise                      */

{
   if ( kbhit())
      {
      getch();
      closegraph();
      exit(1);
      }
}

/* End of File */