X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=libctgraphics%2Fezsupport.cpp;fp=libctgraphics%2Fezsupport.cpp;h=51f97423d7f92a0489eb489f4a73c1311e3a0e06;hb=bf7295a63667dcca309389ee6dd5328a3a25f22b;hp=0000000000000000000000000000000000000000;hpb=1eb1fcf291b39a016864d78a4060e83cd9046437;p=ctsim.git diff --git a/libctgraphics/ezsupport.cpp b/libctgraphics/ezsupport.cpp new file mode 100644 index 0000000..51f9742 --- /dev/null +++ b/libctgraphics/ezsupport.cpp @@ -0,0 +1,216 @@ +/***************************************************************************** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg +** +** $Id: ezsupport.cpp,v 1.1 2000/06/19 18:05:03 kevin Exp $ +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License (version 2) as +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + +#include +#include +#include "kstddef.h" +#include "ezplot.h" + + +/* NAME + * axis_scale calculates graph axis scaling + * + * SYNOPSIS: + * retval = axis_scale (min, max, nint, minp, maxp, nintp, + * rec_total, rec_frac) + * + * INPUT: + * double min Smallest value to plot + * double max Largest value to plot + * int nint Number of intervals desired + * + * OUTPUT: + * int retval FALSE if illegal parameters, else TRUE + * double *minp Minimum graph value + * double *maxp Maximum graph value + * int *nintp Number of intervals for graph + * int *rec_total Recommended field width for printing out the number + * int *rec_frac Recommended number of digits for print fraction + */ + +int +axis_scale (double min, double max, int nint, double *minp, double *maxp, int *nintp) +{ + double eps, a, scale, mina, maxa, d, j, e, f, v, wdt, g, h; + + if (min >= max || nint < 1) { + sys_error (ERR_WARNING, "Invalid params: min=%lf, min=%lf, num intervals=%d [axis_scale]", min, max, nint); + return (FALSE); + } + + eps = 0.025; + a = fabs(min); + if (fabs(min) < fabs(max)) + a = fabs(max); + scale = pow (10.0, floor(log10(a))); + loop: + mina = min / scale; + maxa = max / scale; + d = (maxa - mina) / nint; + j = d * eps; + e = floor (log10(d)); + f = d / pow (10.0, e); + v = 10.0; + if (f < sqrt(2.0)) + v = 1.0; + else if (f < sqrt (10.0)) + v = 2.0; + else if (f < sqrt (50.0)) + v = 5.0; + wdt = v * pow (10.0, e); + g = floor (mina / wdt); + if (fabs(g + 1 - mina / wdt) < j) + g = g + 1; + *minp = wdt * g; + h = floor (maxa / wdt) + 1.0; + if (fabs(maxa / wdt + 1 - h) < j) + h = h - 1; + *maxp = wdt * h; + *nintp = static_cast(h - g); + if (fabs(*maxp) >= 10.0 || fabs(*minp) >= 10.0) { + scale = scale * 10.0; + goto loop; + } + + *minp *= scale; + *maxp *= scale; + + return (TRUE); +} + + +/* NAME + * make_numfmt Make a numeric format string + * + * SYNOPSIS + * make_numfmt (fmtstr, fldwid, nfrac, min, max, nint) + * char *fmtstr Returned format string for printf() + * int *fldwid Returned field width + * int *nfrac If < 0, then calculate best number of + * fraction places & return that value + * If >= 0, then use that number of places + * double min Minimum value + * double max Maximum value + * int nint Number of intervals between min & max + * + * DESCRIPTION + * This routine is written as an INTERNAL routine for EZPLOT + */ + +static inline double +trunc (double x) +{ + double integer; + + double frac = modf (x, &integer); + + return (integer); +} + +void +make_numfmt (char *fmtstr, int *fldwid, int *nfrac, double minval, double maxval, int nint) +{ + int wid, frac, expon; + + double delta = (maxval - minval) / nint; + double absmin = fabs(minval); + double absmax = fabs(maxval); + double logt = log10( max(absmin, absmax) ); + + if (fabs(logt) >= 6) { /* use exponential format */ + if (fabs(logt) > 99) + expon = 5; /* E+102 */ + else + expon = 4; /* E+00 */ + + if (*nfrac < 0) { /* calculate frac */ + delta /= pow (10., floor(logt)); /* scale delta */ + frac = static_cast(fabs(trunc(log10(delta)))) + 1; + if (frac < 1) + frac = 1; /* to be safe, add decimal pt */ + } else /* use users' frac */ + frac = *nfrac; + + wid = 2 + frac + expon; + if (minval < 0. || maxval < 0.) + ++wid; + snprintf (fmtstr, sizeof(fmtstr), "%%%d.%dle", wid, frac); + } else { /* use fixed format */ + wid = static_cast(trunc(logt)) + 1; + if (wid < 1) + wid = 1; + if (minval < 0. || maxval < 0.) + ++wid; + + if (*nfrac < 0) { /* calculate frac */ + if (delta >= 0.999999) + frac = 1; /* add a decimal pt to be safe */ + else + frac = static_cast(fabs(trunc(log10(delta)))) + 1; + } else /* use users' frac */ + frac = *nfrac; + + wid += 1 + frac; + snprintf (fmtstr, sizeof(fmtstr), "%%%d.%dlf", wid, frac); + } + + *fldwid = wid; + *nfrac = frac; +} + +#ifdef TEST +int +main (void) +{ + double min, max; + double x, xinc; + int i, nint, wid, frac; + char fmtstr[10]; + + printf ("Enter min, max, & number of intervals -- "); + scanf ("%lf %lf %d", &min, &max, &nint); + + frac = -1; /* let makefmt determine fraction */ + + makefmt (fmtstr, &wid, &frac, min, max, nint); + + printf ("Format string = %s\n", fmtstr); + + xinc = (max - min) / nint; + + x = min; + for (i = 0; i <= nint; i++) { + printf (fmtstr, x); + x += xinc; + printf ("\n"); + } +} +#endif + +void +ezplot_1d (double *y, int n) +{ + double x [n]; + + for (int i = 0; i < n; i++) + x[i] = i; + + ezplot (x, y, n); +}