#include <stdlib.h>
#include <stdio.h>
typedef struct
{
int nrows;
int ncols;
unsigned char *pixels;
} image;
unsigned char *newImage( image *img, int nrows, int ncols )
{
img->nrows = nrows;
img->ncols = ncols;
img->pixels = (unsigned char *)malloc( nrows * ncols );
return img->pixels;
}
void freeImage( image *img )
{
img->nrows = 0;
img->ncols = 0;
free( img->pixels );
}
void setPixel( image img, int row, int col, unsigned char val )
{
img.pixels[ img.ncols*row + col ] = val;
}
unsigned char getPixel( image img, int row, int col )
{
return img.pixels[ img.ncols*row + col ] ;
}
void writeImage( image img, char *filename )
{
FILE *file;
/* open the image file for writing */
if ( (file = fopen( filename, "wb") ) == NULL )
{
printf("file %s could not be created\n", filename );
exit( EXIT_FAILURE );
}
/* write out the PGM Header information */
fprintf( file, "P5\n");
fprintf( file, "# Created by writeImage\n");
fprintf( file, "%d %d %d\n", img.ncols, img.nrows, 255 );
/* write the pixel data */
fwrite(img.pixels, 1, img.nrows*img.ncols, file );
/* close the file */
fclose( file );
}
/* Make all pixels of an image the same value */
void clearImage( image img, const unsigned char val)
{
int r, c;
for ( r = 0; r<img.nrows; r++ )
for ( c = 0; c<img.ncols; c++ )
setPixel( img, r, c, val );
}
/* Draw a circle in the image */
void drawCircle( image img, int row, int col,
int radius, unsigned char value )
{
int r, c;
int boxLeft, boxRight, boxTop, boxBottom;
/* find the bounding box for the circle */
boxLeft = col-radius;
if ( boxLeft < 0 ) boxLeft = 0;
boxTop = row-radius;
if ( boxTop < 0 ) boxTop = 0;
boxRight = col+radius;
if ( boxRight >= img.ncols ) boxRight = img.ncols-1 ;
boxBottom = row+radius;
if ( boxBottom >= img.nrows ) boxBottom = img.nrows-1 ;
/* scan thru the pixels in the bounding box, setting */
/* those inside the circle to the forground color */
for ( r = boxTop; r<boxBottom; r++ )
for ( c = boxLeft; c<boxRight; c++ )
if ( (r-row)*(r-row)+(c-col)*(c-col) <= radius*radius )
setPixel( img, r, c, value );
}
int main ( int argc, char* argv[] )
{
image img ;
/* image size, background and foreground gray levels */
int nrows, ncols, bgvalue, fgvalue;
/* circle radius, how many to draw, how many there are */
int radius, howmany, circCount;
/* number of attempts made, and maximum attempts allowed */
int tries, maxtries;
/* where circles have been drawn, up to MAXCIRC circles */
const int MAXCIRC = 100;
int crow[MAXCIRC];
int ccol[MAXCIRC];
/* proposed row and column for a circle */
int r, c;
/* distance squared of (r,c) from (oldr,oldc) of an */
/* existing circle, and if this results in an overlap */
int circ, distSq, oldr, oldc, overlap ;
/* initialize circle locations arrays */
circCount = 0;
for ( circ=0; circ<MAXCIRC; circ++ )
crow[circ] = ccol[circ] = 0;
/* remind user of parameters */
if ( argc != 8)
{
printf("sepCircles fileName nrows ncols bkground");
printf(" fground radius howmany\n");
system( "pause" );
return EXIT_SUCCESS;
}
/* collect parameters from command line */
nrows = atoi( argv[2] );
ncols = atoi( argv[3] );
bgvalue = atoi( argv[4] );
fgvalue = atoi( argv[5] );
radius = atoi( argv[6] );
howmany = atoi( argv[7] );
/* user might specify more circles than can be drawn w/o */
/* overlap, so set a limit on the number of attempts to */
/* draw "howmany" circles */
maxtries= 3*howmany;
newImage( &img, nrows, ncols );
clearImage( img, bgvalue );
srand( time(NULL) );
/* keep going until all circles have been drawn or too many */
/* attempts to find a new location have occured */
for ( tries=0, circCount=0; circCount<howmany && tries<maxtries; tries++ )
{
overlap = 0;
r = rand()%nrows; /* pick a random spot for the new circle */
c = rand()%ncols;
/* look thru the old circles for one that would overlap */
for ( circ=0; circ<circCount && !overlap; circ++ )
{
/* calculate distance from proposed (r,c) and an old */
/* center (oldr, oldc) */
oldr = crow[circ];
oldc = ccol[circ];
distSq = (r-oldr)*(r-oldr)+(c-oldc)*(c-oldc);
/* if distance**2 is less than diameter**2, then overlap */
if ( distSq <= 4*radius*radius ) overlap = 1;
}
/* if the proposed circle at (r,c) does not overlap another */
if ( !overlap )
{
drawCircle( img, r, c, radius, fgvalue );
/* remember the location of this new circle */
crow[circCount] = r;
ccol[circCount] = c;
circCount++ ;
}
}
/* write the image to disk and free memory */
writePGMimage( img, argv[1]);
freeImage( &img );
system( "pause" );
}
Comments: