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

  1. /*
  2.  *
  3.  *    G N U P L O T  --  graphics.c
  4.  *
  5.  *  Copyright (C) 1986, 1987  Thomas Williams, Colin Kelley
  6.  *
  7.  *  You may use this code as you wish if credit is given and this message
  8.  *  is retained.
  9.  *
  10.  *  Please e-mail any useful additions to vu-vlsi!plot so they may be
  11.  *  included in later releases.
  12.  *
  13.  *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
  14.  */
  15.  
  16. #include <math.h>
  17. #include "gnuplot.h"
  18.  
  19. char *strcpy(),*strncpy(),*strcat();
  20.  
  21. BOOLEAN log_x = 0, log_y = 0;  /* set to false */
  22. extern int term;
  23.  
  24. extern BOOLEAN term_init;
  25.  
  26. extern struct termentry term_tbl[];
  27.  
  28.  
  29. #define max(a,b) ((a > b) ? a : b)
  30.  
  31. #define map_x(x) (int)((x-xmin)*xscale) /* maps floating point x to screen */ 
  32. #define map_y(y) (int)((y-ymin)*yscale)    /* same for y */
  33.  
  34.  
  35. double raise(x,y)
  36. double x;
  37. int y;
  38. {
  39. int i;
  40. double val;
  41.  
  42.     val = 1.0;
  43.     for (i=0; i < abs(y); i++)
  44.         val *= x;
  45.     if (y < 0 ) return (1.0/val);
  46.     return(val);
  47. }
  48.  
  49.  
  50. double make_tics(tmin,tmax,logscale)
  51. double tmin,tmax;
  52. BOOLEAN logscale;
  53. {
  54. double xr,xnorm,tics,tic,l10;
  55.  
  56.     xr = fabs(tmin-tmax);
  57.     
  58.     l10 = log10(xr);
  59.     if (logscale) {
  60.         tic = raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
  61.         if (tic < 1.0)
  62.             tic = 1.0;
  63.     } else {
  64.         xnorm = pow(10.0,l10-(double)((l10 >= 0.0 ) ? (int)l10 : ((int)l10-1)));
  65.         if (xnorm <= 2)
  66.             tics = 0.2;
  67.         else if (xnorm <= 5)
  68.             tics = 0.5;
  69.         else tics = 1.0;    
  70.         tic = tics * raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
  71.     }
  72.     return(tic);
  73. }
  74.  
  75. char *idx(a,b)
  76. char *a,b;
  77. {
  78.     do {
  79.         if (*a == b)
  80.             return(a);
  81.     } while (*a++);
  82.     return(0);
  83. }
  84.  
  85.  
  86. num2str(num,str)
  87. double num;
  88. char str[];
  89. {
  90. static char temp[80];
  91. double d;
  92. char *a,*b;
  93.  
  94.      if ((d = fabs(num)) > 9999.0 || d < 0.001 && d != 0.0) 
  95.         (void) sprintf(temp,"%-.3e",num);    
  96.     else
  97.         (void) sprintf(temp,"%-.3g",num);
  98.     if (b = idx(temp,'e')) {
  99.         a = b;
  100.         while ( *(--a) == '0') /* trailing zeros */
  101.             ;    
  102.         if ( *a == '.') 
  103.             a--;
  104.         (void) strncpy(str,temp,(int)(a-temp)+1);
  105.         str[(int)(a-temp)+1] = '\0';
  106.         a = b+1;    /* point to 1 after 'e' */
  107.         (void) strcat(str,"e");
  108.         if ( *a == '-') 
  109.             (void) strcat(str,"-");
  110.         a++;                         /* advance a past '+' or '-' */
  111.         while ( *a == '0' && *(a+1) != '\0') /* leading zeroes */
  112.             a++;
  113.         (void) strcat(str,a); /* copy rest of string */
  114.     }
  115.     else
  116.         (void) strcpy(str,temp);    
  117. }
  118.  
  119.  
  120. do_plot(plots, pcount, xmin, xmax, ymin, ymax)
  121. struct curve_points *plots;
  122. int pcount;            /* count of plots in linked list */
  123. double xmin, xmax;
  124. double ymin, ymax;
  125. {
  126. int i, x;
  127. struct termentry *t = &term_tbl[term];
  128. BOOLEAN prev_undef;
  129. int curve, xaxis_y, yaxis_x, dpcount;
  130. struct curve_points *this_plot;
  131. enum PLOT_TYPE p_type;
  132. double xscale, yscale;
  133. double ytic, xtic, least, most, ticplace;
  134. int mms,mts;
  135.  
  136. static char xns[20],xms[20],yns[20],yms[20],xts[20],yts[20];
  137. static char label[80];
  138.  
  139.     if (ymin == HUGE || ymax == -HUGE)
  140.         xlfail("all points undefined!");
  141.  
  142.     ytic = make_tics(ymin,ymax,log_y);
  143.     xtic = make_tics(xmin,xmax,log_x);
  144.     dpcount = 0;
  145.     
  146.     if (ymin < ymax ) {
  147.         ymin = ytic * floor(ymin/ytic);    
  148.         ymax = ytic * ceil(ymax/ytic);
  149.     }
  150.     else {
  151.         ymin = ytic * ceil(ymin/ytic);
  152.         ymax = ytic * floor(ymax/ytic);
  153.     }
  154.  
  155.     if (xmin == xmax)
  156.         xlfail("xmin should not equal xmax!");
  157.     if (ymin == ymax)
  158.         xlfail("ymin should not equal ymax!");
  159.     
  160.     yscale = (t->ymax - 2)/(ymax - ymin);
  161.     xscale = (t->xmax - 2)/(xmax - xmin);
  162.     
  163.     (*t->init)();
  164.     if( (*t->graphics)() > 0) return(1);
  165.     (*t->linetype)(-2); /* border linetype */
  166.  
  167.     /* draw plot border */
  168.     (*t->move)(0,0);    
  169.     (*t->vector)(t->xmax-1,0);    
  170.     (*t->vector)(t->xmax-1,t->ymax-1);    
  171.     (*t->vector)(0,t->ymax-1);    
  172.     (*t->vector)(0,0);
  173.  
  174.     least = (ymin < ymax) ? ymin : ymax;
  175.     most = (ymin < ymax) ? ymax : ymin;
  176.  
  177.     for (ticplace = ytic + least; ticplace < most ; ticplace += ytic) { 
  178.         (*t->move)(0,map_y(ticplace));
  179.         (*t->vector)(t->h_tic,map_y(ticplace));
  180.         (*t->move)(t->xmax-1,map_y(ticplace));
  181.                    (*t->vector)(t->xmax-1-t->h_tic,map_y(ticplace));
  182.     }
  183.  
  184.     if (xmin < xmax ) {
  185.         least = xtic * floor(xmin/xtic);    
  186.         most = xtic * ceil(xmax/xtic);
  187.     }
  188.     else {
  189.         least = xtic * ceil(xmin/xtic);
  190.         most = xtic * floor(xmax/xtic);
  191.     }
  192.  
  193.     for (ticplace = xtic + least; ticplace < most ; ticplace += xtic) { 
  194.         (*t->move)(map_x(ticplace),0);
  195.         (*t->vector)(map_x(ticplace),t->v_tic);
  196.         (*t->move)(map_x(ticplace),t->ymax-1);
  197.                    (*t->vector)(map_x(ticplace),t->ymax-1-t->v_tic);
  198.     }
  199.  
  200.     if (log_x) {
  201.         num2str(pow(10.0,xmin),xns);
  202.         num2str(pow(10.0,xmax),xms);
  203.         num2str(pow(10.0,xtic),xts);
  204.     }
  205.     else {
  206.         num2str(xmin,xns);
  207.         num2str(xmax,xms);
  208.         num2str(xtic,xts);
  209.     }
  210.     if (log_y) {
  211.         num2str(pow(10.0,ymin),yns);
  212.         num2str(pow(10.0,ymax),yms);
  213.         num2str(pow(10.0,ytic),yts);
  214.     } else {
  215.         num2str(ymin,yns);
  216.         num2str(ymax,yms);
  217.         num2str(ytic,yts);
  218.     }
  219.     mms = max(strlen(xms),strlen(yms));
  220.     mts = max(strlen(xts),strlen(yts));
  221.  
  222.     (void) sprintf(label,"%s < y < %-*s  inc = %-*s",yns,mms,yms,mts,yts);
  223.     (*t->lrput_text)(0, label);
  224.     (void) sprintf(label,"%s < x < %-*s  inc = %-*s",xns,mms,xms,mts,xts);
  225.     (*t->lrput_text)(1, label);
  226.  
  227.  
  228. /* DRAW AXES */
  229.     (*t->linetype)(-1);    /* axis line type */
  230.     xaxis_y = map_y(0.0);
  231.     yaxis_x = map_x(0.0); 
  232.  
  233.     if (xaxis_y < 0)
  234.         xaxis_y = 0;                /* save for impulse plotting */
  235.     else if (xaxis_y >= t->ymax)
  236.         xaxis_y = t->ymax - 1;
  237.     else if (!log_y) {
  238.         (*t->move)(0,xaxis_y);
  239.         (*t->vector)((t->xmax-1),xaxis_y);
  240.     }
  241.  
  242.     if (!log_x && yaxis_x >= 0 && yaxis_x < t->xmax) {
  243.         (*t->move)(yaxis_x,0);
  244.         (*t->vector)(yaxis_x,(t->ymax-1));
  245.     }
  246.  
  247. /* DRAW CURVES */
  248.     this_plot = plots;
  249.     for (curve = 0; curve < pcount; this_plot = this_plot->next_cp, curve++) {
  250.         (*t->linetype)(curve);
  251.         (*t->ulput_text)(curve, this_plot->title);
  252.         (*t->linetype)(curve);
  253.  
  254.         p_type = this_plot->plot_type;
  255.         switch(this_plot->plot_style) {
  256.             case IMPULSES:
  257.                 for (i = 0; i < this_plot->p_count; i++) {
  258.                     if (!this_plot->points[i].undefined) {
  259.                             x = map_x(this_plot->points[i].x);
  260.                         (*t->move)(x,xaxis_y);
  261.                         (*t->vector)(x,map_y(this_plot->points[i].y));
  262.                     }
  263.                 }
  264.                 break;
  265.             case LINES:
  266.                 prev_undef = TRUE;
  267.                 for (i = 0; i < this_plot->p_count; i++) {
  268.                     if (!this_plot->points[i].undefined) {
  269.                             x = map_x(this_plot->points[i].x);
  270.                         if (prev_undef)
  271.                             (*t->move)(x,
  272.                             map_y(this_plot->points[i].y));
  273.                         (*t->vector)(x,
  274.                             map_y(this_plot->points[i].y));
  275.                     }
  276.                     prev_undef = this_plot->points[i].undefined;
  277.                 }
  278.                 break;
  279.             case POINTS:
  280.                 for (i = 0; i < this_plot->p_count; i++) {
  281.                     if (!this_plot->points[i].undefined) {
  282.                             x = map_x(this_plot->points[i].x);
  283.                         (*t->point)(x,map_y(this_plot->points[i].y),dpcount);
  284.                     }
  285.                 }
  286.                 dpcount++;
  287.                 break;
  288.  
  289.         }
  290.     }
  291.     (*t->text)();
  292.     return(0);
  293. }
  294.