#ifndef lint
static char *sccsid = "@(#)toruspoly.c	1.1 (UKC) 9/12/87";
#endif  lint
/*
 *	Draw image for hidden line removal stuff to bomb out on.
 *
 *	Y
 *	^
 *	|  Z
 *	| /
 *	|/
 *	+----> X
 *
 *	phi is horizontal scanning, starting on positive X axis and going
 *	towards Z axis.
 *
 *	theta is elevation, horizontal = 0.0, positive towards y-axis.
 *
 *	Vectors (once clipped) are plotted in the order and direction
 *	in which they were supplied here, so you can reasonably try to
 *	optimise head motion by drawing continuously as far as possible.
 */
#include <math.h>

#define RES 10		/* stepsize in degrees, should be a factor of 180 */

#define PI 3.141592653589793

/* convert array index to angle */
#define PtoPHI(p) ((p*RES) * (PI/180))
#define TtoTHETA(t) ((t*RES - 90) * (PI/180))
/* defines top save typing */
#define MAXP (360/RES)
#define MAXT (180/RES)

static double x[MAXP+1][MAXT+1];
static double y[MAXP+1][MAXT+1];
static double z[MAXP+1][MAXT+1];

static triangle(), line();

genpoly()
{
	int p, t;		/* phi and theta loop counters */

	double sinphi[MAXP+1], cosphi[MAXP+1];	/* precomputed */

	/* precompute sin( and cos(phi) */
	for (p = 0; p < MAXP; p++) {
		double phi;
		phi = PtoPHI(p);
		sinphi[p] = sin(phi);
		cosphi[p] = cos(phi);
	}
	/* wraparound */
	sinphi[MAXP] = sinphi[0]; cosphi[MAXP] = cosphi[0];

	for (t = 0; t <= MAXT; t++) {
		double theta, sintheta, costheta;
		theta = TtoTHETA(t);
		sintheta = sin(theta);
		costheta = cos(theta);
		for (p = 0; p < MAXP; p++) {
			double r; /* horizontal radius of object in this direction */
			/* image-generating function */
			/* a torus/doughnut/inner-tube at present */
			r = 0.5 + (costheta * costheta)/2;
			x[p][t] = r * cosphi[p] * costheta;
			z[p][t] = r * sinphi[p] * costheta;
			y[p][t] = sintheta * costheta;
		}
		/* wraparound */
		x[p][t] = x[0][t];
		y[p][t] = y[0][t];
		z[p][t] = z[0][t];
	}

	/* generate all obscuring quadrilateral polygons as triangle pairs */
	for (p = 0; p < MAXP; p++) {
		/* bottom triangle */
		triangle(p, 1, p, 0, p+1, 1);

		/* square tiles */
		for (t = 2; t < MAXT; t++) {
			triangle(p, t, p, t-1, p+1, t-1);
			triangle(p, t, p+1, t-1, p+1, t);
		}

		/* top triangle */
		triangle(p, MAXT, p, MAXT-1, p+1, MAXT-1);
	}
	
	/* draw lines of longitude(?) from pole to pole */
	for (p = 0; p < MAXP; p++) {
		for (t = 0; t < MAXT; t++) {
			line(p, t, p, t+1);
		}
	}

	/* lines of the other -itude, ring-shaped. */
	for (t = 1; t < MAXT; t++) {
		for (p = 0; p < MAXP; p++) {
			line(p, t, p+1, t);
		}
	}
}

static
triangle(p1, t1, p2, t2, p3, t3)
{
	addtri(x[p1][t1], y[p1][t1], z[p1][t1],
	       x[p2][t2], y[p2][t2], z[p2][t2],
	       x[p3][t3], y[p3][t3], z[p3][t3]);
}

static
line(p1, t1, p2, t2)
{
	addline(x[p1][t1], y[p1][t1], z[p1][t1],
		x[p2][t2], y[p2][t2], z[p2][t2]);
}
