/* See SO1DPlot.h */ /* Last edited on 2003-07-08 13:33:52 by stolfi */ #include #include #include #include #include #include #include #include #include /* INTERNAL DATA TYPES */ /* Scale factor for Y (ranges over [0_1]) to plot Y. */ #define YSCALE ((double)0.70710678118654752440) //+0.03 /* INTERNAL PROTOTYPES */ /* IMPLEMENTATIONS */ void SO1DPlot_AddFunctionPicture ( SOPlot_PSStream *ps, /* Picture stream. */ SOFunction *f, /* Function to be plotted. */ FuncMap *FMap, /* Describes a local mapping of function values. */ SOGrid_Dim pDim, /* Function point dimension. */ double *initP, /* Initial graphic point. */ double *finP, /* Final graphic point. */ double fPlotMin, /* Nominal minimum {f} value. */ double fPlotMax, /* Nominal maximum {f} value. */ double limit_val, /* A value to plot a line for limit ckecking. Has to be positive. */ int fDivs, /* Number of divisions between the initial and the last point. */ double lineWidth, /* Line width for graphic plotting. */ double *fObsMin, /* (IN/OUT) Min value seen during plot. */ double *fObsMax, /* (IN/OUT) Max value seen during plot. */ char *caption /* Either picture comments or NULL. */ ) { int i, j; double dist, xdist, Inc[pDim], pnt[pDim]; double val, nval, midy, xinc, x, scale, ymargin, cpt_margin = 0.0; //cpt_margin = 0.07; //char tmpstr[100]; dist = 0; for(j = 0; j < pDim; j++) { xdist = (finP[j] - initP[j]); dist += xdist * xdist; Inc[j] = (double)xdist / fDivs; pnt[j] = initP[j]; } /* dist = distance between the two tracing points. */ dist = sqrt(dist); xinc = dist / fDivs; scale = (double)(dist * YSCALE) / (fPlotMax - fPlotMin); ymargin = (double)(dist * YSCALE) / 40; pswr_new_picture(ps, 0.0, dist + cpt_margin, 0.0, dist * YSCALE); /* Draws the background rectangle and middle y line (usually 0.0). */ pswr_set_fill_color(ps, 1.0, 1.0, 1.0); pswr_rectangle(ps, 0.0+cpt_margin, dist+cpt_margin, 0.0, dist * YSCALE, TRUE, TRUE); pswr_set_pen(ps, 0.0, 0.0, 0.8, lineWidth, 0.0, 0.0); midy = (fPlotMin + fPlotMax) / 2; /* Middle line - normally zero. */ pswr_segment(ps, 0.0+cpt_margin, (midy - fPlotMin)*scale, dist+cpt_margin, (midy - fPlotMin)*scale); /* if(limit_val >= 0 && limit_val < fPlotMax) */ /* { pswr_set_pen(ps, 0.0, 1.0, 1.0, lineWidth, 0.0, 0.0); */ /* pswr_segment(ps, 0.0, (limit_val - fPlotMin)*scale, dist, (limit_val - fPlotMin)*scale); */ /* } */ /* x = xinc; */ /* pswr_set_pen(ps, 0.5, 0.5, 0.5, lineWidth, 0.0, 0.0); */ /* for(i = 1; i < fDivs; i++) */ /* { pswr_segment(ps, x, 0.0, x, dist * YSCALE); */ /* x += xinc; */ /* } */ /* Writes value ranges. */ /* pswr_set_pen(ps, 0.0, 0.0, 0.0, lineWidth, 0.0, 0.0); */ /* if(fabs(fPlotMax) >= 10.0) */ /* for(i = 0; i <= 10; i++) */ /* { */ /* sprintf(tmpstr,"%.1g", fPlotMin + ((double)i/10.0)*(fPlotMax - fPlotMin)); */ /* pswr_label(ps, tmpstr, 0.0 + ymargin+0.055, (dist * YSCALE) * ((double)i/10.0) */ /* - (2.0*ymargin)+((double)0.0025*(10-i)), 1.0, 0.0); */ /* } */ /* else */ /* for(i = 0; i <= 10; i++) */ /* { */ /* sprintf(tmpstr,"%.2f", fPlotMin + ((double)i/10.0)*(fPlotMax - fPlotMin)); */ /* pswr_label(ps, tmpstr, 0.0 + ymargin+0.055, (dist * YSCALE) * ((double)i/10.0) */ /* - (2.0*ymargin)+((double)0.0025*(10-i)), 1.0, 0.0); */ /* } */ /* Specific well plot (temporary) */ /* printf(" DEBUG >> dist: %.16g \n\n", dist); */ /* pswr_set_pen(ps, 0.0, 0.8, 0.0, lineWidth, 0.0, 0.0); */ /* pswr_segment(ps, dist*0.7171572875+cpt_margin, 0.0, dist*0.7171572875+cpt_margin, dist * YSCALE); //teste1 */ /* pswr_segment(ps, dist*0.1489361702+cpt_margin, 0.0, dist*0.1489361702+cpt_margin, dist * YSCALE); //teste2 */ /* pswr_segment(ps, dist*0.8936170213+cpt_margin, 0.0, dist*0.8936170213+cpt_margin, dist * YSCALE); //teste2 */ if(FMap->map == NULL) f->m->eval(f, pnt, &val); else { double mval; f->m->eval(f, pnt, &mval); FMap->map(&mval, pnt, &val); } if(val < fPlotMin)val = fPlotMin; else if(val > fPlotMax)val = fPlotMax; if(val < *fObsMin)*fObsMin = val; if(val > *fObsMax)*fObsMax = val; x = 0.0; pswr_set_pen(ps, 0.8, 0.0, 0.0, lineWidth, 0.0, 0.0); for(i = 0; i < fDivs; i++) { for(j = 0; j < pDim; j++) pnt[j] += Inc[j]; if(FMap->map == NULL) f->m->eval(f, pnt, &nval); else { double mval; f->m->eval(f, pnt, &mval); FMap->map(&mval, pnt, &nval); } if(nval < fPlotMin)nval = fPlotMin; else if(nval > fPlotMax)nval = fPlotMax; if(nval < *fObsMin)*fObsMin = nval; if(nval > *fObsMax)*fObsMax = nval; pswr_segment(ps, x+cpt_margin, (val - fPlotMin)*scale, x+xinc+cpt_margin, (nval - fPlotMin)*scale); x += xinc; val = nval; } pswr_set_pen(ps, 0.0, 0.0, 0.0, lineWidth, 0.0, 0.0); if(caption != NULL)pswr_add_caption(ps, caption, 0.0); } void SO1DPlot_SingleFunction ( bool eps, /* TRUE for EPS figures, FALSE for PS document. */ char *paperSize, /* Paper size ({letter}, {a3}, etc.). */ double hFigSize, /* Total figure width (in pt). */ double vFigSize, /* Total figure height (in pt). */ SOFunction *f, /* Function to plot. */ FuncMap *FMap, /* Describes a local mapping of function values. */ SOGrid_Dim pDim, /* Function point dimension. */ double *initP, /* Initial graphic point. */ double *finP, /* Final graphic point. */ double fPlotMin, /* Nominal minimum {f} value. */ double fPlotMax, /* Nominal maximum {f} value. */ int fDivs, /* Number of divisions between the initial and the last point. */ double lineWidth, /* Line width for graphic plotting. */ char *figName, /* Figure name (minus extension). */ double *fObsMin, /* (IN/OUT) Min value seen during plot. */ double *fObsMax /* (IN/OUT) Max value seen during plot. */ ) { double hPageSize, vPageSize; if(paperSize == NULL) {hPageSize = hFigSize + 150; vPageSize = vFigSize + 150;} else pswr_get_paper_dimensions(paperSize, &hPageSize, &vPageSize); SOPlot_PSStream *ps = SOPlot_OpenStream(eps, figName, paperSize, hPageSize, vPageSize); double Margin = (eps ? 25 : 50); pswr_set_page_layout(ps, hPageSize - (2*Margin), vPageSize - (2*Margin), 0, Margin, Margin, (! eps), 1, 1); SO1DPlot_AddFunctionPicture ( ps, f, FMap, pDim, initP, finP, fPlotMin, fPlotMax, -1, fDivs, lineWidth, fObsMin, fObsMax, figName ); SOPlot_CloseStream(ps); } void SO1DPlot_Array ( double_vec array, /* Double array to get plotted. */ char *figName, /* Figure name (minus extension). */ double fPlotMin, /* Nominal minimum {f} value. */ double fPlotMax, /* Nominal maximum {f} value. */ int fDivs /* Number of divisions between function background lines. */ ) { int i; double hPageSize, vPageSize, Margin = 25, Xscale, Yscale, minval, maxval, lineWidth = 0.15; double xmargin = 0.05, ymargin = 0.05, yinc = (double)(fPlotMax - fPlotMin)/fDivs; char caption[350]; if(array.nel < 2)return; pswr_get_paper_dimensions("a4", &hPageSize, &vPageSize); SOPlot_PSStream *ps = SOPlot_OpenStream(TRUE, figName, "a4", hPageSize, vPageSize); pswr_set_page_layout(ps, hPageSize - (2*Margin), vPageSize - (2*Margin), 0, Margin, Margin, FALSE, 1, 1); minval = array.el[0]; maxval = array.el[0]; for(i = 1; i < array.nel; i++) { if(array.el[i] < minval) minval = array.el[i]; if(array.el[i] > maxval) maxval = array.el[i]; } Xscale = (double) 1.0 / array.nel; Yscale = (double) 1.0 / (fPlotMax - fPlotMin) * YSCALE; pswr_new_picture(ps, 0.0, 1.0+(2*xmargin), 0.0, 1.0*YSCALE+(2*ymargin)); /* Draws the background rectangle. */ pswr_set_fill_color(ps, 1.0, 1.0, 1.0); pswr_rectangle(ps, xmargin, xmargin+1.0, ymargin, 2*ymargin+1.0*YSCALE, TRUE, TRUE); /* Draws some gray background lines. */ pswr_set_pen(ps, 0.5, 0.5, 0.5, lineWidth, 0.0, 0.0); for(i = 1; i < array.nel; i++) pswr_segment(ps, xmargin+(i*Xscale), ymargin, xmargin+(i*Xscale), 2*ymargin+1.0*YSCALE); for(i = 1; i < fDivs; i++) pswr_segment(ps, xmargin, ymargin+(yinc * i)*Yscale, xmargin+1.0, ymargin+(yinc * i)*Yscale); pswr_set_pen(ps, 0.9, 0.2, 0.2, lineWidth, 0.0, 0.0); for(i = 1; i < fDivs; i++) { sprintf(caption,"%f", fPlotMin+(yinc * i)); pswr_label(ps, caption, 0.0, ymargin/2.0+(yinc * i)*Yscale, 0.0, 0.0); } /* Draws the graphic main line. */ pswr_set_pen(ps, 0.0, 0.8, 0.0, lineWidth, 0.0, 0.0); for(i = 1; i < array.nel; i++) pswr_segment(ps, xmargin+((i-1)*Xscale), ymargin+(array.el[i-1]-fPlotMin)*Yscale, xmargin+(i*Xscale), ymargin+(array.el[i]-fPlotMin)*Yscale); pswr_set_pen(ps, 0.0, 0.0, 0.0, lineWidth, 0.0, 0.0); sprintf(caption," %s Min: %.16g", figName, minval); pswr_label(ps, caption, 0.0, ymargin/2.0, 0.0, 0.0); sprintf(caption," %s Max: %.16g", figName, maxval); pswr_label(ps, caption, 0.0, 0.0, 0.0, 0.0); SOPlot_CloseStream(ps); }