--- /dev/null
+/*****************************************************************************
+** 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 <math.h>
+#include <algorithm>
+#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<int>(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<int>(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<int>(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<int>(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);
+}