home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d386 / xlispstat.lha / XLispStat / src3.lzh / UNIX / myplot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-30  |  3.4 KB  |  143 lines

  1. /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney                  */
  2. /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz    */
  3. /* You may give out copies of this software; for conditions see the    */
  4. /* file COPYING included with this distribution.                       */
  5.  
  6. #include <math.h>
  7. #include "gnuplot.h"
  8. #include "xlisp.h"
  9.  
  10. # define numberp(x) (fixp(x) || floatp(x))
  11. # define makefloat(x) ((fixp(x)) ? (double) getfixnum(x) : getflonum(x))
  12. # define sequencep(x) (listp(x) || simplevectorp(x))
  13.  
  14. extern LVAL coerce_to_list();
  15.  
  16. static double NiceValue(x)
  17.     double x;
  18. {
  19.   long ilx;
  20.   double lx, v1, v2, v3, v4;
  21.     
  22.   if (x <= 0) return (0.0);
  23.   else {
  24.     lx = log(x) / log(10.0);
  25.     ilx = floor(lx);
  26.     v1 = pow(10.0, (float) ilx);
  27.     v2 = pow(10.0, (float) ilx) * 2.0;
  28.     v3 = pow(10.0, (float) ilx) * 5.0;
  29.     v4 = pow(10.0, (float) ilx + 1);
  30.  
  31.     if ((fabs(x - v1) < fabs(x - v2))
  32.     && (fabs(x - v1) < fabs(x - v3))
  33.     && (fabs(x - v1) < fabs(x - v4)))
  34.       return(v1);
  35.     else if ((fabs(x - v2) < fabs(x - v3))
  36.          && (fabs(x - v2) < fabs(x - v4)))
  37.       return(v2);
  38.     else if (fabs(x - v3) < fabs(x - v4))
  39.       return(v3);
  40.     else
  41.       return(v4);
  42.     }
  43. }
  44.  
  45. static SetNiceRange(xmin, xmax, ticks)
  46.      double *xmin, *xmax;
  47.      int *ticks;
  48. {
  49.   double delta;
  50.     
  51.   if ((*xmax <= *xmin) || (*ticks < 2)) return;
  52.     
  53.   delta = NiceValue((*xmax - *xmin) / (*ticks - 1));
  54.     
  55.   *xmin = floor(*xmin / delta) * delta;
  56.   *xmax = ceil(*xmax / delta) * delta;
  57.     
  58.   *ticks = 1 + (.01 + (*xmax - *xmin) / delta);/* add .01 for rounding */
  59. }
  60.  
  61. static set_range(low, high)
  62.      double *low, *high;
  63. {
  64.   int ticks = 4;
  65.  
  66.   if (*low == *high) {
  67.     (*low)--;
  68.     (*high)++;
  69.   }
  70.   else SetNiceRange(low, high, &ticks);
  71. }
  72.  
  73. static LVAL gnupointlineplot(plot_style)
  74.      enum PLOT_STYLE plot_style;
  75. {
  76.   LVAL next, nextx, nexty;
  77.   int n, i;
  78.   struct curve_points *this_plot, real_plot;
  79.   struct coordinate *pts;
  80.   double xmin, xmax, ymin, ymax, dx, dy;
  81.   LVAL x, y;
  82.   
  83.   xlstkcheck(2);
  84.   xlsave(x);
  85.   xlsave(y);
  86.  
  87.   x = xlgetarg();
  88.   if (consp(x) && sequencep(car(x))) {
  89.     y = car(cdr(x));
  90.     x = car(x);
  91.   }
  92.   else y = xlgetarg();
  93.   x = coerce_to_list(x);
  94.   y = coerce_to_list(y);
  95.  
  96.   n = llength(x);
  97.   if (llength(y) != n) xlfail("lengths do not match");
  98.   for (next = x; next != NULL; next = cdr(next))
  99.     if (! numberp(car(next))) xlerror("not a number", car(next));
  100.   for (next = y; next != NULL; next = cdr(next))
  101.     if (! numberp(car(next))) xlerror("not a number", car(next));
  102.  
  103.   pts = (struct coordinate *) calloc(sizeof(struct coordinate), n);
  104.  
  105.   this_plot = &real_plot;
  106.   this_plot->points = (struct coordinate *) pts;
  107.   this_plot->next_cp = 0;
  108.   this_plot->plot_type = DATA;
  109.   this_plot->plot_style = plot_style;
  110.   this_plot->title = "";
  111.   this_plot->p_count = n;
  112.  
  113.   xmin = HUGE;
  114.   xmax = -HUGE;
  115.   ymin = HUGE;
  116.   ymax = -HUGE;
  117.   for(i = 0, nextx = x, nexty = y; i < n;
  118.       i++, nextx = cdr(nextx), nexty = cdr(nexty)) {
  119.     dx = makefloat(car(nextx));
  120.     dy = makefloat(car(nexty));
  121.     this_plot->points[i].undefined = FALSE;
  122.     this_plot->points[i].x = dx;
  123.     this_plot->points[i].y = dy;
  124.     if (dx > xmax) xmax = dx;
  125.     if (dx < xmin) xmin = dx;
  126.     if (dy > ymax) ymax = dy;
  127.     if (dy < ymin) ymin = dy;
  128.   }
  129.  
  130.   set_range(&xmin, &xmax);
  131.   set_range(&ymin, &ymax);
  132.  
  133.   do_plot(this_plot, 1, xmin, xmax, ymin, ymax);
  134.  
  135.   free(pts);
  136.   xlpopn(2);
  137.  
  138.   return(NIL);
  139. }
  140.  
  141. LVAL gnupointplot() { return(gnupointlineplot(POINTS)); }
  142. LVAL gnulineplot() { return(gnupointlineplot(LINES)); }
  143.