/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:d2cirarc.c 12.0$ */
/* $ACIS:d2cirarc.c 12.0$ */
/* $Source: /ibm/acis/usr/src/ibm/ditroff/dit3812/RCS/d2cirarc.c,v $ */
#ifndef lint
static char *rcsid = "$Header:d2cirarc.c 12.0$";
#endif

#include <stdio.h>
#include <math.h>
#include <pmp/pmp.h>

#define EPSILON 5
#define FALSE 0

static int vecx, vecy;

d2cirarc(xc,yc,xv,yv)
int xc,yc,xv,yv;
	{
	register int x,y,xold,yold;
	register int n;
	register int adj;
	int xend, yend;
	double radius, endlen, ratio;
	int rad;

#ifdef DEBUG
	fprintf(stderr,"d2cirarc(%d,%d,%d,%d)\n",xc,yc,xv,yv);
#endif DEBUG

	vecx = vecy = 0;
	x = xc;
	y = yc;

	rad = (int)(radius = sqrt((double)(xc*xc + yc*yc)))+.5;
	endlen = sqrt((double)(xv*xv + yv*yv));
	
	ratio = radius/endlen;

	xend = (int)(((double)(-xv))*ratio);
	yend = (int)(((double)(-yv))*ratio);
#ifdef DEBUG
	fprintf(stderr,"start(%d,%d), end(%d,%d)\n",x,y,xend,yend);
#endif

	n = 1;
	while ( 8<<n++ < rad );
	adj = (1<<n)-1;

#ifdef DEBUG
	fprintf(stderr,"n = %d\n",n);
#endif

	xold = x;
	yold = y;

	x = x<<8;
	y = y<<8;

	xend = xend<<8;
	yend = yend<<8;

	x += ((y+( adj&(y>>31)))>>n);
	y -= ((x+( adj&(x>>31)))>>n);

	do
		{
		if ( x>xend )
			while( x>xend  ) 
				{

#ifdef DEBUG
				fprintf(stderr,"x=%d, y=%d ",(x+128)>>8,(y+128)>>8);
				fprintf(stderr,"xold=%d, yold=%d ",xold,yold);
				fprintf(stderr,"(%d,%d)\n",xold-((x+128)>>8),yold-((y+128)>>8));
#endif

				draw_vec(xold-((x+128)>>8),yold-((y+128)>>8));

				xold = (x+128)>>8;
				yold = (y+128)>>8;

				x += ((y+( adj&(y>>31)))>>n);
				y -= ((x+( adj&(x>>31)))>>n);

				}
		else
			while( x<xend ) 
				{

#ifdef DEBUG
				fprintf(stderr,"x=%d, y=%d ",(x+128)>>8,(y+128)>>8);
				fprintf(stderr,"xold=%d, yold=%d ",xold,yold);
				fprintf(stderr,"(%d,%d)\n",xold-((x+128)>>8),yold-((y+128)>>8));
#endif
				
				draw_vec(xold-((x+128)>>8),yold-((y+128)>>8));

				xold = (x+128)>>8;
				yold = (y+128)>>8;

				x += ((y+( adj&(y>>31)))>>n);
				y -= ((x+( adj&(x>>31)))>>n);

				}
		}
	while( abs(abs(y) - abs(yend)) != abs(y-yend) );

#ifdef DEBUG
	fprintf(stderr,"x=%d, y=%d\n",(x+128)>>8,(y+128)>>8);
#endif
				
	draw_vec(xold-((xend+128)>>8),yold-((yend+128)>>8));
	if( (vecy!=0)||(vecx!=0) )
		p_vec_relative(vecx,vecy);
	}

draw_vec(dx,dy)
	register int dx,dy;
	{

	if(vecx==dx)
		{
		if(dx==0)
			{
			vecy+=dy;
			return;
			}
		else if (vecy==dy)
			{
			vecy=vecy<<1;
			vecx=vecx<<1;
			return;
			}
		}
	if((vecy==0)&&(dy==0))
		{
		vecx+=dx;
		return;
		}
	else if(vecx==vecy)
		{
		if(vecx==0)
			{
			vecx=dx;
			vecy=dy;
			return;
			}
		else if(dx==dy)
			{
			vecx+=dx;
			vecy+=dy;
			return;
			}
		}
	if((vecy==0)&&((dy==1)||(dy==-1)))
		{
		p_vec_relative(vecx+dx,vecy+dy);
		vecx=vecy=0;
		return;
		}
	else if((vecx==0)&&((dx==1)||(dx==-1)))
		{
		p_vec_relative(vecx+dx,vecy+dy);
		vecx=vecy=0;
		return;
		}
	else if((vecy==0)||(vecx==0)||(dx==0)||(dy==0)||((vecy%dy)!=0)||((vecx%dx)!=0)||(vecy/dy != vecx/dx))
		{
		p_vec_relative(vecx,vecy);
		vecx=dx;
		vecy=dy;
		return;
		}
	else
		{
		vecx+=dx;
		vecy+=dy;
		}
	}
