I08 Answer


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* Puzzle I08 -- filled circle
|
|
*/

makeCircle( FILE *image, int nrows, int ncols )
{
  const int levelIN  = 220; /* gray levels inside and */
  const int levelOUT = 50;  /* outside of the circle  */

  int r, c  ;       /* row and col of current pixel */
  int rc, cc ;      /* row and col of center of image */
  int rd, cd ;      /* row and col difference from center */
  double radius, dist ; /* radius of circle, distance from center */

  /* calculate center of image, size of radius */
  rc = nrows/2;
  cc = ncols/2;
  if ( nrows<ncols ) radius = nrows/3;
  else               radius = ncols/3;

  /* write out the pixel data */
  for ( r=0; r<nrows; r++ )
  {
    rd = r - rc;

    for ( c=0; c<ncols; c++ )
    {
      cd   = c - cc;
      dist = sqrt( (double)(rd*rd + cd*cd) );
      if ( dist < radius )
        fputc( levelIN, image );
      else
        fputc( levelOUT, image );
    }
  }
}

void openImage( char *argv[], FILE **image, int *nrows, int *ncols )
{

  /* open the image file for writing */
  if ( (*image = fopen( argv[1], "wb") ) == NULL )
  {
    printf("file %s could not be created\n", argv[1] );
    exit( EXIT_FAILURE );
  }

  *nrows = atoi( argv[2] );
  if ( *nrows < 1 )
  {
    printf("number of rows must be positive\n");
    exit( EXIT_FAILURE );
  }

  *ncols = atoi( argv[3] );
  if ( *nrows < 1 )
  {
    printf("number of columns must be positive\n");
    exit( EXIT_FAILURE );
  }
}

/* write out the PGM Header information
|
| The number of gray levels is assumed to be 255.
|
*/
void writeHeader( FILE *image, int nrows, int ncols )
{
  fprintf( image, "P5 ");
  fprintf( image, "# Created by makeCircle\n");

  /* width, height, number of gray levels */
  fprintf( image, "%d %d %d ", ncols, nrows, 255 );
}

int main( int argc, char *argv[] )
{
  int nrows, ncols ;
  FILE *image;

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("circle fileName.pgm nrows ncols\n");
    return 0;
  }

  /* Open the image file, get number of rows and columns */
  openImage( argv, &image, &nrows, &ncols );

  /* write header information */
  writeHeader( image, nrows, ncols );

  /* Create the Image */
  makeCircle( image, nrows, ncols );

  /* close the file */
  fclose ( image );
  return 1;
}

Comments: Floating point math can be avoided. You don't really need to use the square root function to determine if a pixel is inside of the circle. The radius squared of the circle can be calculated (using integers). For each pixel, calculated its distance from the center squared (using integers). The two squares can be compared to determine if the pixel is inside of the circle.

back