/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:circle.c 12.0$ */
/* $ACIS:circle.c 12.0$ */
/* $Source: /ibm/acis/usr/src/ibm/ditroff/dit3812/RCS/circle.c,v $ */

#ifndef lint
static char *rcsid = "$Header:circle.c 12.0$";
#endif

/* circle generator */

#include <vector.h>
#include <pmp/pmp.h>

#include <stdio.h>

/* do something about fill */

int circle(radius)
	int radius;
{
	register int x,y,d;
	register int ox,oy,dx,dy;
	cursor_reg *startcr1,*startcr2,*startcr3;
	vectors *octant1,*octant2,*octant3,*octant4;
	vectors *octant5,*octant6,*octant7,*octant8;
	int save_ends;

	save_ends = v_set_dflt_ends(P_VECTOR_ROUND_ENDS);
	startcr1 = p_cr_mark(); /* save the start position */
	
	octant1 = v_new();	/* allocate vs */
	octant2 = v_new();
	octant3 = v_new();
	octant4 = v_new();
	octant5 = v_new();
	octant6 = v_new();
	octant7 = v_new();
	octant8 = v_new();
	oy = radius;
	ox = 0;
	x = 0;
	y = radius;
	d = 3 - (radius<<1);
	while (x<y)
		{
		dx=x-ox; dy=y-oy;
		v_draw(octant1, dx, dy);
		v_draw(octant2, dy, dx);
		v_draw(octant3, dy,-dx);
		v_draw(octant4, dx,-dy);
		v_draw(octant5,-dx,-dy);
		v_draw(octant6,-dy,-dx);
		v_draw(octant7,-dy, dx);
		v_draw(octant8,-dx, dy);
		ox=x; oy=y;
		if (d<0)
			d += (x<<2) + 6;
		else
			{
			d += ((x-y)<<2) + 10;
			y--;
			}
		x++;
		}
	if (x==y) {
		dx=x-ox; dy=y-oy;
		v_draw(octant1, dx, dy);
		v_draw(octant2, dy, dx);
		v_draw(octant3, dy,-dx);
		v_draw(octant4, dx,-dy);
		v_draw(octant5,-dx,-dy);
		v_draw(octant6,-dy,-dx);
		v_draw(octant7,-dy, dx);
		v_draw(octant8,-dx, dy);
	 }
	p_cr_return(startcr1,P_KEEP_CURSOR_REG);
	p_draw_vectors(octant6);

	p_cr_return(startcr1,P_KEEP_CURSOR_REG);
	p_draw_vectors(octant7);

	p_cr_return(startcr1,P_FREE_CURSOR_REG);
	p_mv_relative(radius,radius);
	startcr2 = p_cr_mark();
	p_draw_vectors(octant1);

	p_cr_return(startcr2,P_KEEP_CURSOR_REG);
	p_draw_vectors(octant8);

	p_cr_return(startcr2,P_FREE_CURSOR_REG);
	p_mv_relative(radius,-radius);
	startcr3 = p_cr_mark();
	p_draw_vectors(octant2);

	p_cr_return(startcr3,P_KEEP_CURSOR_REG);
	p_draw_vectors(octant3);

	p_cr_return(startcr3,P_KEEP_CURSOR_REG);
	p_mv_relative(-radius,-radius);
	startcr2 = p_cr_mark();
	p_draw_vectors(octant4);

	p_cr_return(startcr2,P_FREE_CURSOR_REG);
	p_draw_vectors(octant5);

 	p_cr_return(startcr3,P_FREE_CURSOR_REG);

	v_free(octant1);
	v_free(octant2);
	v_free(octant3);
	v_free(octant4);
	v_free(octant5);
	v_free(octant6);
	v_free(octant7);
	v_free(octant8);
	v_set_dflt_ends(save_ends);
}

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

#define MAXSPLINEPOINTS 50
spline(infil)
FILE *infil;
{      
 /*  B-SPLINE TO dh1 dv1, THEN TO dh2 dv2 ... ***/
int  itx[MAXSPLINEPOINTS];
int  ity[MAXSPLINEPOINTS];
int  i = 0;
int  dx,dy;
char ch;    
	itx[0] = itx[1] = 0;
	ity[0] = ity[1] = 0;
 	for (i=2;i<=MAXSPLINEPOINTS-1;i++)
	{
		do { 
			ch= getc(infil);
		   } while ( isspace(ch) && (ch!='\n') );
		if (ch=='\n')
			break;
		else
			ungetc(ch,infil);
		if (fscanf(infil,"%d %d",&dx,&dy) != 2)
		{ 
			fprintf(stderr,"spline input bogus!?\n");
			return(0);
		}
		itx[i]= itx[i-1] + dx;
		ity[i]= ity[i-1] + dy;
	/*
	fprintf(stderr,"i=%d,itx=%d,ity=%d\n",i,itx[i],ity[i]);
	*/
	}
	if (i > MAXSPLINEPOINTS - 1 ) 
	{
		fprintf(stderr,"spline:no. points > %d\n",MAXSPLINEPOINTS);
	}
	else
	{
		itx[i] = itx[i-1];
		ity[i] = ity[i-1];
		drawspline(i,itx,ity); 
		}
}
#define DX 1
#define DY 1
#define X 0
#define Y 1
#define MAX 50

dist(x1, y1, x2, y2)	/* integer distance from x1,y1 to x2,y2 */
{
	double dx, dy;
 
	dx = x2 - x1;
	dy = y2 - y1;
	return sqrt(dx*dx + dy*dy) + 0.5;
}


round(x, dx)	/* round x relative to dx */
{
#if (DX == 1)
	return(x);
#else
	x = (x + dx - 1) / dx;
	return x * dx;
#endif
}

/* this routine doubles the beginning and ending points */
drawspline(n,x,y)	/* draw spline curve */
	int n;
	int x[],y[];
{
	int  xp, yp, pxp, pyp, oldx, oldy;
	double t1, t2, t3, w;
	int i, j, steps;

	int save_ends;

	save_ends = v_set_dflt_ends(P_VECTOR_ROUND_ENDS);
	oldx=0;
	oldy=0;
	pxp = pyp = -9999;
	for (i = 0; i < n-1; i++) {	/* interval */
		steps = (dist(x[i],y[i], x[i+1],y[i+1]) + dist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2;
		/* 
		fprintf ( stderr,"steps=%d,i=%d,n=%d\n",steps,i,n);
		*/
		for (j = 0; j < steps; j++) {	/* points within */
			w = (double) j / steps;
			t1 = 0.5 * w * w;
			w = w - 0.5;
			t2 = 0.75 - w * w;
			w = w - 0.5;
			t3 = 0.5 * w * w;
			xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5;
			yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5;
			if (xp != pxp || yp != pyp) {
				pxp = xp;
				pyp = yp;
				p_vec_relative(xp-oldx,yp-oldy);
				oldx = xp;
				oldy = yp;
			}
		}
	}

	v_set_dflt_ends(save_ends);
}
