Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

simple.c

Go to the documentation of this file.
00001 
00002 /* simple.c:    Simple C interface onto the lux libraries.
00003  *               -- reinventing the wheel yet again...
00004  *
00005  *              Accessible functions:
00006  *
00007  *                      draw_box
00008  *                      add_label
00009  *                      set_color
00010  *                      plot
00011  *                      move_to
00012  *                      draw_to
00013  *                      point
00014  *                      get_mouse
00015  *                      pause
00016  *                      clear_graphics
00017  *                      exit_graphics
00018  *
00019  *              Less commonly used:
00020  *
00021  *                      crop_gfx
00022  *                      nocrop_gfx
00023  *                      wait_for_mouse
00024  *                      check_mouse
00025  *
00026  *              All positions are specified in "data" units, so the
00027  *              "draw" functions can only be used after the box has
00028  *              been constructed.
00029  */
00030 
00031 #include <stdio.h>
00032 
00033 typedef unsigned long Window;
00034 
00035 static int      print   = 1;
00036 
00037 static Window   xwin    = 0;
00038 static int      crop    = 1;
00039 
00040 void crop_gfx()   {crop = 1;}
00041 void nocrop_gfx() {crop = 0;}
00042 
00043 static int      xorigin = 100;
00044 static int      yorigin = 100;
00045 static int      xsize   = 400;
00046 static int      ysize   = 400;
00047 
00048 static float    xmin    = 0;
00049 static float    xmax    = 0;
00050 static float    ymin    = 0;
00051 static float    ymax    = 0;
00052 
00053 static float    xlast[2] = {0, 0};
00054 static float    ylast[2] = {0, 0};
00055 
00056 static void initialize_graphics()
00057 {
00058     if ((xwin = lux_openwin(xorigin, yorigin, xsize, ysize)) <= 0)
00059         fprintf(stderr, "Can't initialize graphics\n");
00060 }
00061 
00062 void set_box(int xo, int yo, int xs, int ys)
00063 {
00064     if (xo >= 0) xorigin = xo;
00065     if (yo >= 0) yorigin = yo;
00066     if (xs > 0) xsize = xs;
00067     if (ys > 0) ysize = ys;
00068 }
00069 
00070 void Draw_box(float xmin_in, float xmax_in, char *xlabel,
00071               float ymin_in, float ymax_in, char *ylabel,
00072               int draw)
00073 {
00074     if (!xwin) initialize_graphics();
00075 
00076     /* Draw a box, with tick marks. */
00077 
00078     xmin = xmin_in;
00079     xmax = xmax_in;
00080     ymin = ymin_in;
00081     ymax = ymax_in;
00082 
00083     lux_setup_region(xwin, 1.5, 1.5, 7.5, 7.5);
00084     lux_setup_axis(xwin, xmin, xmax, ymin, ymax);
00085 
00086     if (draw) {
00087 
00088         lux_draw_axis(xwin);
00089 
00090         /* Add optional labels. */
00091 
00092         if (xlabel && *xlabel != '\0')
00093             lux_draw_string(xwin,
00094                             0.5*(xmin + xmax), ymin - 0.075*(ymax - ymin),
00095                             -1., xlabel, 0);
00096 
00097         if (ylabel && *ylabel != '\0')
00098             lux_draw_vstring(xwin,
00099                              xmin - 0.077*(xmax - xmin), 0.5*(ymin + ymax),
00100                              0., ylabel, 0);
00101     }
00102 }
00103 
00104 void draw_box(float xmin_in, float xmax_in, char *xlabel,
00105               float ymin_in, float ymax_in, char *ylabel)
00106 {
00107     Draw_box(xmin_in, xmax_in, xlabel, ymin_in, ymax_in, ylabel, 1);
00108 }
00109 
00110 void nodraw_box()
00111 {
00112     Draw_box(0, 1, "", 0, 1, "", 0);
00113 }
00114 
00115 void add_label(char *label)
00116 {
00117     if (xmax <= xmin) Draw_box(0, 1, "", 0, 1, "", 0);
00118 
00119     lux_draw_string(xwin,
00120                     0.5*(xmin + xmax), ymax + 0.05*(ymax - ymin),
00121                     0., label, 0);
00122 }
00123 
00124 void set_color(char *color)
00125 {
00126     if (!xwin) initialize_graphics();
00127 
00128     if (color && *color != '\0')
00129         lux_set_color(xwin, lux_lookup_color(xwin, color));
00130 }
00131 
00132 static float xinterp(float x1, float y1, float x2, float y2, float y)
00133 {
00134     if (y2 == y1)
00135         return x1;
00136     else
00137         return x1 + (y - y1) * (x2 - x1) / (y2 - y1);}
00138 
00139 static float yinterp(float x1, float y1, float x2, float y2, float x)
00140 {
00141     if (x2 == x1)
00142         return y1;
00143     else
00144         return y1 + (x - x1) * (y2 - y1) / (x2 - x1);
00145 }
00146 
00147 static void plot_inside(float x1, float y1, float x2, float y2)
00148 {
00149     /* Draw the portion of the line from (x1, y1)to (x2, y2) that
00150      * lies within the box. */
00151 
00152     float xpl[2], ypl[2];
00153 
00154     if (x1 >= xmin && x1 <= xmax && y1 >= ymin && y1 <= ymax) {
00155         xpl[0] = x1;
00156         ypl[0] = y1;
00157     } else if (x2 >= xmin && x2 <= xmax && y2 >= ymin && y2 <= ymax) {
00158         xpl[0] = x2;
00159         ypl[0] = y2;
00160         x2 = x1;
00161         y2 = y1;
00162         x1 = xpl[0];
00163         y1 = ypl[0];
00164     } else
00165         return;
00166 
00167     /* Plot from (x1, y1) = (xpl[0], ypl[0]) inside the box to (x2, y2). */
00168 
00169     if (x2 < xmin) {
00170         float yb = yinterp(x1, y1, x2, y2, xmin);
00171         if (yb < ymin) {
00172             xpl[1] = xinterp(x1, y1, x2, y2, ymin);
00173             ypl[1] = ymin;
00174         } else if (yb > ymax) {
00175             xpl[1] = xinterp(x1, y1, x2, y2, ymax);
00176             ypl[1] = ymax;
00177         } else {
00178             xpl[1] = xmin;
00179             ypl[1] = yb;
00180         }
00181     } else if (x2 > xmax) {
00182         float yb = yinterp(x1, y1, x2, y2, xmax);
00183         if (yb < ymin) {
00184             xpl[1] = xinterp(x1, y1, x2, y2, ymin);
00185             ypl[1] = ymin;
00186         } else if (yb > ymax) {
00187             xpl[1] = xinterp(x1, y1, x2, y2, ymax);
00188             ypl[1] = ymax;
00189         } else {
00190             xpl[1] = xmax;
00191             ypl[1] = yb;
00192         }
00193     } else {
00194         if (y2 < ymin) {
00195             xpl[1] = xinterp(x1, y1, x2, y2, ymin);
00196             ypl[1] = ymin;
00197         } else if (y2 > ymax) {
00198             xpl[1] = xinterp(x1, y1, x2, y2, ymax);
00199             ypl[1] = ymax;
00200         } else {
00201             xpl[1] = x2;
00202             ypl[1] = y2;
00203         }
00204     }
00205 
00206     lux_draw_linesf(xwin, xpl, ypl, 2, 0);
00207 
00208 }
00209 
00210 void plot(float *x, float *y, int n)
00211 {
00212     if (!xwin) {
00213 
00214         if (print)
00215             fprintf(stderr, "plot: must draw box before plotting data\n");
00216         print = 0;
00217 
00218     } else {
00219 
00220         if (crop) {
00221 
00222             /* Apply cropping as we go. */
00223 
00224             int i1 = 0, i2;
00225 
00226             while (i1 < n) {
00227 
00228                 while (i1 < n && (x[i1] < xmin || x[i1] > xmax
00229                                   || y[i1] < ymin || y[i1] > ymax)) i1++;
00230 
00231                 if (i1 >= n) return;
00232 
00233                 /* Point #i1 is the first to lie inside the box. */
00234 
00235                 i2 = i1;
00236                 while (i2 < n && x[i2] >= xmin && x[i2] <= xmax
00237                        && y[i2] >= ymin && y[i2] <= ymax) i2++;
00238 
00239                 /* Point #i2 is the first to lie outside the box. */
00240 
00241                 /* Special treatment of line from i1-1 to i1. */
00242 
00243                 if (i1 > 0)
00244                     plot_inside(x[i1-1], y[i1-1], x[i1], y[i1]);
00245 
00246                 /* Draw from i1 to i2-1. */
00247 
00248                 if (i2 > i1+1) lux_draw_linesf(xwin, x+i1, y+i1, i2-i1, 0);
00249 
00250                 /* Special treatment of line from i2-1 to i2. */
00251 
00252                 if (i2 < n)
00253                     plot_inside(x[i2-1], y[i2-1], x[i2], y[i2]);
00254 
00255                 i1 = i2;
00256             }
00257 
00258         } else
00259 
00260             lux_draw_linesf(xwin, x, y, n, 0);
00261     }
00262 }
00263 
00264 void move_to(float x, float y)
00265 {
00266     if (!xwin) {
00267         if (print)
00268             fprintf(stderr, "plot: must draw box before plotting data\n");
00269         print = 0;
00270     } else {
00271         xlast[0] = x;
00272         ylast[0] = y;
00273     }
00274 }
00275 
00276 void draw_to(float x, float y)
00277 {
00278     if (!xwin) {
00279         if (print)
00280             fprintf(stderr, "plot: must draw box before plotting data\n");
00281         print = 0;
00282     } else {
00283         xlast[1] = x;
00284         ylast[1] = y;
00285 
00286         if (crop)
00287             plot_inside(xlast[0], ylast[0], xlast[1], ylast[1]);
00288         else
00289             lux_draw_linesf(xwin, xlast, ylast, 2, 0);
00290 
00291         xlast[0] = x;
00292         ylast[0] = y;
00293     }
00294 }
00295 
00296 void point(float x, float y, float point_size)
00297 {
00298     if (!xwin) {
00299         if (print)
00300             fprintf(stderr, "plot: must draw box before plotting data\n");
00301         print = 0;
00302     } else {
00303         lux_fill_arcf(xwin,
00304                       x - point_size/2,
00305                       y - point_size/2, 
00306                       point_size,
00307                       point_size * (ymax-ymin) / (xmax-xmin),
00308                       0.0, 360.0);
00309     }
00310 }
00311 
00312 int check_mouse()
00313 {
00314     /* Return 0 if no mouse button has been pressed; return the number
00315        of the button (1, 2, 3) otherwise. */
00316 
00317     int i = lux_check_buttonpress(xwin);
00318 
00319     if (i < 0 || i > 3)
00320         return 0;
00321     else
00322         return i;
00323 }
00324 
00325 static int mouse_print = 1;
00326 
00327 void get_mouse(float *x, float *y)
00328 {
00329 
00330     /* Return cursor position on right mouse click. */
00331 
00332     if (mouse_print) {
00333         fprintf(stderr,
00334                 "use left button to get cursor position information,\n");
00335         fprintf(stderr,
00336                 "use right button to capture cursor coordinates\n");
00337         mouse_print = 0;
00338     }
00339 
00340     get_mouse_position(xwin, x, y);
00341     /* fprintf(stderr, "x = %f, y = %f\n", *x, *y); */
00342 }
00343 
00344 void wait_for_mouse()
00345 {
00346     /* Wait for mouse press before continuing. */
00347 
00348     float xdum, ydum;
00349 
00350     if (!xwin) return;
00351 
00352     fprintf(stderr,
00353             "\a\npress any mouse button in display window to continue\n");
00354     get_mouse_position(xwin, &xdum, &ydum);
00355 }
00356 
00357 void pause(int time)
00358 {
00359     lux_pause(time);
00360 }
00361 
00362 void clear_graphics()
00363 {
00364     /* Clear the graphics window. */
00365 
00366     lux_reset_window(xwin);
00367 }
00368 
00369 void exit_graphics()
00370 {
00371     /* Enter idle mode before quitting.  Exit on any keypress. */
00372 
00373     if (!xwin) return;
00374 
00375     fprintf(stderr, "\a\npress any key in display window to exit\n");
00376     while(!win_getkey(xwin));
00377 }
00378 
00379 
00380 #ifdef TEST
00381 
00382 /* Run a standard test program... */
00383 
00384 #define N 6
00385 
00386 main()
00387 {
00388     float x[N] = {0.1, 0.9, 0.9, 0.5, 0.1, 0.1};
00389     float y[N] = {0.1, 0.1, 0.9, 2.2, 0.9, 0.1};
00390 
00391     set_color("blue");
00392     draw_box(0, 1, "x-axis", 0, 2, "y-axis");
00393 
00394     nocrop_gfx();
00395     set_color("black");
00396     plot(x, y, N);
00397 
00398     crop_gfx();
00399     set_color("yellow");
00400     plot(x, y, N);
00401 
00402     set_color("green");
00403     move_to(0.2, 0.5);
00404     draw_to(0.2, 0.6);
00405     draw_to(0.3, 0.6);
00406     draw_to(0.3, 0.5);
00407     draw_to(0.2, 0.5);
00408 
00409     set_color("red");
00410     add_label("hello, this is a test");
00411 
00412     set_color("purple");
00413     point(0.9, 1.0, .1);
00414 
00415     get_mouse(x, y);
00416 
00417     clear_graphics();
00418     set_color("pink");
00419     draw_box(0, (*x > 0 ? *x : 1), "x-axis",
00420              0, (*y > 0 ? *y : 1), "y-axis");
00421 
00422     get_mouse(x, y);
00423     get_mouse(x, y);
00424 
00425     while(1) {
00426         int i = check_mouse();
00427         fprintf(stderr, "mouse = %d\n", i);
00428         if (i > 0) break;
00429         pause(100000);
00430     }
00431 
00432     exit_graphics();
00433 }
00434 
00435 #endif

Generated at Sun Feb 24 09:57:16 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001