/* See SOPlot.h */ /* Last edited on 2003-07-08 14:56:12 by stolfi */ #include #include #include #include #include #include #include #include #include #include /* #define TwoPi (2.0 * Pi) */ #define Invisible ((Color){{-1,-1,-1}}) /* FILE AND PAGE CONTROL */ SOPlot_PSStream *SOPlot_OpenStream ( bool eps, /* TRUE for EPS figures, FALSE for PS document. */ char *name, /* Document name or figure name prefix. */ char *paperSize, /* Paper size ({letter}, {a3}, etc.). */ double hPageSize, /* Total figure width (in pt). */ double vPageSize /* Total figure height (in pt). */ ) { SOPlot_PSStream *ps; ps = pswr_new_stream(eps, name, NULL, paperSize, hPageSize, vPageSize); return(ps); } void SOPlot_CloseStream(SOPlot_PSStream *ps) { pswr_close_stream(ps); } void SOPlot_ChangeLayout ( SOPlot_PSStream *ps, /* Picture stream. */ char *paperSize, /* Paper size ({letter}, {a3}, etc.). */ double hPicSize, /* Width of each picture (in pt). */ double vPicSize, /* Height of each picture (in pt). */ /* bool adjustPicSize, /\* TRUE to fit {hPicSize,vPicSize} to page size. *\/ */ /* double hPicMargin, /\* Left/right margin for each picture (in pt). *\/ */ /* double vPicMargin, /\* Top/bottom margin for each picture (in pt). *\/ */ int captionLines, /* Number of caption lines below each picture. */ int hCount, /* Number of pictures in each row. */ int vCount /* Number of pictures in each column. */ ) { bool adjustPicSize = TRUE; double hPageSize, vPageSize; double hPicMargin = 5, vPicMargin = 5; if(strlen(paperSize)) { pswr_get_paper_dimensions(paperSize, &hPageSize, &vPageSize); hPicSize = (int)(hPageSize - (2*hCount*hPicMargin)-160) / hCount; vPicSize = (int)(vPageSize - (2*vCount*vPicMargin)-160) / vCount; } pswr_set_page_layout(ps, hPicSize, vPicSize, adjustPicSize, hPicMargin, vPicMargin, captionLines, hCount, vCount); } void SOPlot_AddPage ( SOPlot_PSStream *ps, /* Picture stream. */ const char *pageName /* Name of the new page (may be NULL). */ ) { pswr_new_page(ps, pageName); } double SOPlot_DefaultFigSize ( bool eps, char *paperSize, int nRows, int nCols, int captionLines ) { if (nRows <= 0) { nRows = 1; } if (nCols <= 0) { nCols = 1; } if (eps) { return 150.0 / (nRows < nCols ? nRows : nCols); } else { double hsize, vsize; pswr_get_paper_dimensions(paperSize, &hsize, &vsize); hsize = (hsize/72.0 - 2.0)*25.0/nCols; vsize = ((vsize - 10.0*nRows*captionLines)/72.0 - 2.0)*25.0/nRows; if (hsize < 0.0) { hsize = 10.0; } if (vsize < 0.0) { vsize = 10.0; } return (hsize < vsize ? hsize : vsize); } } double SOPlot_Brightness(Color *C) { return 0.299 * C->c[0] + 0.587 * C->c[1] + 0.114 * C->c[2]; } Color SOPlot_ColorScale(double s, Color *A, Color *B) { double yA = SOPlot_Brightness(A) + 0.02; double yB = SOPlot_Brightness(B) + 0.02; double u, v; if (fabs(yA - yB) < 0.00001) { /* Same brightness, use linear interpolation: */ v = s; } else { /* Interpolate brigtnesses in log scale: */ double y = yA*exp(s*log(yB/yA)); v = (y - yA)/(yB - yA); if (v < 0.0) { v = 0.0; } if (v > 1.0) { v = 1.0; } } u = 1.0 - v; return (Color) {{ u*A->c[0] + v*B->c[0], u*A->c[1] + v*B->c[1], u*A->c[2] + v*B->c[2] }}; } Color SOPlot_InterpolateColor ( double f, /* Function value */ double fPlotMin, /* Minimum function value. */ Color *CMin, /* Color to use for {fPlotMin}. */ bool clipMin, /* TRUE maps values below {fPlotMin} to invisible. */ double fPlotMax, /* Maximum function VALUE. */ Color *CMax, /* Color to use for {fPlotMax}. */ bool clipMax /* TRUE maps values above {fPlotMax} to invisible. */ ) { if (f < fPlotMin) { if (clipMin) { return Invisible; } else { return *CMin; } } else if (f > fPlotMax) { if (clipMax) { return Invisible; } else { return *CMax; } } else { double s = (f - fPlotMin)/(fPlotMax - fPlotMin); double t = 1.0 - s; return (Color) {{ s*CMax->c[0] + t*CMin->c[0], s*CMax->c[1] + t*CMin->c[1], s*CMax->c[2] + t*CMin->c[2] }}; } } Color SOPlot_ClipColor(Color *C) { double m = 0; int i; for (i = 0; i < 3; i++) { double ci = fabs(C->c[i]); if (ci > m) { m = ci; } } if (m <= 1.0) { return *C; } else { Color A = (Color){{C->c[0]/m, C->c[1]/m, C->c[2]/m}}; double yC = SOPlot_Brightness(C); double yA = yC/m; double s = (yC < 1.0 ? yC : 1.0) - yA; return (Color) {{ A.c[0] + s*(1.0 - A.c[0]), A.c[1] + s*(1.0 - A.c[1]), A.c[2] + s*(1.0 - A.c[2]) }}; } }