home *** CD-ROM | disk | FTP | other *** search
- /*** IMDISP module PLOT.C
-
- PLOT contains the routines for plotting spectra and lines from
- images. It was originally written by Ed Esfandari to support the
- International Halley Watch CD-ROM. This module was extensively
- modified and moderately tested by:
-
- A. Warnock
- ST Systems Corp
- Mail Code 681
- NASA/Goddard Space Flight Center
- Greenbelt, MD.
-
- All bugs contained herein are mine and mine alone.
-
- ***/
-
- /* * * * INCLUDE files * * * */
-
- #include <conio.h>
- #include <graph.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "imdef.h"
- #include "dispio.h"
- #include "disputil.h"
- #include "imageio.h"
- #include "labutil.h"
-
- /* * * * External functions * * * */
-
- /* * * * Function declarations * * * */
-
- void Plot32(long *buf, long miny, long maxy, int len, char * symbol,
- int color, int zoom);
- void Plotpair(long xbuf[], long buf[], long minx, long maxx, long miny,
- long maxy, int len, char * symbol, int color, int zoom);
-
- /* * * * Global Variables * * * */
-
- void Plot32( long * buf, long miny, long maxy, int len, char * symbol,
- int color, int zoom)
-
- /*** Plot32 plots a single array of 32-bit y-values against a running
- index on the x-axis. The code provides for zooming in on a region
- of interest, plotting with dots or lines and plotting in different
- colors.
-
- Original version - 3/31/89 AEE
- Modified version - 8/90 AW3
-
- Parameter Type In/out Description
- buf long ptr in The buffer containing the y data
- miny long in The minimum y value to plot
- maxy long in The maximum y value to plot
- len int in The number of points in the y array
- symbol char in Plotting symbol flag: 'D' for dots
- anything else for line
- color int in Plotting color (index into current pal)
- zoom int in Zoom flag: 0 if no zooming this time
- 1 if zooming desired (i.e., ask)
-
- ***/
- {
- int i, j, yaxisrev;
- int adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
- int line1, samp1, line2, samp2;
- int start = 0, tmplen = len, tmpdn = numDN;
- int wave_flag, string_len;
- int top, bottom, left, right, height, width;
- int num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
- int tic, tic_height=5, numbins;
- long minx, maxx;
- long tmpminy = miny, tmpmaxy = maxy;
- long tmpminx = minx, tmpmaxx = maxx;
- char bufmin[15], bufmax[15], xbufmin[15], xbufmax[15];
- char ch='N';
- float scale_ydata_to_screen;
- float pixperbin, yrange;
-
- /* Find the actual starting and ending X values from the header, if
- present */
-
- minx = (long) xstart;
- maxx = minx + (long)(len * xinterval);
-
- /* Set display sizes in units of screen pixels */
- top = dispnl / 10;
- bottom = dispnl - top;
- left = dispns / 10;
- right = dispns - (dispns / 32);
- height = bottom - top;
- width = right - left;
- right = left + width; /* reset right edge */
- numbins = width;
- pixperbin = (float)len / numbins;
- tic = (numbins / 16) * pixperbin;
- tic_height = dispnl / 100;
-
-
- /* Top of the plotting loop - do this until no more zooming */
- while (zoom >= 0)
- {
- yrange = (float) (maxy - miny) ;
- if (yrange != 0)
- scale_ydata_to_screen = ( (float) height) / yrange;
-
- /* Draw box around the plot */
- FrameBox( top, left, bottom, right, numDN-1, TRUE);
-
- /* Draw in the tic marks */
- for (i = 0; i <= num_Xtics; i++)
- {
- j = left + width*i/num_Xtics;
- DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
- }
-
- for (i = 0; i <= num_Ytics; i++)
- {
- j = bottom - height*i/num_Ytics;
- DrawLine (j, left, j, left-tic_height, numDN-1);
- }
-
- /* Label the axes and draw in plot and axis titles */
- sprintf(bufmin, "%10.2G", (float)miny);
- LengthText(bufmin, 6, &string_len);
- string_len = string_len + tic_height + 2;
- DrawText(bufmin, bottom+5, left-string_len, 6, 0, numDN-1);
-
- sprintf(bufmax, "%10.2G", (float)maxy);
- LengthText(bufmax, 6, &string_len);
- string_len = string_len + tic_height + 2;
- DrawText(bufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
-
- sprintf(xbufmin, "%ld", minx);
- LengthText(xbufmin, 10, &string_len);
- DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
-
- sprintf(xbufmax, "%ld", maxx);
- LengthText(xbufmax, 10, &string_len);
- DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
-
- LengthText(xunit, 15, &string_len);
- DrawText(xunit, bottom+30, left+(width-string_len)/2, 15, 0, numDN-1);
- DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
-
- /* Set the starting points for the plot */
- lowedge = bottom;
- leftedge= left;
- prevy = max( buf[0], miny);
- prevy = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
- prevx = left;
-
- /* Loop over the points in the y array */
- for (i=start; i<start+len; i++)
- {
- if(buf[i] <= maxy && buf[i] >= miny)
- {
-
- /* adjval to fall in plot range */
- adjval = (int) (((float) (buf[i]-miny)) * scale_ydata_to_screen);
-
- /* make y-axis increase upward */
- ycord = lowedge - adjval;
-
- /* scales the length of X-axis (samples) correctly */
- nextx = leftedge + (int) ((i-start) * ((float)width/len));
-
- /* plot the next point */
-
- if (strlen(symbol) == 0)
- {
- /* use lines; connect the points */
- DrawLine(prevy, prevx, ycord, nextx, color);
- prevy = ycord;
- prevx = nextx;
- }
- else
- DrawText(symbol, ycord, nextx, 8, 0, color);
- }
- }
-
- if (zoom == 2) /* We've already zoomed once */
- {
- minx = tmpminx;
- miny = tmpminy;
- maxx = tmpmaxx;
- maxy = tmpmaxy;
- len = tmplen;
- start = 0;
- numDN = tmpdn;
- DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,numDN-1);
- ch = getch();
- }
-
- if (zoom == 1) /* We haven't zoomed, and we want to */
- {
- ch = 'Y';
- zoom = 2;
- }
-
- /* Either way, find the new endpoints and redraw the plot */
- if (ch == 'y' || ch == 'Y')
- {
- /* clears the prompt line */
- DrawText("Would you like to zoom again (y/n)? ", 10, 1, 8, 0, 0);
-
- /* select the endpoints of the zoom */
- DrawText(" Arrow keys move + around. +,- (in/de)crements cursor steps.",
- 10, 1, 8, 0,numDN-1);
-
- LengthText("Hit Return to Select End Points", 8, &string_len);
- DrawText("Hit Return to Select End Points",
- dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
-
- PlaceCursor(bottom+6, right/2, numDN-1);
- MoveCursor(&line1, &samp1);
- DrawText("*", line1+4, samp1-4, 8, 0, numDN-1);
-
- MoveCursor(&line2, &samp2);
- DrawText("*", line2+4, samp2-4, 8, 0, numDN-1);
-
- /* clean up the screen */
- RemoveCursor();
- ClearDisplay(0);
-
- /* watch for reversed endpoints */
- if (samp1 > samp2)
- {
- i = samp2;
- samp2 = samp1;
- samp1 = i;
- }
-
- /* watch for values off the plot */
- if (samp1 < left)
- samp1 = left;
- if (samp2 > right)
- samp2 = right;
- if (samp2 < left)
- samp2 = left; /* both end points < minx of plot */
- if (samp1 > right)
- samp1 = right; /* both end points > maxx of plot */
-
- /* set the new starting points */
- start = (samp1-left) * ((float) len /(float)width);
- len = (samp2-samp1) * ((float) len /(float)width);
-
- if(len > 0)
- {
- /* X-axis range selected is > 0 */
- minx = start+1;
- maxx = len+start;
- miny = 0x7fffffff;
- maxy = 0x80000000;
-
- /* new min and max for the plot */
- for (i= start; i<start+len; i++)
- {
- if (buf[i] < miny)
- miny= buf[i];
- if (buf[i] > maxy)
- maxy= buf[i];
- }
- prevy= lowedge - ((int) (((float) (buf[start] - miny)) * scale_ydata_to_screen));
- prevx= leftedge;
- }
- else
- {
- /* selected X range is zero */
- zoom = -1;
- }
-
- minx= (long) (xstart + (float) (minx) * xinterval - xinterval);
- maxx= (long) (xstart + (float) (maxx) * xinterval);
-
-
- }
- else
- zoom = -1;
- }
-
- } /* end plot32 */
-
-
-
- void Plotpair(long * xbuf, long * ybuf, long minx, long maxx, long miny,
- long maxy, int len, char * symbol, int color, int zoom)
-
- /*** PlotPair plots two arrays of 32-bit values against each other. The
- code provides for zooming in on a region of interest, plotting
- with dots or lines and plotting in different colors.
-
- Original version - 3/31/89 AEE
- Modified version - 8/90 AW3
-
- Parameter Type In/out Description
- xbuf long ptr in The buffer containing the x data
- ybuf long ptr in The buffer containing the y data
- miny long in The minimum y value to plot
- maxy long in The maximum y value to plot
- len int in The number of points in the y array
- symbol char in Plotting symbol flag: 'D' for dots
- anything else for line
- color int in Plotting color (index into current pal)
- zoom int in Zoom flag: 0 if no zooming this time
- 1 if zooming desired (i.e., ask)
-
- ***/
- {
- int i, j, yaxisrev;
- int adjval, leftedge, nextx, lowedge, ycord, prevy, prevx;
- int line1, samp1, line2, samp2;
- int start = 0, x_right, x_width;
- int tmplen = len, tmpdn = numDN;
- long tmpminy = miny, tmpmaxy = maxy;
- long tmpminx = minx, tmpmaxx = maxx;
- char ybufmin[15], ybufmax[15], xbufmin[15], xbufmax[15];
- float scale_ydata_to_screen, scale_xdata_to_screen;
- float yrange, xrange;
- char ch='N';
- int wave_flag, string_len;
- int top, bottom, left, right, height, width;
- int num_Xtics=16, num_Ytics=10, num_Xlabels=8, num_Ylabels=5;
- int tic, tic_height=5, numbins;
- float pixperbin;
-
- top = dispnl / 10;
- bottom = dispnl - top;
- left = dispns / 10;
- right = dispns - (dispns / 32);
- height = bottom - top;
- width = right - left;
- right = left + width; /* reset right edge */
- numbins = width;
- pixperbin = (float)len / numbins;
- tic = (numbins / 16) * pixperbin;
- tic_height = dispnl / 100;
-
-
- while (zoom >= 0)
- {
- yrange = (float) (maxy - miny) ;
- if (yrange != 0)
- scale_ydata_to_screen = ( (float) height) / yrange;
-
- xrange= (float) (maxx - minx);
- if (xrange != 0)
- scale_xdata_to_screen= ((float) width)/xrange;
-
- /* draw box outline */
- FrameBox( top, left, bottom, right, numDN-1, TRUE);
-
- /* Put in the tic marks */
- for (i = 0; i <= num_Xtics; i++)
- {
- j = left + width*i/num_Xtics;
- DrawLine (bottom, j, bottom-tic_height, j, numDN-1);
- }
-
- for (i = 0; i <= num_Ytics; i++)
- {
- j = bottom - height*i/num_Ytics;
- DrawLine (j, left, j, left-tic_height, numDN-1);
- }
-
- /* write coordinates */
-
- sprintf(ybufmin, "%10.2G", (float)miny);
- LengthText(ybufmin, 6, &string_len);
- string_len = string_len + tic_height + 2;
- DrawText(ybufmin, bottom+5, left-string_len, 6, 0, numDN-1);
-
- sprintf(ybufmax, "%10.2G", (float)maxy);
- LengthText(ybufmax, 6, &string_len);
- string_len = string_len + tic_height + 2;
- DrawText(ybufmax, bottom-height+5, left-string_len, 6, 0, numDN-1);
-
- sprintf(xbufmin, "%ld", minx);
- LengthText(xbufmin, 10, &string_len);
- DrawText(xbufmin, bottom+20, left-string_len/2, 10, 0, numDN-1);
-
- sprintf(xbufmax, "%ld", maxx);
- LengthText(xbufmax, 10, &string_len);
- DrawText(xbufmax, bottom+20, right-string_len/2, 10, 0, numDN-1);
-
- DrawText(xunit, bottom+30, left+(width/2)-75, 15, 0, numDN-1);
- DrawText("Counts", bottom-(height/2)+50, left-20, 15, 90, numDN-1);
-
- lowedge = bottom;
- leftedge= left;
-
- prevy = max( ybuf[start], miny);
- prevy = lowedge - ( (int) (((float) (prevy - miny)) * scale_ydata_to_screen));
- prevx = left;
-
- for (i=start; i<start+len; i++)
- {
- if(ybuf[i] <= maxy && ybuf[i] >= miny)
- {
-
- /* adjval to fall in plot range */
- adjval= (int) (((float) (ybuf[i]-miny)) * scale_ydata_to_screen);
-
- /* make y-axis increase upward */
- ycord= lowedge - adjval;
-
- /* scales the length of X-axis(samples) correctly */
- nextx= leftedge + (int) ( ((float) (xbuf[i] - minx)) * scale_xdata_to_screen);
-
- if (strlen(symbol) == 0)
- {
- /* use lines; connect the points */
- DrawLine(prevy, prevx, ycord, nextx, color);
- prevy = ycord;
- prevx = nextx;
- }
- else
- DrawText(symbol, ycord, nextx, 8, 0, color);
- }
- }
-
- if (zoom == 2) /* We've already zoomed once */
- {
- minx = tmpminx;
- miny = tmpminy;
- maxx = tmpmaxx;
- maxy = tmpmaxy;
- len = tmplen;
- start = 0;
- numDN = tmpdn;
- DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,numDN-1);
- ch = getch();
- }
-
- if (zoom == 1) /* We haven't zoomed, and we want to */
- {
- ch= 'Y';
- zoom = 2;
- }
-
- if (ch == 'y' || ch == 'Y')
- {
- /*clears this line*/
- DrawText("Would you like to zoom again (y/n)? ",10,1,8,0,0);
-
- DrawText(" Arrow keys move + around. +,- (in/de)crements cursor steps.",
- 10, 1, 8, 0,numDN-1);
- LengthText("Hit Return to Select End Points", 8, &string_len);
- DrawText("Hit Return to Select End Points",
- dispnl-10, left+(width-string_len)/2, 8, 0, numDN-1);
-
- PlaceCursor(bottom+6,right/2,numDN-1);
- MoveCursor(&line1,&samp1);
- DrawText("*",line1+4,samp1-4,8,0,numDN-1);
- MoveCursor(&line2,&samp2);
- DrawText("*",line2+4,samp2-4,8,0,numDN-1);
- RemoveCursor();
- ClearDisplay(0);
-
- if (samp1 > samp2)
- {
- i= samp2;
- samp2= samp1;
- samp1= i;
- }
- if (samp1 < left)
- samp1 = left;
- if (samp2 > right)
- samp2 = right;
- if (samp2 < left)
- samp2 = left; /* both end points < minx of plot */
- if (samp1 > right)
- samp1 = right; /* both end points > maxx of plot */
-
- start = (samp1-left) * ((float) len /(float)width);
- len = (samp2-samp1) * ((float) len /(float)width);
-
- if(len > 0)
- {
- /* X-axis range selected is > 0 */
-
- minx = 0x7fffffff;
- maxx = 0x80000000;
- miny = 0x7fffffff;
- maxy = 0x80000000;
- for (i= start; i<start+len; i++)
- {
- if (xbuf[i] < minx)
- minx = xbuf[i];
- if (xbuf[i] > maxx)
- maxx = xbuf[i];
- if (ybuf[i] < miny)
- miny = ybuf[i];
- if (ybuf[i] > maxy)
- maxy = ybuf[i];
- }
- prevy = lowedge - ((int) (((float) (ybuf[start] - miny)) * scale_ydata_to_screen));
- prevx = leftedge - ((int) (((float) (xbuf[start] - minx)) * scale_xdata_to_screen));
- }
- else
- {
- /* selected X range is zero */
- zoom = -1;
- }
- }
- else
- zoom = -1;
- }
-
- } /* end Plotpair */
-