home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / imdisp / source / plot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-04  |  17.2 KB  |  513 lines

  1. /***  IMDISP module PLOT.C
  2.  
  3.         PLOT contains the routines for plotting spectra and lines from
  4.     images.  It was originally written by Ed Esfandari to support the
  5.     International Halley Watch CD-ROM.  This module was extensively
  6.     modified and moderately tested by:
  7.  
  8.           A. Warnock
  9.           ST Systems Corp
  10.           Mail Code 681
  11.           NASA/Goddard Space Flight Center
  12.           Greenbelt, MD.
  13.  
  14.      All bugs contained herein are mine and mine alone.
  15.  
  16. ***/
  17.  
  18. /* * * * INCLUDE files * * * */
  19.  
  20. #include <conio.h>
  21. #include <graph.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include "imdef.h"
  26. #include "dispio.h"
  27. #include "disputil.h"
  28. #include "imageio.h"
  29. #include "labutil.h"
  30.  
  31. /* * * * External functions * * * */
  32.  
  33. /* * * * Function declarations * * * */
  34.  
  35. void Plot32(long *buf, long miny, long maxy, int len, char * symbol,
  36.            int color, int zoom);
  37. void Plotpair(long xbuf[], long buf[], long minx, long maxx, long miny,
  38.              long maxy, int len, char * symbol, int color, int zoom);
  39.  
  40. /* * * * Global Variables * * * */
  41.  
  42. void Plot32( long * buf, long miny, long maxy, int len, char * symbol,
  43.             int color, int zoom)
  44.  
  45. /***  Plot32 plots a single array of 32-bit y-values against a running
  46.       index on the x-axis.  The code provides for zooming in on a region
  47.       of interest, plotting with dots or lines and plotting in different
  48.       colors.
  49.  
  50.       Original version - 3/31/89 AEE
  51.       Modified version - 8/90 AW3
  52.  
  53.    Parameter    Type    In/out   Description
  54.       buf     long ptr   in      The buffer containing the y data
  55.       miny      long     in      The minimum y value to plot
  56.       maxy      long     in      The maximum y value to plot
  57.       len       int      in      The number of points in the y array
  58.      symbol     char     in      Plotting symbol flag: 'D' for dots
  59.                                     anything else for line
  60.      color      int      in      Plotting color (index into current pal)
  61.      zoom       int      in      Zoom flag:  0 if no zooming this time
  62.                                    1 if zooming desired (i.e., ask)
  63.  
  64. ***/
  65. {
  66.     int            i, j, yaxisrev;
  67.     int            adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
  68.     int            line1, samp1, line2, samp2;
  69.     int            start = 0, tmplen = len, tmpdn = numDN;
  70.     int            wave_flag, string_len;
  71.     int            top, bottom, left, right, height, width;
  72.     int            num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
  73.     int            tic, tic_height=5, numbins;
  74.     long           minx, maxx;
  75.     long           tmpminy = miny, tmpmaxy = maxy;
  76.     long           tmpminx = minx, tmpmaxx = maxx;
  77.     char           bufmin[15], bufmax[15], xbufmin[15], xbufmax[15];
  78.     char           ch='N';
  79.     float          scale_ydata_to_screen;
  80.     float          pixperbin, yrange;
  81.  
  82. /*  Find the actual starting and ending X values from the header, if
  83.     present */
  84.  
  85.     minx = (long) xstart;
  86.     maxx = minx + (long)(len * xinterval);
  87.  
  88. /*  Set display sizes in units of screen pixels */
  89.     top       = dispnl / 10;
  90.     bottom    = dispnl - top;
  91.     left      = dispns / 10;
  92.     right     = dispns - (dispns / 32);
  93.     height    = bottom - top;
  94.     width     = right - left;
  95.     right     = left + width;            /* reset right edge */
  96.     numbins   = width;
  97.     pixperbin = (float)len / numbins;
  98.     tic = (numbins / 16) * pixperbin;
  99.     tic_height = dispnl / 100;
  100.  
  101.  
  102. /*  Top of the plotting loop - do this until no more zooming */
  103.     while (zoom >= 0)
  104.     {
  105.        yrange = (float) (maxy - miny) ;
  106.        if (yrange != 0)
  107.           scale_ydata_to_screen = ( (float) height) / yrange;
  108.  
  109. /* Draw box around the plot */
  110.        FrameBox( top, left, bottom, right, numDN-1, TRUE);
  111.  
  112. /* Draw in the tic marks */
  113.        for (i = 0;  i <= num_Xtics;  i++)
  114.        {
  115.            j = left + width*i/num_Xtics;
  116.            DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
  117.        }
  118.  
  119.        for (i = 0;  i <= num_Ytics;  i++)
  120.        {
  121.            j = bottom - height*i/num_Ytics;
  122.            DrawLine (j, left, j, left-tic_height, numDN-1);
  123.        }
  124.  
  125. /* Label the axes and draw in plot and axis titles */
  126.        sprintf(bufmin, "%10.2G", (float)miny);
  127.        LengthText(bufmin, 6, &string_len);
  128.        string_len = string_len + tic_height + 2;
  129.        DrawText(bufmin, bottom+5, left-string_len, 6, 0, numDN-1);
  130.  
  131.        sprintf(bufmax, "%10.2G", (float)maxy);
  132.        LengthText(bufmax, 6, &string_len);
  133.        string_len = string_len + tic_height + 2;
  134.        DrawText(bufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
  135.  
  136.        sprintf(xbufmin, "%ld", minx);
  137.        LengthText(xbufmin, 10, &string_len);
  138.        DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
  139.  
  140.        sprintf(xbufmax, "%ld", maxx);
  141.        LengthText(xbufmax, 10, &string_len);
  142.        DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
  143.  
  144.        LengthText(xunit, 15, &string_len);
  145.        DrawText(xunit, bottom+30, left+(width-string_len)/2, 15, 0, numDN-1);
  146.        DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
  147.  
  148. /*  Set the starting points for the plot */
  149.        lowedge = bottom;
  150.        leftedge= left;
  151.        prevy   = max( buf[0], miny);
  152.        prevy   = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
  153.        prevx   = left;
  154.  
  155. /*  Loop over the points in the y array */
  156.        for (i=start; i<start+len; i++)
  157.        {
  158.           if(buf[i] <= maxy && buf[i] >= miny)
  159.           {
  160.  
  161.           /* adjval to fall in plot range */
  162.               adjval = (int) (((float) (buf[i]-miny)) * scale_ydata_to_screen);
  163.  
  164.           /* make y-axis increase upward */
  165.               ycord = lowedge - adjval;
  166.  
  167.           /* scales the length of X-axis (samples) correctly */
  168.               nextx = leftedge + (int) ((i-start) * ((float)width/len));
  169.  
  170.           /* plot the next point */
  171.  
  172.               if (strlen(symbol) == 0)
  173.               {
  174.               /* use lines; connect the points */
  175.                   DrawLine(prevy, prevx, ycord, nextx, color);
  176.                   prevy = ycord;
  177.                   prevx = nextx;
  178.               }
  179.               else
  180.                   DrawText(symbol, ycord, nextx, 8, 0, color);
  181.           }
  182.        }
  183.  
  184.        if (zoom == 2) /* We've already zoomed once */
  185.        {
  186.           minx  = tmpminx;
  187.           miny  = tmpminy;
  188.           maxx  = tmpmaxx;
  189.           maxy  = tmpmaxy;
  190.           len   = tmplen;
  191.           start = 0;
  192.           numDN = tmpdn;
  193.           DrawText("Would you like to zoom again (y/n)?  ",10,1,8,0,numDN-1);
  194.           ch = getch();
  195.        }
  196.  
  197.        if (zoom == 1) /* We haven't zoomed, and we want to */
  198.        {
  199.           ch   = 'Y';
  200.           zoom = 2;
  201.        }
  202.  
  203.        /*  Either way, find the new endpoints and redraw the plot */
  204.        if (ch == 'y' || ch == 'Y')
  205.        {
  206.           /* clears the prompt line */
  207.           DrawText("Would you like to zoom again (y/n)?  ", 10, 1, 8, 0, 0);
  208.  
  209.           /* select the endpoints of the zoom */
  210.           DrawText("   Arrow keys move + around. +,- (in/de)crements cursor steps.",
  211.                        10, 1, 8, 0,numDN-1);
  212.  
  213.           LengthText("Hit Return to Select End Points", 8, &string_len);
  214.           DrawText("Hit Return to Select End Points",
  215.                        dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
  216.  
  217.           PlaceCursor(bottom+6, right/2, numDN-1);
  218.           MoveCursor(&line1, &samp1);
  219.           DrawText("*", line1+4, samp1-4, 8, 0, numDN-1);
  220.  
  221.           MoveCursor(&line2, &samp2);
  222.           DrawText("*", line2+4, samp2-4, 8, 0, numDN-1);
  223.  
  224.           /* clean up the screen */
  225.           RemoveCursor();
  226.           ClearDisplay(0);
  227.  
  228.           /* watch for reversed endpoints */
  229.           if (samp1 > samp2)
  230.           {
  231.               i     = samp2;
  232.               samp2 = samp1;
  233.               samp1 = i;
  234.           }
  235.  
  236.           /* watch for values off the plot */
  237.           if (samp1 < left)
  238.               samp1 = left;
  239.           if (samp2 > right)
  240.               samp2 = right;
  241.           if (samp2 < left)
  242.               samp2 = left;   /* both end points < minx of plot */
  243.           if (samp1 > right)
  244.               samp1 = right;  /* both end points > maxx of plot */
  245.  
  246.           /* set the new starting points */
  247.           start = (samp1-left) *  ((float) len /(float)width);
  248.           len   = (samp2-samp1) *  ((float) len /(float)width);
  249.  
  250.           if(len > 0)
  251.           {
  252.           /* X-axis range selected is > 0 */
  253.               minx = start+1;
  254.               maxx = len+start;
  255.               miny = 0x7fffffff;
  256.               maxy = 0x80000000;
  257.  
  258.           /* new min and max for the plot */
  259.               for (i= start; i<start+len; i++)
  260.               {
  261.                   if (buf[i] < miny)
  262.                       miny= buf[i];
  263.                   if (buf[i] > maxy)
  264.                       maxy= buf[i];
  265.               }
  266.               prevy= lowedge - ((int) (((float) (buf[start] - miny)) * scale_ydata_to_screen));
  267.               prevx= leftedge;
  268.           }
  269.           else
  270.           {
  271.           /* selected X range is zero */
  272.               zoom = -1;
  273.           }
  274.  
  275.           minx= (long) (xstart + (float) (minx) * xinterval - xinterval);
  276.           maxx= (long) (xstart + (float) (maxx) * xinterval);
  277.  
  278.  
  279.        }
  280.        else
  281.            zoom = -1;
  282.     }
  283.  
  284. } /* end plot32 */
  285.  
  286.  
  287.  
  288. void Plotpair(long * xbuf, long * ybuf, long minx, long maxx, long miny,
  289.              long maxy, int len, char * symbol, int color, int zoom)
  290.  
  291. /***  PlotPair plots two arrays of 32-bit values against each other.  The
  292.       code provides for zooming in on a region of interest, plotting
  293.       with dots or lines and plotting in different colors.
  294.  
  295.       Original version - 3/31/89 AEE
  296.       Modified version - 8/90 AW3
  297.  
  298.    Parameter    Type    In/out   Description
  299.       xbuf    long ptr   in      The buffer containing the x data
  300.       ybuf    long ptr   in      The buffer containing the y data
  301.       miny      long     in      The minimum y value to plot
  302.       maxy      long     in      The maximum y value to plot
  303.       len       int      in      The number of points in the y array
  304.      symbol     char     in      Plotting symbol flag: 'D' for dots
  305.                                     anything else for line
  306.       color     int      in      Plotting color (index into current pal)
  307.       zoom      int      in      Zoom flag:  0 if no zooming this time
  308.                                    1 if zooming desired (i.e., ask)
  309.  
  310. ***/
  311. {
  312.     int            i, j, yaxisrev;
  313.     int            adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
  314.     int            line1, samp1, line2, samp2;
  315.     int            start = 0, x_right, x_width;
  316.     int            tmplen = len, tmpdn = numDN;
  317.     long           tmpminy = miny, tmpmaxy = maxy;
  318.     long           tmpminx = minx, tmpmaxx = maxx;
  319.     char           ybufmin[15], ybufmax[15], xbufmin[15], xbufmax[15];
  320.     float          scale_ydata_to_screen, scale_xdata_to_screen;
  321.     float          yrange, xrange;
  322.     char           ch='N';
  323.     int            wave_flag, string_len;
  324.     int            top, bottom, left, right, height, width;
  325.     int            num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
  326.     int            tic, tic_height=5, numbins;
  327.     float          pixperbin;
  328.  
  329.     top        = dispnl / 10;
  330.     bottom     = dispnl - top;
  331.     left       = dispns / 10;
  332.     right      = dispns - (dispns / 32);
  333.     height     = bottom - top;
  334.     width      = right - left;
  335.     right      = left + width;            /* reset right edge */
  336.     numbins    = width;
  337.     pixperbin  = (float)len / numbins;
  338.     tic        = (numbins / 16) * pixperbin;
  339.     tic_height = dispnl / 100;
  340.  
  341.  
  342.     while (zoom >= 0)
  343.     {
  344.        yrange = (float) (maxy - miny) ;
  345.        if (yrange != 0)
  346.           scale_ydata_to_screen = ( (float) height) / yrange;
  347.  
  348.        xrange= (float) (maxx - minx);
  349.        if (xrange != 0)
  350.           scale_xdata_to_screen= ((float) width)/xrange;
  351.  
  352.        /* draw box outline */
  353.        FrameBox( top, left, bottom, right, numDN-1, TRUE);
  354.  
  355.        /* Put in the tic marks */
  356.        for (i = 0;  i <= num_Xtics;  i++)
  357.        {
  358.            j = left + width*i/num_Xtics;
  359.            DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
  360.        }
  361.  
  362.        for (i = 0;  i <= num_Ytics;  i++)
  363.        {
  364.            j = bottom - height*i/num_Ytics;
  365.            DrawLine (j, left, j, left-tic_height, numDN-1);
  366.        }
  367.  
  368.        /* write coordinates */
  369.  
  370.        sprintf(ybufmin, "%10.2G", (float)miny);
  371.        LengthText(ybufmin, 6, &string_len);
  372.        string_len = string_len + tic_height + 2;
  373.        DrawText(ybufmin, bottom+5, left-string_len, 6, 0, numDN-1);
  374.  
  375.        sprintf(ybufmax, "%10.2G", (float)maxy);
  376.        LengthText(ybufmax, 6, &string_len);
  377.        string_len = string_len + tic_height + 2;
  378.        DrawText(ybufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
  379.  
  380.        sprintf(xbufmin, "%ld", minx);
  381.        LengthText(xbufmin, 10, &string_len);
  382.        DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
  383.  
  384.        sprintf(xbufmax, "%ld", maxx);
  385.        LengthText(xbufmax, 10, &string_len);
  386.        DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
  387.  
  388.        DrawText(xunit, bottom+30, left+(width/2)-75, 15, 0, numDN-1);
  389.        DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
  390.  
  391.        lowedge = bottom;
  392.        leftedge= left;
  393.  
  394.        prevy   = max( ybuf[start], miny);
  395.        prevy   = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
  396.        prevx   = left;
  397.  
  398.        for (i=start; i<start+len; i++)
  399.        {
  400.           if(ybuf[i] <= maxy && ybuf[i] >= miny)
  401.           {
  402.  
  403.           /* adjval to fall in plot range */
  404.               adjval= (int) (((float) (ybuf[i]-miny)) * scale_ydata_to_screen);
  405.  
  406.           /* make y-axis increase upward */
  407.               ycord= lowedge - adjval;
  408.  
  409.           /* scales the length of X-axis(samples) correctly */
  410.               nextx= leftedge + (int) ( ((float) (xbuf[i] - minx)) * scale_xdata_to_screen);
  411.  
  412.               if (strlen(symbol) == 0)
  413.               {
  414.               /* use lines; connect the points */
  415.                   DrawLine(prevy, prevx, ycord, nextx, color);
  416.                   prevy = ycord;
  417.                   prevx = nextx;
  418.               }
  419.               else
  420.                   DrawText(symbol, ycord, nextx, 8, 0, color);
  421.           }
  422.        }
  423.  
  424.        if (zoom == 2) /* We've already zoomed once */
  425.        {
  426.           minx  = tmpminx;
  427.           miny  = tmpminy;
  428.           maxx  = tmpmaxx;
  429.           maxy  = tmpmaxy;
  430.           len   = tmplen;
  431.           start = 0;
  432.           numDN = tmpdn;
  433.           DrawText("Would you like to zoom again (y/n)?  ",10,1,8,0,numDN-1);
  434.           ch = getch();
  435.        }
  436.  
  437.        if (zoom == 1) /* We haven't zoomed, and we want to */
  438.        {
  439.           ch= 'Y';
  440.           zoom = 2;
  441.        }
  442.  
  443.        if (ch == 'y' || ch == 'Y')
  444.        {
  445.           /*clears this line*/
  446.           DrawText("Would you like to zoom again (y/n)?  ",10,1,8,0,0);
  447.  
  448.           DrawText("   Arrow keys move + around. +,- (in/de)crements cursor steps.",
  449.                        10, 1, 8, 0,numDN-1);
  450.           LengthText("Hit Return to Select End Points", 8, &string_len);
  451.           DrawText("Hit Return to Select End Points",
  452.                        dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
  453.  
  454.           PlaceCursor(bottom+6,right/2,numDN-1);
  455.           MoveCursor(&line1,&samp1);
  456.           DrawText("*",line1+4,samp1-4,8,0,numDN-1);
  457.           MoveCursor(&line2,&samp2);
  458.           DrawText("*",line2+4,samp2-4,8,0,numDN-1);
  459.           RemoveCursor();
  460.           ClearDisplay(0);
  461.  
  462.           if (samp1 > samp2)
  463.           {
  464.               i= samp2;
  465.               samp2= samp1;
  466.               samp1= i;
  467.           }
  468.           if (samp1 < left)
  469.               samp1 = left;
  470.           if (samp2 > right)
  471.               samp2 = right;
  472.           if (samp2 < left)
  473.               samp2 = left;   /* both end points < minx of plot */
  474.           if (samp1 > right)
  475.               samp1 = right;  /* both end points > maxx of plot */
  476.  
  477.           start = (samp1-left) *  ((float) len /(float)width);
  478.           len   = (samp2-samp1) *  ((float) len /(float)width);
  479.  
  480.           if(len > 0)
  481.           {
  482.           /* X-axis range selected is > 0 */
  483.  
  484.               minx = 0x7fffffff;
  485.               maxx = 0x80000000;
  486.               miny = 0x7fffffff;
  487.               maxy = 0x80000000;
  488.               for (i= start; i<start+len; i++)
  489.               {
  490.                   if (xbuf[i] < minx)
  491.                       minx = xbuf[i];
  492.                   if (xbuf[i] > maxx)
  493.                       maxx = xbuf[i];
  494.                   if (ybuf[i] < miny)
  495.                       miny = ybuf[i];
  496.                   if (ybuf[i] > maxy)
  497.                       maxy = ybuf[i];
  498.               }
  499.               prevy = lowedge  - ((int) (((float) (ybuf[start] - miny)) * scale_ydata_to_screen));
  500.               prevx = leftedge - ((int) (((float) (xbuf[start] - minx)) * scale_xdata_to_screen));
  501.           }
  502.           else
  503.           {
  504.           /* selected X range is zero */
  505.               zoom = -1;
  506.           }
  507.        }
  508.        else
  509.            zoom = -1;
  510.     }
  511.  
  512. } /* end Plotpair */
  513.