home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff292.lzh
/
MultiPlot
/
source
/
plot.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-10
|
12KB
|
463 lines
#include "struct.h"
#include "plot.h"
#include <graphics/gfxmacros.h>
extern struct Window *window;
extern int CHARWIDTH;
extern int CHARHEIGHT;
extern int LMARGIN; /* CHARWIDTH x 7 */
extern int TMARGIN;
extern int BMARGIN; /* CHARHEIGHT x 3 */
extern int XMINP; /* LMARGIN */
extern int YMAXP; /* MAXVERT - TMARGIN */
extern int YMINP; /* BMARGIN */
extern int debug;
extern int MAXVERT;
extern FFP fround();
extern struct Pict *Pict;
struct TextAttr xfont = { "Times.font", 14, 0, 1 };
struct TextAttr yfont = { "Times.font", 14, 0, 1 };
struct TextAttr tfont = { "Times.font", 24, 0, 1 };
struct IntuiText XITLabel = {
1,0,JAM1, /* front and back text pens, drawmode and fill byte */
0,0, /* XY origin relative to container TopLeft */
&xfont, /* font pointer or NULL for default */
NULL, /* pointer to text */
NULL /* next IntuiText structure */
};
struct IntuiText YITLabel = {
1,0,JAM1, /* front and back text pens, drawmode and fill byte */
0,0, /* XY origin relative to container TopLeft */
&yfont, /* font pointer or NULL for default */
NULL, /* pointer to text */
NULL /* next IntuiText structure */
};
struct IntuiText TITLabel = {
1,0,JAM1, /* front and back text pens, drawmode and fill byte */
0,0, /* XY origin relative to container TopLeft */
&tfont, /* font pointer or NULL for default */
NULL, /* pointer to text */
NULL /* next IntuiText structure */
};
struct TextFont *xf;
struct TextFont *yf;
struct TextFont *tf;
AllowForText()
{
if (Pict->XLabel!=NULL) {
xf=(struct TextFont *) OpenDiskFont(&xfont);
if (xf) {
YMINP = BMARGIN=( xfont.ta_YSize +CHARHEIGHT *4);
CloseFont(xf);
}
else YMINP = BMARGIN= CHARHEIGHT *5;
}
if (Pict->Title!=NULL) {
tf=(struct TextFont *) OpenDiskFont(&tfont);
if (tf) {
YMAXP = MAXVERT - (TMARGIN=( tfont.ta_YSize +CHARHEIGHT *2));
CloseFont(tf);
}
else YMAXP = MAXVERT- (TMARGIN=CHARHEIGHT*3);
}
if (Pict->YLabel!=NULL) {
yf=(struct TextFont *) OpenDiskFont(&yfont);
YITLabel.IText=Pict->YLabel;
if (yf) {
XMINP=LMARGIN=abs(IntuiTextLength(&YITLabel)/strlen(Pict->YLabel))+(9*CHARWIDTH);
CloseFont(yf);
}
else XMINP=LMARGIN=9*CHARWIDTH;
}
return(0);
}
/**********************/
void GetDataLimits(Pict)
struct Pict *Pict;
{
short i;
FFP *x, *y, *e;
struct Plot *Plot;
FFP xmin, xmax, ymin, ymax;
xmin = (ymin = FFPLARGE);
xmax = (ymax = -FFPLARGE);
Plot = Pict->Plot;
while (Plot) {
if (Plot->Enabled) {
i = 0; x = Plot->x; y = Plot->y;
if (Pict->ShowErr) e = Plot->e;
while (i++ < Plot->NPts) {
xmax = max(*x,xmax);
xmin = min(*x,xmin);
x++;
if (Pict->ShowErr) {
ymax = max((*y + *e), ymax);
ymin = min((*y - *e), ymin);
y++; e++;
}
else {
ymax = max(*y,ymax);
ymin = min(*y,ymin);
y++;
}
}
}
Plot = Plot->NextPlot;
}
if (!Pict->XRegionLock)
{Pict->CurrReg->XMax = xmax; Pict->CurrReg->XMin = xmin;}
if (!Pict->YRegionLock)
{Pict->CurrReg->YMax = ymax; Pict->CurrReg->YMin = ymin;}
}
/*****************************************/
void AdjustForTics(dmin, dmax, ntics, tics)
FFP *dmin, *dmax, *tics;
short ntics;
{
FFP tmp, fract, f_ntics;
short i;
f_ntics = (FFP)(ntics);
fract = (FFP)(ntics+1) / f_ntics;
/*** adjust data limits to make "nice" numbers for tic marks ***/
tmp = *dmin - (*dmax - *dmin) / 5;
*dmin = fround( *dmin, DOWN, tmp);
tmp = (*dmax - *dmin) / f_ntics;
tmp = fround( tmp, UP, (tmp * fract) );
*dmax = *dmin + tmp * f_ntics;
tics[0] = fround( *dmin, UP, *dmin+tmp/2);
if (debug) printf("... tic[0]=%f\n", tics[0]);
for (i=1; i<ntics; i++) {
tics[i] = tics[i-1] + tmp;
if (debug) printf("... tic[%d]=%f\n", i, tics[i]);
}
}
/**************/
void Scale(Pict)
struct Pict *Pict;
{
struct Plot *Plot;
struct PlotRegion *Reg;
struct Tics *Tics;
register short i, *xp, *yp;
register FFP *x, *y, xmin, ymin, xscale, yscale;
short *ep, err, err_sav = TRUE;
FFP *e, xmax, ymax;
if (debug) printf("Scale: entry\n");
Reg = Pict->CurrReg;
xmin = Reg->XMin; xmax = Reg->XMax;
ymin = Reg->YMin; ymax = Reg->YMax;
if (FFPSAME(xmax,xmin))
{printf("Scale: xmax = xmin, xscale := 0.\n"); xscale = (FFP)0;}
else
Pict->XScale = xscale = (FFP)(XMAXP-XMINP) / (xmax - xmin);
if (FFPSAME(ymax,ymin))
{printf("Scale: ymax = ymin, yscale := 0.\n"); yscale = (FFP)0;}
else
Pict->YScale = yscale = (FFP)(YMAXP-YMINP) / (ymax - ymin);
#define NEW_X_REGION ( !FFPSAME(Reg->XMin,xmin) || !FFPSAME(Reg->XMax,xmax) )
#define NEW_Y_REGION ( !FFPSAME(Reg->YMin,ymin) || !FFPSAME(Reg->YMax,ymax) )
/* DATA */
Plot = Pict->Plot;
err = Pict->ShowErr;
while (Plot) {
if (Plot->Enabled) {
Reg = Plot->Reg;
if (NEW_X_REGION) {
x = Plot->x; xp = Plot->xp;
for (i = 0; i < Plot->NPts; i++) {
*xp++ = XMINP + (short)((*x++ - xmin) * xscale);
if (debug) printf("*xp=%d\n", *(xp-1));
}
Reg->XMin = xmin; Reg->XMax = xmax;
}
if ( (NEW_Y_REGION) || (err_sav!=err) ) {
y = Plot->y; yp = Plot->yp; e = Plot->e; ep = Plot->ep;
for (i = 0; i < Plot->NPts; i++) {
*yp++ = YMINP + (short)((*y++ - ymin) * yscale);
if (debug) printf("*yp=%d", *(yp-1));
if (err) {
*ep++ = (short)(*e++ * yscale);
if (debug) printf(", *ep=%d", *(ep-1));
}
if (debug) printf("\n");
}
Reg->YMin = ymin; Reg->YMax = ymax;
}
}
Plot = Plot->NextPlot;
}
err_sav = err;
/* TICS */
Tics = Pict->Tics;
for (i=0; i < Tics->NX; i++)
Tics->xp[i] = XMINP + (short)((Tics->x[i] - xmin) * xscale);
for (i=0; i < Tics->NY; i++)
Tics->yp[i] = YMINP + (short)((Tics->y[i] - ymin) * yscale);
if (debug) printf("Scale: entry\n");
}
/**********************/
void DrawAxes(Tics,Grid)
struct Tics *Tics; short Grid;
{
short *xp, *yp, n, tmpx, tmpy, i;
char tmpstr[20];
/*** DRAW BORDER ***/
SetDrMd(rp, JAM1);
SetAPen(rp,2); SetOPen(rp,1);
PRectFill(XMINP-1,YMINP-1,XMAXP+1,YMAXP+1);
PRectFill(XMINP,YMINP,XMAXP,YMAXP);
/*** DRAW TICS/GRID ***/
SetAPen(rp,3);
xp=Tics->xp; yp=Tics->yp;
if (Grid) SetRGB4(vp,3,0,15,15);
for (i=1; i < Tics->NX; i++) {
if (Grid) {
PMove(xp[i],YMINP+1); PDraw(xp[i],YMAXP-1);
}
else {
PMove(xp[i],YMINP+1); PDraw(xp[i],YMINP+X_TIC_SIZE);
PMove(xp[i],YMAXP-1); PDraw(xp[i],YMAXP-X_TIC_SIZE);
}
}
for (i=1; i < Tics->NY; i++) {
if (Grid) {
PMove(XMINP+1,yp[i]); PDraw(XMAXP-1,yp[i]);
}
else {
PMove(XMINP+1,yp[i]); PDraw(XMINP+Y_TIC_SIZE,yp[i]);
PMove(XMAXP-1,yp[i]); PDraw(XMAXP-Y_TIC_SIZE,yp[i]);
}
}
/*** PRINT TIC VALUES AND TEXT ***/
SetAPen(rp,1);
for (i=0; i < Tics->NX; i++) {
n = sprintf(&tmpstr, "%-.4f", Tics->x[i]);
n = min(n, 7);
while (tmpstr[n-1] == '0') n--;
tmpx = Tics->xp[i] - ((n/2) - (FFP)1/2) * CHARWIDTH;
tmpy = max(0, YMINP-2*CHARHEIGHT);
PMove(tmpx, tmpy); Text(rp,tmpstr,n);
}
XITLabel.IText=Pict->XLabel;
n=IntuiTextLength(&XITLabel);
tmpx=( (LMARGIN + (XMAXP-XMINP)/2) - (n/2) );
tmpy = (MAXVERT-xfont.ta_YSize-CHARHEIGHT);
PrintIText(rp,&XITLabel,tmpx,tmpy);
TITLabel.IText=Pict->Title;
n=IntuiTextLength(&TITLabel);
tmpx=( (MAXHORIZ/2) - (n/2) );
tmpy = (CHARHEIGHT);
PrintIText(rp,&TITLabel,tmpx,tmpy);
PrintVText(rp,&YITLabel,2,(MAXVERT/2)-( (strlen(Pict->YLabel)/2)*(yfont.ta_YSize+1)));
for (i=0; i < Tics->NY; i++) {
n = sprintf(&tmpstr, "%-.4f", Tics->y[i]);
n = min( n, (LMARGIN/CHARWIDTH)-1 );
while (tmpstr[n-1] == '0') n--;
tmpx = max(0, XMINP-(n+1)*CHARWIDTH);
PMove(tmpx, Tics->yp[i]-CHARHEIGHT/2); Text(rp,tmpstr,n);
}
}
/*****************/
void DrawPlot(Pict)
struct Pict *Pict;
{
struct Plot *Plot;
short *x, *y, *e, n, m, i;
SetDrMd(rp, JAM1);
Plot = Pict->Plot;
while (Plot) {
if (Plot->Enabled) {
SetAPen(rp, Plot->Color);
/* PLOT POINTS */
if (Plot->PointSize != 0) {
n = Plot->PointSize;
if (abs(n) > 2) {m = (abs(n)/2)-1; SetOPen(rp, Plot->Color);}
x = Plot->xp; y = Plot->yp;
for (i=0; i<Plot->NPts; i++, x++, y++) {
switch (abs(n)) {
case 0: break;
case 1: PWritePixel(*x, *y); break;
case 2: PWritePixel(*x, *y); PWritePixel(*x, *y+1); break;
case 3: PRectFill(*x, *y, *x+1, *y+1); break;
default: PRectFill(*x-m, *y-m, *x+m, *y+m); break;
}
}
}
/* PLOT LINES */
if (Plot->PointSize <= 0) {
PMove(*Plot->xp, *Plot->yp);
x = &(Plot->xp[1]); y = &(Plot->yp[1]);
for (i=1; i<Plot->NPts; i++, x++, y++) PDraw(*x, *y);
}
/* PLOT ERROR BARS */
if (Pict->ShowErr) {
x = Plot->xp; y = Plot->yp; e = Plot->ep;
for (i=0; i < Plot->NPts; i++, x++, y++, e++) {
PMove(*x, *y - *e); PDraw(*x, *y + *e);
}
}
}
Plot = Plot->NextPlot;
}
SetDrMd(rp, COMPLEMENT);
}
/*************************************************************/
extern int CheckUser();
extern int GetHowTo();
extern void CleanUp();
extern USHORT chip WaitSprite[];
extern struct Window *window;
void plot(Pict)
struct Pict *Pict;
{
struct PlotRegion *Reg;
struct Tics *Tics;
int req = GETDATALIMITS;
GetHowTo(Pict);
Tics = Pict->Tics;
InitWind();
do {
switch(req) {
case GETHOWTO:
GetHowTo(Pict); /* fall thru */
case GETDATALIMITS: AllowForText(); GetDataLimits(Pict);
case REPLOT:
default: ;
}
SetPointer(window,WaitSprite,26,14,-4,-4);
Reg = Pict->CurrReg;
if (!Pict->XRegionLock)
AdjustForTics(&Reg->XMin, &Reg->XMax, Tics->NX, Tics->x);
if (!Pict->YRegionLock)
AdjustForTics(&Reg->YMin, &Reg->YMax, Tics->NY, Tics->y);
Scale(Pict);
SetRast(rp,0);
if (Pict->Axes) DrawAxes(Pict->Tics,Pict->Grid);
DrawPlot(Pict);
ClearPointer(window);
req = CheckUser(Pict);
} while (req != QUIT);
CleanUp();
}
/***************************/
void PToU(Pict, xp, yp, x, y)
struct Pict *Pict;
short xp, yp;
FFP *x, *y;
{
if (debug) printf("PToU: entry, xp=%d, yp=%d\n", xp, yp);
*x = Pict->CurrReg->XMin + (FFP)(xp-XMINP) / Pict->XScale;
*y = Pict->CurrReg->YMin + (FFP)(yp-YMINP) / Pict->YScale;
if (debug) printf("PToU: exit, *x=%f, *y=%f\n", *x, *y);
}
PrintVText(rp,PText,X,Y)
struct RastPort *rp;
struct IntuiText *PText;
int X;
int Y;
{
struct TextFont *f;
int height;
int i,n,x,y;
struct TextAttr *at;
static struct TextAttr old_at;
char c;
AskFont(rp,&old_at);
while (PText)
{
SetAPen(rp,PText->FrontPen);
SetBPen(rp,PText->BackPen);
SetDrMd(rp,PText->DrawMode);
at=PText->ITextFont;
f=NULL;
f=(struct TextFont *) OpenFont(at);
if (f) {
SetFont(rp,f);
height=at->ta_YSize+1;
}
else height=9;
x=X+PText->LeftEdge+TextLength(rp,"M",1);
y=Y+PText->TopEdge;
n=strlen(PText->IText);
for (i=0;i<n;i++)
{
c=PText->IText[i];
Move(rp,abs(x-(TextLength(rp,&c,1)/2)),y+(i*height));
Text(rp,&c,1);
}
CloseFont(f);
PText=PText->NextText;
}
f=(struct TextFont *) OpenFont(&old_at);
SetFont(rp,f);
return(0);
}