/*
 * Header Begins--Do not remove################################################
 *
 *	C-code to reproduce discussion of pp58-61 of book
 *
 *	(c) Eugene Fiume, University of Toronto, 1995.
 *
 *	You are permitted to use this code for noncommercial, educational
 *	purposes only.  This header must not be removed from this file.
 *
 * Header Ends--Do not remove##################################################
 */

#include <stdio.h>

#define RADIUS  100
#define OFFSET1	200
#define OFFSET2	450
#define FALSE   (0 == 1)
#define round(x) ( (int)( (x)+0.5 ) )

main(argc, argv)
	int argc;
	char *argv[];
{
	double x,y;
	int i,s,xn,yn;
	double r, eps;
	int done;

	printf("Drawing circles of radius %d.\n\n", RADIUS);
	printf("The first 'circle' will really be a spiral due to numerical\n");
	printf("error, while the second will be a 'corrected' spiral.\n");

	XOpen(800,800, argc, argv);

	/*
	 *	Let's plot something
	 */

	printf("Hit a mouse button to start\n");
	GetEvent();

	/*
	 * This bizzare piece of code quickly computes the smallest number
	 * that is both a power of 2 and greater or equal to the radius.
	 * It is a great example of obscure programming.
	 */ 
	for (r=RADIUS,s=1; s < r; s <<= 1);

	eps = 1.0/s;

	x  = RADIUS;
	y  = RADIUS;

	/*
	 * First let's draw a "circle" directly from our iterative equations.
	 */
	while(xn < 2*RADIUS) {
		xn = round(x);
		yn = round(y);
		setpixel(OFFSET1+xn,OFFSET1+yn,1);
		x  = x - eps*yn;	/*  we can get away with using xn,yn */
		y  = y + eps*xn;	/*  rather than real versions x,y */
	}

	x  = RADIUS;
	y  = RADIUS;
	xn = RADIUS;
	yn = RADIUS;
	done = FALSE;

	/*
	 * Second, let's draw a corrected spiral to give us a circle.
	 */
	setpixel(OFFSET2+RADIUS,OFFSET2+RADIUS,2);
	while (!done) {
		x  = x - eps*yn;
		xn = round(x);
		y  = y + eps*xn;
		yn = round(y);
		setpixel(OFFSET2+xn,OFFSET2+yn,2);
		done = (xn >= RADIUS) && (yn >= RADIUS);
	}

	printf("Hit a mouse button to end.\n");
	GetEvent();
}
