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);
}
}