/*************************************************************************** * Copyright (c) 1986, Tim Mooney * * * * This software is released into the public domain. You may use, * * copy, modify, and redistribute it if this notice is retained. You * * may not sell it, but you may charge a nominal copying/hassle fee for * * making it available. * * * * MP is not finished. Send comments, suggestions, etc. to * * * * Tim Mooney * * 120 Purefoy Rd. * * Chapel Hill NC 27514 * ***************************************************************************/ /*************************************************************************** * mp.c - PLOT DATA EMBEDDED IN TEXT FILE * * Mp reads a text file and extracts data from it in a user-defined way. * (See getdat.c for details. Also, interactive help is available.) * When the data are collected, mp opens a high-res screen, and plots some * or all of the data -- again, in a user-defined way. Some of the * details of plotting specifications (keywords: "how_to string") are * explained in the file sample.dat. Interactive help is also available * from the function GetHowTo(). **************************************************************************** * Capabilities, limitations, and implementation notes: * * Mp can plot lines or points of varying sizes; with or without error * bars; in 10 colors. There is no internal limit on the number of data * sets plotted simultaneously, or on the number of points in a single * data set, or on the total size of all data sets. Memory is allocated * dynamically; when it's used up, mp will stop processing the data file * and crash when it tries to open a new screen. * * Points are actually drawn as squares, except for the smallest sizes. * Mp doesn't plot any other kinds of marks. Points may be any size; one * may fill the screen, in fact. All lines are solid, error bars are * lines. * * GetDat() can scale data on input, directed by information in the * data file it's reading. Although GetDat() can also extract a title and * labels from the data file, mp makes no use of them at present. * * Once the data are plotted on the screen, the user can zoom in and * out, disable axes and grid, etc. Also, the current picture can be * dumped to a file for plotting. The only plotter language supported * is HPGL (Hewlett-Packard) since it's the only one I know. * * Fast Floating Point routines are used throughout. ***************************************************************************/ #include #include #include #include "struct.h" #include "plotlim.h" extern int GetDat(); extern void plot(); long GfxBase = 0; long IntuitionBase = 0; int debug = FALSE; FFP xtic[MAXTICS],ytic[MAXTICS]; short xticp[MAXTICS],yticp[MAXTICS]; char filename[30]; main(argc,argv) char *argv[]; int argc; { register short i, j; int help=FALSE; int xcol=1, ycol=2, ecol=0, terse=TRUE; char c; FILE *fp; struct Pict *Pict; /*** PARSE ARGS ***/ filename[0] = 0; for (i=1; iErrBar = (ecol != 0); Pict->Tics = (struct Tics *)AllocMem(sizeof(struct Tics),MEMF_CLEAR); Pict->Tics->x = xtic;Pict->Tics->y = ytic; Pict->Tics->xp = xticp;Pict->Tics->yp = yticp; Pict->XRegionLock = Pict->YRegionLock = FALSE; Pict->Axes = TRUE; Pict->CurrReg = (struct PlotRegion *)AllocMem(sizeof(struct PlotRegion),MEMF_CLEAR); Pict->NewReg = (struct PlotRegion *)AllocMem(sizeof(struct PlotRegion),MEMF_CLEAR); Pict->Title = NULL; Pict->XLabel = NULL; Pict->YLabel = NULL; Pict->Plot = NULL; /*** GET DATA FROM FILE ***/ GetDat(fp, xcol, ycol, ecol, terse, Pict); if (debug) printf("mp: closing data file\n"); (void) fclose(fp); /*** PLOT DATA ***/ plot(Pict); /*** DEALLOCATE MEMORY ***/ FreeMem(Pict->NewReg,sizeof(struct PlotRegion)); FreeMem(Pict->CurrReg,sizeof(struct PlotRegion)); FreeMem(Pict->Tics,sizeof(struct Tics)); FreeMem(Pict,sizeof(struct Pict)); FreeStructPlot(); return(0); } /************************************************/ #define P_XREG 10000 #define P_YREG 10000 #define P_X_TIC_SIZE X_TIC_SIZE*(P_YREG/MAXVERT) #define P_Y_TIC_SIZE Y_TIC_SIZE*(P_XREG/MAXHORIZ) #define P_CH_WID 75 #define P_CH_HEI 150 #define P_LMARGIN P_CH_WID*8 #define P_BMARGIN P_CH_HEI*2 #define P_TMARGIN 0 #define P_RMARGIN 0 static FFP XScale, YScale, XOffset, YOffset; void fWrtFFP(fp, ffpval) FILE *fp; FFP ffpval; { fprintf(fp, "%d", (int)ffpval); } void WrtAxes(fp, Tics, Grid) FILE *fp; struct Tics *Tics; short Grid; { short n, tmpx, tmpy, i; FFP *x, *y; char tmpstr[20]; /*** DRAW BORDER ***/ fprintf(fp,"SP1;PU%d %d;",P_LMARGIN,P_BMARGIN); fprintf(fp,"PD%d %d %d %d %d %d %d %d;\n",P_XREG,P_BMARGIN,P_XREG,P_YREG, P_LMARGIN,P_YREG,P_LMARGIN,P_BMARGIN); /*** DRAW TICS/GRID ***/ fprintf(fp,"SP2;"); x=Tics->x; y=Tics->y; for (i=1; i < Tics->NX; i++) { if (Grid) { fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;PD",P_BMARGIN); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;\n",P_YREG); } else { fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;PD",P_BMARGIN); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;",P_BMARGIN + P_X_TIC_SIZE); fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;PD",P_YREG); fWrtFFP(fp,(XScale * (XOffset + x[i]))); fprintf(fp," %d;\n",P_YREG - P_X_TIC_SIZE); } } for (i=1; i < Tics->NY; i++) { if (Grid) { fprintf(fp,"PU%d ",P_LMARGIN); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,"PD%d ",P_XREG); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,";\n"); } else { fprintf(fp,"PU%d ",P_LMARGIN); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,";PD%d ", P_LMARGIN + P_Y_TIC_SIZE); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,";"); fprintf(fp,"PU%d ",P_XREG); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,";PD%d ", P_XREG - P_Y_TIC_SIZE); fWrtFFP(fp,(YScale * (YOffset + y[i]))); fprintf(fp,";\n"); } } /*** PRINT TIC VALUES ***/ fprintf(fp,"SP1;"); for (i=0; i < Tics->NX; i++) { n = sprintf(tmpstr, "%-.4f", Tics->x[i]); n = min(n, 7); while (tmpstr[n-1] == '0') n--; tmpstr[n]=0; tmpx = (short)((XScale * (XOffset + Tics->x[i]))); tmpx -= (((n+1)/2)-.5) * P_CH_WID; fprintf(fp, "PU%d 1;", tmpx); fprintf(fp,"LB%s\003", tmpstr); } for (i=0; i < Tics->NY; i++) { n = sprintf(tmpstr, "%-.4f", Tics->y[i]); n = min(n, 7); while (tmpstr[n-1] == '0') n--; tmpstr[n]=0; tmpy = (short)((YScale * (YOffset + Tics->y[i]))); tmpy -= .5 * P_CH_WID; fprintf(fp, "PU1 %d;", tmpy); fprintf(fp,"LB%s\003", tmpstr); } } extern char *stpchr(); WrtPlt(Pict) struct Pict *Pict; { FILE *fp; short i; struct Plot *Plot; FFP *x, *y, *e; short xptsiz, yptsiz; char plotname[30], *chptr; static char PlotNum = 0; strcpy(plotname,filename); if (chptr = stpchr(plotname,'.')) { chptr[1]='p'; chptr[2]='l'; chptr[3]='t'; chptr[4] = '0' + PlotNum; chptr[5]=0; } else { i=strlen(plotname); plotname[i]='.'; plotname[i+1]='p'; plotname[i+2]='l'; plotname[i+3]='t'; plotname[i+4] = '0' + PlotNum; plotname[i+5]=0; } if (!(fp = fopen(plotname,"w") )) {printf("can't open %s\n",plotname); return(FALSE);} fprintf(fp,"IN;SC 0 %d 0 %d;\n", P_XREG+2, P_YREG+2); fprintf(fp,"VS 20.0;\n"); /* VELOCITY cm/s */ fprintf(fp,"\033.N;19:\033.I81;;17:\n"); /* XON/XOFF */ XScale = (FFP)(P_XREG - P_LMARGIN - P_RMARGIN) / (Pict->CurrReg->XMax - Pict->CurrReg->XMin); YScale = (FFP)(P_YREG - P_BMARGIN - P_TMARGIN) / (Pict->CurrReg->YMax - Pict->CurrReg->YMin); XOffset = (FFP)(P_LMARGIN) / XScale - Pict->CurrReg->XMin; YOffset = (FFP)(P_BMARGIN) / YScale - Pict->CurrReg->YMin; Plot = Pict->Plot; while (Plot) { if (Plot->Enabled) { fprintf(fp,"PU;SP%d;\n", 1+Plot->Color-PLOTCOLORBASE); /* PLOT LINES */ if (Plot->PointSize <= 0) { x=Plot->x; y=Plot->y; fprintf(fp, "PU"); fWrtFFP(fp,(XScale * (XOffset + *x))); fprintf(fp," "); fWrtFFP(fp,(YScale * (YOffset + *y))); fprintf(fp,";"); x++; y++; fprintf(fp, "PD"); for (i=1; iNPts; i++, x++, y++) { if (i>1) fprintf(fp, " "); fWrtFFP(fp,(XScale * (XOffset + *x))); fprintf(fp," "); fWrtFFP(fp,(YScale * (YOffset + *y))); } fprintf(fp,";\n"); } /* PLOT POINTS */ if (Plot->PointSize != 0) { /* xptsiz = abs(Plot->PointSize) * (P_XREG / (100 * 11)); */ /* yptsiz = abs(Plot->PointSize) * (P_YREG / (100 * 8.5)); */ xptsiz = abs(Plot->PointSize) * (P_XREG / 1100); yptsiz = abs(Plot->PointSize) * (P_YREG / 850); x=Plot->x; y=Plot->y; for (i=0; iNPts; i++, x++, y++) { fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + *x))); fprintf(fp," "); fWrtFFP(fp,(YScale * (YOffset + *y))); fprintf(fp,";"); fprintf(fp,"PR%d %d;", -xptsiz/2, -yptsiz/2); fprintf(fp,"PD%d 0 0 %d %d 0 0 %d;PA;\n", xptsiz, yptsiz, -xptsiz, -yptsiz); } } /* PLOT ERROR BARS */ if (Pict->ShowErr) { x=Plot->x; y=Plot->y; e=Plot->e; for (i=0; iNPts; i++, x++, y++, e++) { fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + *x))); fprintf(fp," "); fWrtFFP(fp,(YScale * (YOffset + (*y - *e)))); fprintf(fp,";PD"); fWrtFFP(fp,(XScale * (XOffset + *x))); fprintf(fp," "); fWrtFFP(fp,(YScale * (YOffset + (*y + *e)))); fprintf(fp,";\n"); } } } Plot = Plot->NextPlot; } fprintf(fp,"SR%f %f;\n", (float)(100*P_CH_WID) / (P_XREG - P_LMARGIN - P_RMARGIN), (float)(100*P_CH_HEI) / (P_YREG - P_BMARGIN - P_TMARGIN)); WrtAxes(fp, Pict->Tics, Pict->Grid); fprintf(fp, "SP;"); (void) fclose(fp); PlotNum++; return(TRUE); } To_mCAD(Pict) struct Pict *Pict; { FILE *fp; short i; struct Plot *Plot; FFP *x, *y, *e, xtmp, ytmp, xtmp1, ytmp1; FFP xptsiz, yptsiz, XReg, YReg, XScale, XOffset; char plotname[30], *chptr; static char mPlotNum = 0; strcpy(plotname,filename); if (chptr = stpchr(plotname,'.')) { chptr[1]='c'; chptr[2]='a'; chptr[3]='d'; chptr[4] = '0' + mPlotNum; chptr[5]=0; } else { i=strlen(plotname); plotname[i]='.'; plotname[i+1]='c'; plotname[i+2]='a'; plotname[i+3]='d'; plotname[i+4] = '0' + mPlotNum; plotname[i+5]=0; } if (!(fp = fopen(plotname,"w") )) {printf("can't open %s\n",plotname); return(FALSE);} XReg = Pict->CurrReg->XMax - Pict->CurrReg->XMin; YReg = Pict->CurrReg->YMax - Pict->CurrReg->YMin; XScale = YReg/XReg * 1.4434; XOffset = Pict->CurrReg->XMin; Plot = Pict->Plot; while (Plot) { if (Plot->Enabled) { /* PLOT LINES */ if (Plot->PointSize <= 0) { x=Plot->x; y=Plot->y; for (i=1; iNPts; i++, x++, y++) { xtmp = XScale * (*x - XOffset); fprintf(fp, "%f %f\n", xtmp, *y); } fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE); } /* PLOT POINTS */ if (Plot->PointSize != 0) { xptsiz = abs(Plot->PointSize) * (XReg / 582.); xptsiz = XScale * xptsiz; yptsiz = abs(Plot->PointSize) * (YReg / 360.); x=Plot->x; y=Plot->y; for (i=0; iNPts; i++, x++, y++) { xtmp = XScale * (*x - XOffset); xtmp -= xptsiz/2; ytmp = *y - yptsiz/2; fprintf(fp,"%f %f\n", xtmp, ytmp); xtmp += xptsiz; fprintf(fp,"%f %f\n", xtmp, ytmp); ytmp += yptsiz; fprintf(fp,"%f %f\n", xtmp, ytmp); xtmp -= xptsiz; fprintf(fp,"%f %f\n", xtmp, ytmp); ytmp -= yptsiz; fprintf(fp,"%f %f\n", xtmp, ytmp); fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE); } } /* PLOT ERROR BARS */ if (Pict->ShowErr) { x=Plot->x; y=Plot->y; e=Plot->e; for (i=0; iNPts; i++, x++, y++, e++) { xtmp = XScale * (*x - XOffset); ytmp = *y - *e; fprintf(fp,"%f %f\n", xtmp, ytmp); ytmp = *y + *e; fprintf(fp,"%f %f\n", xtmp, ytmp); fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE); } } } Plot = Plot->NextPlot; } /*** DRAW TICS/GRID ***/ x = Pict->Tics->x; y = Pict->Tics->y; for (i=1; i < Pict->Tics->NX; i++) { xtmp = XScale * (x[i] - XOffset); if (Pict->Grid) { PToU(Pict, 0, YMINP, &xtmp, &ytmp); PToU(Pict, 0, YMAXP, &xtmp1, &ytmp1); fprintf(fp,"%f %f\n%f %f\n*>\n*C 2\n\n", xtmp, ytmp, xtmp, ytmp1); } else { PToU(Pict, 0, YMINP, &xtmp1, &ytmp); fprintf(fp,"%f %f\n", xtmp, ytmp); PToU(Pict, 0, YMINP+X_TIC_SIZE, &xtmp1, &ytmp1); fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp, ytmp1); PToU(Pict, 0, YMAXP, &xtmp1, &ytmp); fprintf(fp,"%f %f\n", xtmp, ytmp); PToU(Pict, 0, YMAXP-X_TIC_SIZE, &xtmp1, &ytmp1); fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp, ytmp1); } } for (i=1; i < Pict->Tics->NY; i++) { if (Pict->Grid) { PToU(Pict, XMINP, YMINP, &xtmp, &ytmp); xtmp = XScale * (xtmp - XOffset); PToU(Pict, XMAXP, YMAXP, &xtmp1, &ytmp1); xtmp1 = XScale * (xtmp1 - XOffset); fprintf(fp,"%f %f\n%f %f\n*>\n*C 2\n\n", xtmp, y[i], xtmp1, y[i]); } else { PToU(Pict, XMINP, 0, &xtmp, &ytmp); xtmp = XScale * (xtmp - XOffset); fprintf(fp,"%f %f\n", xtmp, y[i]); PToU(Pict, XMINP+Y_TIC_SIZE, 0, &xtmp1, &ytmp1); xtmp1 = XScale * (xtmp1 - XOffset); fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp1, y[i]); PToU(Pict, XMAXP, 0, &xtmp, &ytmp); xtmp = XScale * (xtmp - XOffset); fprintf(fp,"%f %f\n", xtmp, y[i]); PToU(Pict, XMAXP-Y_TIC_SIZE, 0, &xtmp1, &ytmp1); xtmp1 = XScale * (xtmp1 - XOffset); fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp1, y[i]); } } /*** PRINT TIC VALUES ***/ /* * for (i=0; i < Pict->Tics->NX; i++) { * n = sprintf(tmpstr, "%-.4f", Pict->Tics->x[i]); * n = min(n, 7); * while (tmpstr[n-1] == '0') n--; * tmpstr[n]=0; * } * for (i=0; i < Pict->Tics->NY; i++) { * n = sprintf(tmpstr, "%-.4f", Pict->Tics->y[i]); * n = min(n, 7); * while (tmpstr[n-1] == '0') n--; * tmpstr[n]=0; * } */ /*** DRAW AXES ***/ PToU(Pict, XMINP, YMINP, &xtmp, &ytmp); xtmp = XScale * (xtmp - XOffset); PToU(Pict, XMAXP, YMAXP, &xtmp1, &ytmp1); xtmp1 = XScale * (xtmp1 - XOffset); fprintf(fp, "%f %f\n", xtmp, ytmp); fprintf(fp, "%f %f\n", xtmp1, ytmp); fprintf(fp, "%f %f\n", xtmp1, ytmp1); fprintf(fp, "%f %f\n", xtmp, ytmp1); fprintf(fp, "%f %f\n", xtmp, ytmp); fprintf(fp,"*C 1\n\n"); (void) fclose(fp); mPlotNum++; return(TRUE); }