AUSAM/source/plot/plot3.c

#include "plot.h"






border()
/*
	DOES THE SCALING, DRAWING OF AXES ETC
*/
{

	float x,y;
	register int	xint,yint;
	/*
	** SOME VARIABLE ARE KEPT AS FLOATS BY NECCESSITY,
	** SO THE ABOVE MAKES THEM INTEGERS
	*/
	register int l;
	int k, xpoints,ypoints;
	float temp1, temp2;
	int temp3;
	/* these temps are used because adjust fixes all
	** 3 parameters (lo, hi, dist) but only some will
	** be put in the global locations, and these are temp-
	** orary storage
	*/





	if( status & NO_BORDER )
		return;
	status =| NO_BORDER;
	if(gstatus & TO_HARD_COPY)
	{
#ifdef	ELEC
		if(! (gstatus & HARD_COPY_ON))
		{
			puts(PLOTTER_ON,stdout);
			gstatus =| HARD_COPY_ON;
		}
		/* and a stty to turn echo off should be here */
#else
		fprintf(stderr,"\nGo to the plotter.\n%s\n",
		"Press the 'CALL' button to start and continue plotting");
#endif
	}
	if((status & XINC) && !(status & XMAN_SCALE))
	{
		temp1 = inc_min;
		temp2 = inc_max;
	}
	else
	{
		temp1 = xmin;
		temp2 = xmax;
	}
#ifdef	DEBUG
	fprintf(debug,"Before adjust xmin= %10.5f xmax = %10.5f\n",temp1,temp2);
#endif
	adjust(&temp1,&temp2,&temp3);
#ifdef	DEBUG
	fprintf(debug,"after : xmin = %10.5f xmax = %10.5f tick = %10d\n",temp1,temp2,temp3);
#endif
	if(! (status & XMAN_SCALE ))
	{
		xmin = temp1;
		xmax = temp2;
	}
	if( xtick_gap == 0.0)
	{
		xtick_gap = (xmax - xmin)/temp3;
		xpoints = temp3;
	}
	else
		xpoints = (xmax - xmin)/xtick_gap + 0.5;

	/*
	** THE USER SUPPLIES A DISTANCE BETWEEN NUMBERS
	** ON THE AXES, AND THIS IS CONVERTED TO THE
	** DISTANCE BETWEEN THE LITTLE TICKS
	*/
	xtick_gap =/ TICKS_PER_NUM;

	if((status & YINC) && !(status & YMAN_SCALE))
	{
		temp1 = inc_min;
		temp2 = inc_max;
	}
	else
	{
		temp1 = ymin;
		temp2 = ymax;
	}
#ifdef	DEBUG
	fprintf(debug,"before: ymin = %10.5f ymax = %10.5f\n",temp1,temp2);
#endif
	adjust(&temp1,&temp2,&temp3);
#ifdef	DEBUG
	fprintf(debug,"after: ymin= %10.5f ymax= %10.5f ticks= %10d\n",temp1,temp2,temp3);
#endif
	if(! (status & YMAN_SCALE ))
	{
		ymin = temp1;
		ymax = temp2;
	}
	if(ytick_gap == 0.0 )
	{
		ytick_gap = (ymax - ymin)/temp3;
		ypoints = temp3;
	}
	else
		ypoints = (ymax - ymin)/ytick_gap + 0.5;

	ytick_gap =/ TICKS_PER_NUM;


	/*
	** UNLESS THE USER MOVED THEM, THE AXES
	** ARE AT THE LEFT AND BOTTOM OF THE GRAPH
	*/
	if(! (status & MOVE_XAXIS))
		ypos = ymin;
	if(! (status & MOVE_YAXIS))
		xpos = xmin;


	uwindow(xmin - 0.20*(xmax - xmin), xmax + 0.1*(xmax - xmin),
		ymin - 0.1*(ymax - ymin), ymax + 0.1*(ymax - ymin));

	/*	XAXIS MARKER	*/
	if((gstatus & TO_HARD_COPY) || (gstatus & PAUSE_ON))
		pause();
	headings();	/* NO ERRORS SO FAR, SO DRAW THE HEADINGS OUT */
	if(gstatus & PAUSE_ON)
		pause();
	umovea(xpos,ymin);
	udrawa(xpos,ymax);
	umovea(xmin,ypos);
	udrawa(xmax,ypos);

	umovea(x = xmin,ypos);
	smover(0,TICK_SIZE*2);
	sdrawr(0,-TICK_SIZE*2);
	xprint(x);
	for(k=0; k<xpoints; k++)
	{
		for(l=1; l< TICKS_PER_NUM; l++)
		{
			/*
			** WE LOOP AROUND DOING
			** THE LITTLE TICKS
			*/
			umovea(x=+ xtick_gap,ypos);
			smover(0,TICK_SIZE);
			sdrawr(0,-TICK_SIZE);
		}
		umovea(x=+ xtick_gap,ypos);
		smover(0,TICK_SIZE*2);
		sdrawr(0,-TICK_SIZE*2);
		xprint(x);
	}
	/*	YAXIS	*/

	umovea(xpos,y = ymin);
	smover(TICK_SIZE*2,0);
	sdrawr(-TICK_SIZE*2,0);

	yprint(y);
	for(k=0; k<ypoints; k++)
	{
		for(l=1; l< TICKS_PER_NUM; l++)
		{
			umovea(xpos,y=+ ytick_gap);
			smover(TICK_SIZE,0);
			sdrawr(-TICK_SIZE,0);
		}
		umovea(xpos,y=+ ytick_gap);
		smover(TICK_SIZE*2,0);
		sdrawr(-TICK_SIZE*2,0);
		yprint(y);
	}
	/* THE OLD KEY BOX WAS HERE */
	/* draw in key if wanted */
	if((key_quadrant) && (key_quadrant != END))
	{
		if(gstatus & PAUSE_ON)
			pause();
		xint = xkey_pos;
		yint = ykey_pos;
		smovea(xint, yint=- 22);
		ykey_pos = yint;
		alpha();
		fputs("     KEY",stdout);
		smover(-5,22);
		sdrawr(HOR_BOX_SIZE*14 +52, 0);
		sdrawr(0,-(VER_BOX_SIZE*22 + 52));
		sdrawr(-(HOR_BOX_SIZE*14 + 52), 0);
		sdrawr(0,VER_BOX_SIZE*22 + 52);
		smover(0, -26);
		sdrawr(HOR_BOX_SIZE*14 +52,0);
	}
	/* next we put up extra axes if wanted	*/
	if(gstatus & XMARK)
	{
		if(gstatus & PAUSE_ON)
			pause();
		/*
		** xint IS JUST A SPARE VARIABLE
		*/
		for( xint = 0; xint < xmark_count; xint++)
		{
			if((xmark[xint]>=xmin) && (xmark[xint]<=xmax))
			{
				umovea(xmark[xint],ymin);
				switch(mark_type)
				{
				case SOLID:
					udrawa(xmark[xint],ymax);
					break;
				case SHORT:
					udasha(xmark[xint],ymax,1);
					break;
				case SHORT_LONG:
					udasha(xmark[xint],ymax,3);
					break;
				case LONG:
					udasha(xmark[xint],ymax,2);
					break;
				case OTHER:
				case NOTHING:
					break;
				}
			}
		}
	}
	if(gstatus & YMARK)
	{
		if(gstatus & PAUSE_ON)
			pause();
		for( xint = 0; xint < ymark_count; xint++)
		{
			if((ymark[xint]>=ymin) && (ymark[xint]<=ymax))
			{
				umovea(xmin,ymark[xint]);
				switch(mark_type)
				{
				case SOLID:
					udrawa(xmax,ymark[xint]);
					break;
				case SHORT:
					udasha(xmax,ymark[xint],1);
					break;
				case SHORT_LONG:
					udasha(xmax,ymark[xint],3);
					break;
				case LONG:
					udasha(xmax,ymark[xint],2);
					break;
				case OTHER:
				case NOTHING:
					break;
				}
			}
		}
	}
	/* This is so that the scaling
	** will not change on the plotted
	** lines after the border has been
	** drawn
	*/
	status =| (XMAN_SCALE | YMAN_SCALE);
}

xprint(num)
float num;
{
	char	buf1[30];	/* A TEMPORARY HOME OF THE NUMBERS BEFORE THEY ARE PRINTED */
	char	buf2[30];	/* A TEMPORARY HOME OF THE NUMBERS BEFORE THEY ARE PRINTED */
	if(status & NO_NUMBERS)
		return;
	if(( fabs((num-xpos)/(ymax-ymin)) <0.02) && (ypos != ymin))
		return;
	if( fabs(num/(xmax-xmin)) < 0.00001)
	{
		num =  0.0;
	}
	sprintf(buf1,xformat,num);
	strcpy(buf1,skip(buf1,1));	/* SKIP OVER ANY LEADING BLANKS */
	if(buf1[strlen(buf1)-1] == '.')
		buf1[strlen(buf1)-1] = 0;
	smover(-strlen(buf1)*XCHRSZ/2, -(YCHRSZ+5));
	alpha();
	printf("%s",buf1);

}

yprint(num)
float num;
{
	char	buf1[30];	/* A TEMPORARY HOME OF THE NUMBERS BEFORE THEY ARE PRINTED */
	char	buf2[30];	/* A TEMPORARY HOME OF THE NUMBERS BEFORE THEY ARE PRINTED */



	if(status & NO_NUMBERS)
		return;
	if(( fabs((num-ypos)/(xmax-xmin)) <0.02) && (xpos != xmin))
		return;
	if( fabs(num/(ymax-ymin)) < 0.00001)
	{
		num = 0.0;
	}
	sprintf(buf1,yformat,num);
	strcpy(buf1,skip(buf1,1));
	if(buf1[strlen(buf1)-1] == '.')
		buf1[strlen(buf1)-1] = 0;
	smover(-(strlen(buf1)*XCHRSZ +5), -7);
	alpha();
	printf("%s",buf1);
}



/*
** THIS IS THE HEART OF PLOTS AUTOMATIC SCALING
** ABILITY. GIVEN A LO AND HI VALUE, IT WILL ADJUST
** THESE AND THE NUMBER OF TICKS BETWEEN THEM TO
** PRODUCE WHAT IT CONSIDERS TO BE A NICE SCALING
** THE ROUTINE IS ARBITARY AND FIDDLEY.
** BE MY GUEST TO SUPPLY A NEW ONE AND IF IT WORKS
** WELL THEN TELL THE AUTHOR ABOUT IT !
** (RICHARD GREVIS, AGSM U.N.S.W)
*/

adjust(lo,hi,divisions)
	register float *lo, *hi;
	int	*divisions;
{
	/*
	** THE NORMALISED LOW VALUE
	*/
	int nlo;
	float diff,sdiff;
	int   ndiff;


	diff =  *hi -  *lo;
	if(diff == 0.0)
	{
		/*	WE CAN'T SCALE THE DATA REALLY
		**	SO RATHER THAN BOMBING WE CHOOSE
		**	+- 10% TO BE THE SCALE THEN PLOUGH
		**	ON FROM THERE
		*/

		*hi =+ *hi/10.0;
		*lo =- *lo/10.0;
		diff = *hi - *lo;
		warning("Data constant, Arbitary scaling done");
	}

	sdiff = size(diff);
#ifdef	DEBUG
	fprintf(debug,"first diff = %10.5f	sdiff = %10.5f\n",diff,sdiff);
#endif
	 *lo = floor( *lo*SENSITIVITY/sdiff + 1.0e-2)*sdiff/SENSITIVITY;
	 *hi = ceil( *hi*SENSITIVITY/sdiff - 1.0e-2)*sdiff/SENSITIVITY;
	diff =  *hi - *lo;
	sdiff = size(diff);
	/*
	** WE MUST NORMALISE THE DIFFERANCE TO GET
	** BETWEEN 1 AND 20 FOR THE SWITCH
	*/
	if((diff*SENSITIVITY/sdiff +0.5) >= 10)
	{
		ndiff = SENSITIVITY*diff/sdiff + 0.5;
		sdiff =/ 2.0;
	}
	else
		ndiff = SENSITIVITY*2.0*diff/sdiff + 0.5;
	if(ndiff >20)
		ndiff =/ 5;
	if( *lo<0.0)nlo =  *lo/(sdiff) -0.5;
	else nlo =  *lo/(sdiff) + 0.5;
	nlo =% 10;
	if(nlo<0)nlo =+ 10;
#ifdef	DEBUG
	fprintf(debug," diff = %10.5f	sdiff = %10.5f\n",diff,sdiff);
	fprintf(debug,"ndiff = %10d	nlo = %10d\n",ndiff,nlo);
#endif
	switch(ndiff)
	{
		case 1:
		case 10:
		case 2:
		case 5:
		case 20:
			*divisions = 5;
			break;
		case 9:
			if((nlo == 1)) *lo =- sdiff;
			else  *hi =+ sdiff;
			*divisions = 5;
			break;
		case 18:
			if((nlo <= 2))
			{
				*lo =- nlo*sdiff;
			}
			else
				*hi =+ sdiff;
			*divisions = 5;
			break;
		case 8:
		case 4:
		case 16:
			*divisions = 4;
			break;
		case 15:
			if(nlo == 1)
				*lo =- sdiff;
			else
				*hi =+ sdiff;
			*divisions = 4;
			break;
		case 3:
		case 6:
		case 12:
			*divisions = 6;
			break;
		case 7:
			if(nlo<=3)
			{
				 *lo =- nlo*sdiff;
				*divisions = (14 -nlo)/2;
			}
			else
				*divisions = 7;	/* OR PERHAPS 7 */
			break;
		case 14:
			*divisions = 7;
			break;
		case 11:
			if(nlo == 1)
				*lo =- sdiff;
			else
				*hi =+ sdiff;
			*divisions = 6;
			break;
		case 13:
			if(nlo == 1)
				*lo =- sdiff;
			else
				*hi =+ sdiff;
			*divisions = 7;
			break;
		case 17:
			if(nlo <= 3)
			{
				*lo =- nlo*sdiff;
				*hi =+ (3-nlo)*sdiff;
			}
			else
				*hi =+ 3*sdiff;
			*divisions = 5;
			break;
		case 19:
			if(nlo ==1)
				*lo =- sdiff;
			else
				*hi =- sdiff;
			*divisions = 5;
			break;
		default:
			flush_warnings();
			error("Unknown scaling error, check data and consult Richard Grevis");
			gexit();
			break;
	}
}




headings()
{
	int	down;
	int k;

	k = 0;
	down = 0;


	if(gstatus & PAUSE_ON)
		pause();
	for( k=0; k< head_count; k++)
	{
		smovea(500 -strlen(head_str[k])*XCHRSZ/2, 750 -YCHRSZ*down++);
		alpha();
		fputs(head_str[k], stdout);
	}
	if(x_str)
	{
		smovea(500 -strlen(x_str)*XCHRSZ/2,10);
		alpha();
		fputs(x_str,stdout);
	}
	if(y_str)
		syputsa(10,380 + strlen(y_str)*YCHRSZ/2, y_str);
	if(date_str)
	{
		smovea(1022-(strlen(date_str)*XCHRSZ), 767);
		alpha();
		fputs(date_str,stdout);
	}
}