/* This file is moondraw.c. It is one of the three .c files that must be compiled to create the executable program moon. */ #include #include #include "moon.h" #define RADIUS 13 /* radius of moon, in characters */ #define LINE (2 * RADIUS) /* number of chars on each line of screen */ #define LIGHT '@' /* draw the light side of moon with this character */ #define DARK '-' /* draw the dark side of moon with this character */ #define RATIO 2.4 /* each character is this many times taller than wide */ /* Draw the moon line by line from top to bottom. Because the moon is circular, the lines at the top and bottom are shortest, and the line in the middle is longest. That's why limb starts small, grows, and then becomes small again. Because the moon's limb (outline) is curved, each line must be indented a different amount: printf %*s. radians is the current phase. The terminator is the line that divides the light side from the dark side. */ void draw(double radians) { int y; /* loop from top to bottom */ int x; /* loop from left to right */ int limb; /* distance in characters from center of moon to limb */ int terminator; /* distance in characters from center to terminator */ char left; /* from the left limb to the terminator */ char right; /* from the right limb to the terminator */ #ifdef DEBUG printf ("%.5f radians\n", radians); #endif for (y = RADIUS / RATIO; y >= -RADIUS / RATIO; --y) { limb = sqrt((double) ((RADIUS + RATIO * y) * (RADIUS - RATIO * y))); /* Before the full moon, light up the right side of the moon. After the full moon, light up the left side of the moon. */ if (radians >= PI) { terminator = limb * cos(radians - PI); left = LIGHT; right = DARK; } else { terminator = limb * cos(radians); right = LIGHT; left = DARK; } /* Center the moon horizontally. */ printf ("%*s", LINE/2 - limb, ""); for (x = limb + terminator; x > 0; --x) { printf ("%c", left); } for (x = limb - terminator; x > 0; --x) { printf ("%c", right); } printf ("\n"); } }