home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / vopl / glvopl.lha / glvopl / src / axis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-08  |  10.1 KB  |  544 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #ifdef SGI_GL
  4. #include "gl.h"
  5. #else
  6. #include "vogl.h"
  7. #endif
  8. #include "vopl.h"
  9.  
  10. void    log_axis(), lin_axis();
  11.  
  12. extern    double log10();
  13. extern    float hstrlength();
  14.  
  15. /*
  16.  * formatlabel
  17.  *
  18.  *    chose a "nice" format for an axis label, awful at the moment.
  19.  */
  20. formatlabel(alabel, form)
  21.     float    alabel;
  22.     char    *form;
  23. {
  24.     int    i, j;
  25.  
  26.     if (ABS(alabel) < 1.0e-9)
  27.         alabel = 0.0;
  28.  
  29.     if ((ABS(alabel) > 999999.0) || (ABS(alabel) < 0.000001))
  30.         sprintf(form, "%.4g", alabel);
  31.     else 
  32.         sprintf(form, "%f", alabel);
  33.  
  34.     /*
  35.      * if there is no 'e' in there or there is a dot then
  36.      * eat trailing zeros.....
  37.      */
  38.     if ((strchr(form, 'e') == (char *)NULL &&
  39.         strchr(form, 'E') == (char *)NULL) &&
  40.         strchr(form, '.') != (char *)NULL) {
  41.         i = strlen(form) - 1;
  42.         while (i >= 0 && form[i] == '0') 
  43.             i--;
  44.  
  45.         if (form[i] == '.')
  46.             i--;
  47.  
  48.         form[++i] = '\0';
  49.         if (form[0] == '\0') {
  50.             form[0] = '0';
  51.             form[1] = '\0';
  52.         }
  53.     }
  54. }
  55.  
  56. /*
  57.  * axistitle
  58.  *
  59.  *    Draws an x, y or z axis, with or without annotation, tickmarks etc
  60.  */
  61. void
  62. axistitle(title, ax)
  63.     char    *title, ax;
  64. {
  65.     char    **s, err_buf[EBUF_SIZE];
  66.  
  67.     /*
  68.      * save the goddam title somewhere....
  69.      */
  70.     switch (ax) {
  71.     case 'x':
  72.     case 'X':
  73.         s = &plotdev.axes[XIND].title;
  74.         break;
  75.     case 'y':
  76.     case 'Y':
  77.         s = &plotdev.axes[YIND].title;
  78.         break;
  79.     case 'z':
  80.     case 'Z':
  81.         s = &plotdev.axes[ZIND].title;
  82.         break;
  83.     default:
  84.         sprintf(err_buf, "axistitle: unknown axis '%c'", ax);
  85.         vopl_error(err_buf);
  86.     }
  87.  
  88.     *s = savestr(*s, title);
  89. }
  90.  
  91. /*
  92.  * drawaxis
  93.  *
  94.  *    Draws an x, y or z axis, with or without annotation, tickmarks etc
  95.  */
  96. void
  97. drawaxis(axis)
  98.     char    axis;
  99. {
  100.     int    ind;
  101.     char    err_buf[EBUF_SIZE];
  102.  
  103.     switch (axis) {
  104.     case 'x':
  105.     case 'X':
  106.         ind = XIND;
  107.         break;
  108.     case 'y':
  109.     case 'Y':
  110.         ind = YIND;
  111.         break;
  112.     case 'z':
  113.     case 'Z':
  114.         ind = ZIND;
  115.         break;
  116.     default:
  117.         sprintf(err_buf, "drawaxis: unknown axis '%c'", axis);
  118.         vopl_error(err_buf);
  119.     }
  120.  
  121.     if (!plotdev.axes[ind].scaleset) { 
  122.         plotdev.axes[ind].min = -1.0;
  123.         plotdev.axes[ind].max = 1.0;
  124.     }
  125.  
  126.     if (plotdev.axes[ind].scaling == LOGARITHMIC)
  127.         log_axis(ind);
  128.     else
  129.         lin_axis(ind);
  130. }
  131.  
  132. /*
  133.  * drawaxes2
  134.  *
  135.  *    Draws the x and y axes, with or without annotation, tickmarks etc
  136.  */
  137. void
  138. drawaxes2()
  139. {
  140.     int    axis;
  141.  
  142.     for (axis = 0; axis < AXES; axis++)
  143.         if (!plotdev.axes[axis].scaleset) { 
  144.             plotdev.axes[axis].min = -1.0;
  145.             plotdev.axes[axis].max = 1.0;
  146.         }
  147.  
  148.     if (plotdev.axes[XIND].scaling == LOGARITHMIC) 
  149.         log_axis(XIND);
  150.     else
  151.         lin_axis(XIND);
  152.  
  153.     if (plotdev.axes[YIND].scaling == LOGARITHMIC) 
  154.         log_axis(YIND);
  155.     else 
  156.         lin_axis(YIND);
  157. }
  158.  
  159. /*
  160.  * drawaxes
  161.  *
  162.  *    Draws an x, y, and z axes, with or without annotation, tickmarks etc
  163.  */
  164. void
  165. drawaxes()
  166. {
  167.     int    axis;
  168.  
  169.     for (axis = 0; axis < AXES; axis++) {
  170.         if (!plotdev.axes[axis].scaleset) { 
  171.             plotdev.axes[axis].min = -1.0;
  172.             plotdev.axes[axis].max = 1.0;
  173.         }
  174.  
  175.         if (plotdev.axes[axis].scaling == LOGARITHMIC) 
  176.             log_axis(axis);
  177.         else
  178.             lin_axis(axis);
  179.     }
  180. }
  181.  
  182. /*
  183.  * lin_axis
  184.  *
  185.  *    draw a linear axis
  186.  */
  187. void
  188. lin_axis(axis)
  189.     int        axis;
  190. {
  191.     float         x, y, tinc, sx, sy, ssx, ssy;
  192.     float        alabel;
  193.     int         i, j, count;
  194.         char        form[50], err_buf[EBUF_SIZE];
  195.     axisdata    ax;
  196.     Screencoord     left, right, bottom, top;
  197.  
  198.     
  199.     pushattributes();
  200.     pushmatrix();
  201.     pushviewport();
  202.  
  203.     getviewport(&left, &right, &bottom, &top);
  204.  
  205.     /*
  206.      * FUDGE is so that the last axes anotation doesn't get clipped
  207.      */
  208.     /*
  209.     viewport(left,
  210.         right  - (short)(FUDGE * (right - left)),
  211.         bottom,
  212.         top - (short)(FUDGE * (top - bottom)));
  213.     */
  214.  
  215.     ortho2(-1.0, 1.0 + FUDGE, -1.0, 1.0);
  216.  
  217.     switch (axis) {
  218.     case XIND:
  219.         htextsize(TEXTWIDTH, TEXTHEIGHT);
  220.         move2(XMIN, YMIN);
  221.         draw2(XMAX, YMIN);
  222.  
  223.         htextang(0.0);
  224.         hcentertext(1);
  225.  
  226.         ax = plotdev.axes[XIND];
  227.  
  228.         x = ax.max - ax.min;
  229.         count = x / ax.div + 0.5;
  230.         tinc = (XMAX - XMIN) / x * ax.div;
  231.  
  232.         for (i = 0; i <= count; i++) {
  233.             sx = i * tinc + XMIN;
  234.  
  235.             if (i < count && ax.minorticks)
  236.                 for (j = 1; j <= ax.minorticks; j++) {
  237.                     ssx = sx + tinc * j / ax.minorticks;
  238.  
  239.                     move2(ssx, YMIN);
  240.                     if (!(ax.minorticks & 1) && j == ax.minorticks/2)
  241.                         draw2(ssx, YMIN - 0.75 * LINELEN);
  242.                     else
  243.                         draw2(ssx, YMIN - 0.5 * LINELEN);
  244.                     if (ax.minorticks && plotdev.grid && !(j % plotdev.grid))
  245.                         draw2(ssx, YMAX);
  246.                 }
  247.  
  248.             if (plotdev.grid) 
  249.                 if (!(i % plotdev.grid)) {
  250.                     move2(sx, YMAX);
  251.                     draw2(sx, YMIN);
  252.                 }
  253.         
  254.  
  255.             if (ax.ntspacing && !(i % ax.ntspacing)) {
  256.                 move2(sx, YMIN);
  257.                 draw2(sx, YMIN - LINELEN);
  258.             }
  259.         
  260.             if (ax.annotate) {
  261.                 alabel = ax.min + ax.div * i;
  262.                 if (ax.format)
  263.                     sprintf(form, ax.format, alabel);
  264.                 else
  265.                     formatlabel(alabel, form);
  266.  
  267.                 move2(sx, YMIN - LINELEN - 1.1 * TEXTHEIGHT / 2);
  268.                 hcharstr(form);
  269.             }
  270.         }
  271.  
  272.         if (ax.title != (char *)NULL) {
  273.             htextang(0.0);
  274.             hcentertext(1);
  275.             x = 0.5 * (XMAX - XMIN) + XMIN;
  276.             y = (YMIN - 6.0 * TEXTWIDTH);
  277.             htextsize(1.3 * TEXTWIDTH, 1.3 * TEXTHEIGHT);
  278.             move2(x, y);
  279.             hcharstr(ax.title);
  280.         }
  281.         break;
  282.     case YIND:
  283.         htextsize(TEXTWIDTH, TEXTHEIGHT);
  284.         hcentertext(0);
  285.         htextang(0.0);
  286.  
  287.         move2(XMIN, YMIN);
  288.         draw2(XMIN, YMAX);
  289.  
  290.         ax = plotdev.axes[YIND];
  291.  
  292.         y = ax.max - ax.min;
  293.         tinc = (YMAX - YMIN) / y * ax.div;
  294.         count = y / ax.div + 0.5;
  295.  
  296.         for (i = 0; i <=  count; i++) {
  297.             sy = i * tinc + YMIN;
  298.  
  299.             if (i < count && ax.minorticks)
  300.                 for (j = 1; j <= ax.minorticks; j++) {
  301.                     ssy = sy + tinc * j / ax.minorticks;
  302.  
  303.                     move2(XMIN, ssy);
  304.                     if (!(ax.minorticks & 1) && j == ax.minorticks/2)
  305.                         draw2(XMIN - 0.75 * LINELEN, ssy);
  306.                     else
  307.                         draw2(XMIN - 0.5 * LINELEN, ssy);
  308.                     if (ax.minorticks && plotdev.grid && !(j % plotdev.grid))
  309.                         draw2(XMAX, ssy);
  310.                 }
  311.  
  312.  
  313.             if (plotdev.grid) 
  314.                 if (!(i % plotdev.grid)) {
  315.                     move2(XMIN, sy);
  316.                     draw2(XMAX, sy);
  317.                 }
  318.  
  319.             if (ax.ntspacing && !(i % ax.ntspacing)) {
  320.                 move2(XMIN, sy);
  321.                 draw2(XMIN - LINELEN, sy);
  322.             }
  323.  
  324.             if (ax.annotate) {
  325.                 alabel = ax.min + ax.div * i;
  326.                 if (ax.format)
  327.                     sprintf(form, ax.format, alabel);
  328.                 else
  329.                     formatlabel(alabel, form);
  330.  
  331.                 move2(XMIN - hstrlength(form) - 2 * LINELEN, sy - TEXTHEIGHT / 2);
  332.                 hcharstr(form);
  333.             }
  334.         }
  335.  
  336.         if (ax.title != (char *)NULL) {
  337.             x = XMIN - 7.0 * TEXTWIDTH;
  338.             y = 0.5 * (YMAX - YMIN) + YMIN;
  339.             move2(x, y);
  340.             htextang(90.0);
  341.             hcentertext(1);
  342.             htextsize(1.3 * TEXTWIDTH, 1.3 * TEXTHEIGHT);
  343.             hcharstr(ax.title);
  344.             htextang(0.0);
  345.         }
  346.         break;
  347.     case ZIND:
  348.         vopl_error("Z-Axis not yet implemented");
  349.         break;
  350.     default:
  351.         sprintf(err_buf, "axis: unknown axis: %d", axis);
  352.         vopl_error(err_buf);
  353.     }
  354.  
  355.     popviewport();
  356.     popmatrix();
  357.     popattributes();
  358. }
  359.  
  360.  
  361. /*
  362.  * log_axis
  363.  *
  364.  *    Does a logarithmic axis with exponential style annotation
  365.  */
  366. void
  367. log_axis(axis)
  368.     int    axis;
  369. {
  370.  
  371.     float         x, y, tinc, sx, sy, ssx, ssy;
  372.     float        alabel, ldiv;
  373.     int         i, j;
  374.         char        form[21], err_buf[EBUF_SIZE];
  375.     axisdata    ax;
  376.     Screencoord     left, right, bottom, top;
  377.     
  378.     pushattributes();
  379.     pushmatrix();
  380.     pushviewport();
  381.  
  382.     getviewport(&left, &right, &bottom, &top);
  383.  
  384.     viewport(left,
  385.         right  - (short)(0.05 * (right - left)),
  386.         bottom,
  387.         top - (short)(0.05 * (top - bottom)));
  388.  
  389.     ortho2(-1.0, 1.0, -1.0, 1.0);
  390.  
  391.  
  392.     switch (axis) {
  393.     case XIND:
  394.         htextsize(TEXTWIDTH, TEXTHEIGHT);
  395.         move2(XMIN, YMIN);
  396.         draw2(XMAX, YMIN);
  397.  
  398.         htextang(0.0);
  399.         hcentertext(0);
  400.  
  401.         ax = plotdev.axes[XIND];
  402.  
  403.         /*
  404.          * Get the minimum exponent value.
  405.          */
  406.         alabel = (float)log10((double)ax.min);
  407.  
  408.         tinc = (XMAX - XMIN) / (ax.nticks);
  409.  
  410.         for (i = 0; i <= ax.nticks; i++) {
  411.  
  412.             sx = i * tinc + XMIN;
  413.             /* Minor ticks */
  414.             if (i < ax.nticks && ax.minorticks) 
  415.                 for (j = 1; j < 10; j++) {
  416.                     ssx = sx + tinc * log10((double)j);
  417.  
  418.                     move2(ssx, YMIN);
  419.                     if (j == 5)
  420.                         draw2(ssx, YMIN - 0.75 * LINELEN);
  421.                     else
  422.                         draw2(ssx, YMIN - 0.5 * LINELEN);
  423.                     if (ax.minorticks && plotdev.grid && !(j % plotdev.grid))
  424.                         draw2(ssx, YMAX);
  425.                 }
  426.  
  427.             if (plotdev.grid)
  428.                 if (!(i % plotdev.grid)) {
  429.                     move2(sx, YMAX);
  430.                     draw2(sx, YMIN);
  431.                 }
  432.  
  433.             if (ax.ntspacing && !(i % ax.ntspacing)) {
  434.                 move2(sx, YMIN);
  435.                 draw2(sx, YMIN - LINELEN);
  436.             }
  437.             
  438.             if (ax.annotate) {
  439.                 formatlabel(alabel, form);
  440.  
  441.                 htextsize(0.7 * TEXTWIDTH, 0.7 * TEXTHEIGHT);
  442.                 move2(sx + 0.5 * TEXTWIDTH, YMIN - LINELEN - 0.8 * TEXTHEIGHT);
  443.                 hcharstr(form);
  444.                 rmv2(-hstrlength(form), 0.0);
  445.                 htextsize(TEXTWIDTH, TEXTHEIGHT);
  446.                 rmv2(-1.3 * TEXTWIDTH, -0.9 * TEXTHEIGHT);
  447.                 hcharstr("10");
  448.             }
  449.             alabel += ax.div;
  450.         }
  451.  
  452.         if (ax.title != (char *)NULL) {
  453.             hcentertext(1);
  454.             x = 0.5 * (XMAX - XMIN) + XMIN;
  455.             y = (YMIN - 6.0 * TEXTWIDTH);
  456.             move2(x, y);
  457.             htextsize(1.3 * TEXTWIDTH, 1.3 * TEXTHEIGHT);
  458.             hcharstr(ax.title);
  459.         }
  460.         break;
  461.     case YIND:
  462.         htextsize(TEXTWIDTH, TEXTHEIGHT);
  463.         hcentertext(0);
  464.         htextang(0.0);
  465.  
  466.         move2(XMIN, YMIN);
  467.         draw2(XMIN, YMAX);
  468.  
  469.         ax = plotdev.axes[YIND];
  470.  
  471.         /*
  472.          * Get the minimum exponent value.
  473.          */
  474.         alabel = (float)log10((double)ax.min);
  475.  
  476.         hcentertext(0);
  477.  
  478.         tinc = (YMAX - YMIN) / (ax.nticks);
  479.  
  480.         for (i = 0; i <= ax.nticks; i++) {
  481.  
  482.             sy = i * tinc + YMIN;
  483.  
  484.             if (i < ax.nticks && ax.minorticks)
  485.                 for (j = 1; j < 10; j++) {
  486.                     ssy = sy + tinc * log10((double)j);
  487.  
  488.                     move2(XMIN, ssy);
  489.                     if (j == 5)
  490.                         draw2(XMIN - 0.75 * LINELEN, ssy);
  491.                     else
  492.                         draw2(XMIN - 0.5 * LINELEN, ssy);
  493.                     if (ax.minorticks && plotdev.grid && !(j % plotdev.grid))
  494.                         draw2(XMAX, ssy);
  495.                 }
  496.  
  497.             if (plotdev.grid) 
  498.                 if (!(i % plotdev.grid)) {
  499.                     move2(XMIN, sy);
  500.                     draw2(XMAX, sy);
  501.                 }
  502.  
  503.             if (ax.ntspacing && !(i % ax.ntspacing)) {
  504.                 move2(XMIN, sy);
  505.                 draw2(XMIN - LINELEN, sy);
  506.             }
  507.  
  508.             if (ax.annotate) {
  509.                 formatlabel(alabel, form);
  510.                 htextsize(0.7 * TEXTWIDTH, 0.7 * TEXTHEIGHT);
  511.                 move2(XMIN - hstrlength(form) - 2 * LINELEN, sy + 0.5 * TEXTHEIGHT);
  512.                 hcharstr(form);
  513.                 rmv2(-hstrlength(form), -TEXTHEIGHT);
  514.                 htextsize(TEXTWIDTH, TEXTHEIGHT);
  515.                 rmv2(-TEXTWIDTH, 0.0);
  516.                 hcharstr("10");
  517.             }
  518.             alabel += ax.div;
  519.         }
  520.  
  521.         if (ax.title != (char *)NULL) {
  522.             x = XMIN - 7.0 * TEXTWIDTH;
  523.             y = 0.5 * (YMAX - YMIN) + YMIN;
  524.             move2(x, y);
  525.             htextang(90.0);
  526.             hcentertext(1);
  527.             htextsize(1.3 * TEXTWIDTH, 1.3 * TEXTHEIGHT);
  528.             hcharstr(ax.title);
  529.             htextang(0.0);
  530.         }
  531.         break;
  532.     case ZIND:
  533.         vopl_error("Z-Axis not yet implemented");
  534.         break;
  535.     default:
  536.         sprintf(err_buf, "axis: unknown axis: %d", ax);
  537.         vopl_error(err_buf);
  538.     }
  539.  
  540.     popviewport();
  541.     popmatrix();
  542.     popattributes();
  543. }
  544.