source: project/chicken/tags/0.1071/examples/x11cplot.c @ 17995

Last change on this file since 17995 was 17995, checked in by felix winkelmann, 10 years ago

imported historic version of chicken (0.1071)

File size: 9.9 KB
Line 
1/* Code from Gary W. Flake's book "The computational Beaty of Nature" */
2
3
4#include <unistd.h>
5#include <stdlib.h>
6#include <stdio.h>
7#include <strings.h>
8#include <X11/Xlib.h>
9#include <X11/Xutil.h>
10#include <math.h>
11#include "x11cplot.h"
12
13
14#define NUM_LEVELS      256
15#define BORDER_WIDTH    2
16#define C_WHITE         0
17#define C_BLACK         1
18
19
20#define MIN(x, y)     ((x) < (y) ? (x) : (y))
21#define MAX(x, y)     ((x) > (y) ? (x) : (y))
22#define ABS(x)        ((x) >= 0 ? (x) : -(x))
23#define SIGN(x)       ((x) >= 0 ? 1 : -1)
24#define SQR(x)        ((x)*(x))
25#define GETBIT(c,i)   (((1 << (i)) & (c)) ? 1 : 0)
26#define SETBIT(c,i,b) ((b) ? ((c) | (1 << (i))) : ((c) & ~(1 << (i))))
27
28#define H2V(x) ((x)<1.0/6 ? 6*(x) : (x)<0.5 ? 1.0 : (x)<4.0/6 ? 4-6*(x) : 0.0)
29
30#define NORMX(x) \
31  ((int) (plot_xmax == plot_xmin) ? plot_xmin : \
32   ((((x) - plot_xmin) / (plot_xmax - plot_xmin)) * plot_width))
33
34#define NORMY(y) \
35  ((int) (plot_ymax == plot_ymin) ? plot_ymin : \
36   (((plot_ymin - (y)) / (plot_ymax - plot_ymin) + 1.0) * plot_height))
37
38#define LIMX(x) (((x) == plot_width) ? ((x) - 1) : (x))
39#define LIMY(y) (((y) == plot_height) ? ((y) - 1) : (y))
40
41#define COLOR(val) (plot_inverse ? ((plot_levels - 1) - (val)) : (val))
42
43
44static int x_backgroundcolor = C_WHITE, x_foregroundcolor = C_BLACK;
45static int x_screen, x_depth, x11plot_levels, x11plot_width, x11plot_height;
46static unsigned long x_blackpixel, x_whitepixel;
47static unsigned long x_colors[NUM_LEVELS];
48static Colormap x_colormap;
49static Display  *x_display;
50static XGCValues x_gcvalues;
51static Window x_window;
52static GC x_gc;
53
54
55int plot_levels, plot_width, plot_height, plot_inverse = 0, plot_mag = 1;
56double plot_xmin, plot_xmax, plot_ymin, plot_ymax;
57int x11_force_flush = 0;
58
59
60static int create_gc(Window x_newwindow, GC *x_newgc)
61{
62  *x_newgc = XCreateGC(x_display, x_newwindow, (unsigned long)0, &x_gcvalues);
63  if(*x_newgc == 0)                     /* unable to create a GC */
64    return(0);
65  XSetForeground(x_display, *x_newgc, x_whitepixel);
66  XSetBackground(x_display, *x_newgc, x_blackpixel);
67  x_backgroundcolor = C_BLACK;
68  x_foregroundcolor = C_WHITE;
69  return(1);
70}
71
72
73static Window open_window(int width, int height)
74{
75   XSetWindowAttributes x_windowattributes;
76   unsigned long        x_windowmask;
77   Window               x_newwindow;
78
79   /* Set up the attributes for the window. */
80
81   x_windowattributes.backing_store = Always;
82   x_windowattributes.event_mask = ButtonPressMask | ButtonReleaseMask;
83   x_windowattributes.border_pixel  = x_whitepixel;
84   x_windowattributes.background_pixel = x_blackpixel;
85   x_backgroundcolor = C_BLACK;
86   x_foregroundcolor = C_WHITE;
87   
88   x_windowmask = CWBackingStore | CWEventMask | CWBackPixel | CWBorderPixel;
89   x_windowattributes.override_redirect = False;
90   x_windowmask |= CWOverrideRedirect;
91
92   /* Open a window on the display */
93   x_newwindow = XCreateWindow(x_display, XRootWindow(x_display, x_screen),
94                               0,0, width,height, BORDER_WIDTH, x_depth,
95                               InputOutput, CopyFromParent, x_windowmask,
96                               &x_windowattributes);
97
98   XSetStandardProperties(x_display, x_newwindow, "x11plot", "x11plot", None, 0,
99                          0, 0);
100
101   /* Create a graphic context (GC) for the window, only for the first time */
102   if(create_gc(x_newwindow, &x_gc) == 0) {
103     XDestroyWindow(x_display, x_newwindow);
104     return((Window)0);
105   }
106 
107   /* Ask X to place the window visibly on the screen */
108   XMapWindow(x_display, x_newwindow);
109   XFlush(x_display);
110   return(x_newwindow);
111}
112
113
114static void int_to_hexstr(int i, char *str)
115{
116   sprintf(str, "%2x", i);
117   for(i = 0; i < 2; i++)
118     if(str[i] == ' ') str[i] = '0';
119}
120
121
122static inline double hue_shift(double x)
123{
124  return(x - floor(x));
125}
126
127
128static void hsb_to_rgb(double hue, int *R, int *G, int *B)
129{
130  double hueshift;
131
132  hueshift = hue_shift(hue + 2.0/6);
133  *R = 255 * H2V(hueshift) + 0.5;
134  hueshift = hue_shift(hue);
135  *G = 255 * H2V(hueshift) + 0.5;
136  hueshift = hue_shift(hue - 2.0/6);
137  *B = 255 * H2V(hueshift) + 0.5;
138}
139
140
141void _plot_init(int width, int height, int levels)
142{
143  XColor x_hardwarecolor;
144  char hexR[8], hexG[8], hexB[8], name[16], *display;
145  int status, i, R, G, B;
146  double hue;
147
148  display = getenv("DISPLAY");
149  if((x_display = XOpenDisplay(display)) == NULL) {
150    fprintf(stderr, "X11plot_init: could not open display %s.\n",
151            XDisplayName(display));
152    exit(1);
153  }
154  x_screen     = XDefaultScreen(x_display);
155  x_depth      = XDefaultDepth(x_display, x_screen);
156  x_whitepixel = XWhitePixel(x_display, x_screen);
157  x_blackpixel = XBlackPixel(x_display, x_screen);
158  x_colormap   = XDefaultColormap(x_display, x_screen);
159
160  /* Initialize grey map */
161  if(x_depth == 1 || levels == 2) {  /* monochrome system */
162    for(i = 0; i < NUM_LEVELS / 2; i++) x_colors[i] = x_blackpixel;
163    for(i = NUM_LEVELS / 2; i < NUM_LEVELS; i++) x_colors[i] = x_whitepixel;
164  }
165  else {
166    for(i = 0; i < NUM_LEVELS; i++) {
167      if(i > 0) {
168        hue = i / (NUM_LEVELS - 1.0);
169        hsb_to_rgb(hue, &R, &G, &B);
170        int_to_hexstr(R, hexR);
171        int_to_hexstr(G, hexG);
172        int_to_hexstr(B, hexB);
173        sprintf(name,"#%s%s%s", hexR, hexG, hexB);
174        status = XParseColor(x_display, x_colormap, name, &x_hardwarecolor);
175        if (status != 0) {
176          status = XAllocColor(x_display, x_colormap, &x_hardwarecolor);
177          x_colors[i] = x_hardwarecolor.pixel;
178        }
179        else
180          fprintf(stderr, "No such color %s\n", name);
181      }
182      else
183        x_colors[i] = x_blackpixel;
184    }
185  }
186
187  x11plot_width = width;
188  x11plot_height = height;
189  x11plot_levels = levels;
190  x_window = open_window(width * plot_mag, height * plot_mag);
191}
192
193
194void _plot_point(int i, int j, int val)
195{
196  int cval, ii, jj;
197
198  val = (val < 0) ? 0 : (val >= x11plot_levels) ? x11plot_levels - 1: val;
199  cval = ((double)val / (x11plot_levels - 1)) * (NUM_LEVELS - 1) + 0.5;
200  XSetForeground(x_display, x_gc, x_colors[cval]);
201  for(ii = 0; ii < plot_mag; ii++)
202    for(jj = 0; jj < plot_mag; jj++)
203      XDrawPoint(x_display, x_window, x_gc, i * plot_mag + ii,
204                 j * plot_mag + jj);
205  if(x11_force_flush) XFlush(x_display);
206}
207
208
209void _plot_line(int i, int j, int k, int l, int val)
210{
211  int cval, ii, jj;
212
213  val = (val < 0) ? 0 : (val >= x11plot_levels) ? x11plot_levels : val;
214  cval = ((double)val / x11plot_levels) * (NUM_LEVELS - 1) + 0.5;
215  XSetForeground(x_display, x_gc, x_colors[cval]);
216#if 0
217  for(ii = 0; ii < plot_mag; ii++)
218    for(jj = 0; jj < plot_mag; jj++)
219      XDrawLine(x_display, x_window, x_gc,
220                i * plot_mag + ii, j * plot_mag + jj,
221                k * plot_mag + ii, l * plot_mag + jj);
222#else
223  if(plot_mag == 1)
224    XDrawLine(x_display, x_window, x_gc, i, j, k, l);
225  else {
226    double tx, ty, t, dt;
227    int len;
228 
229    if(i == k && j == l)
230      _plot_point(i, j, val);
231    else {
232      len = MAX(ABS(i - k), ABS(j - l));
233      dt = 1.0 / len;
234      for(ii = 0, t = 0.0; ii < len + 1; ii++, t += dt) {
235        tx = t * i + (1.0 - t) * k + 0.5;
236        ty = t * j + (1.0 - t) * l + 0.5;
237        _plot_point(tx, ty, val);
238      }
239    }
240  }
241#endif
242}
243
244
245static Bool button_click(XEvent *ev)
246{
247  return(1);
248}
249
250
251void _plot_finish(void)
252{
253  XEvent ev;
254
255  XFlush(x_display);
256  fprintf(stderr, ">> Done. Click mouse on window to end program. <<\n");
257  XIfEvent(x_display, &ev, (Bool (*)()) button_click, 0);
258}
259
260
261void plot_init(int width, int height, int levels)
262{
263  _plot_init(width, height, levels);
264  plot_levels = levels;
265  plot_width = width;
266  plot_height = height;
267  plot_xmin = 0.0;
268  plot_xmax = width - 1;
269  plot_ymin = height - 1;
270  plot_ymax = 0.0;
271}
272
273
274void plot_set_range(double xmin, double xmax, double ymin, double ymax)
275{
276  plot_xmin = xmin;
277  plot_xmax = xmax;
278  plot_ymin = ymin;
279  plot_ymax = ymax;
280}
281
282
283void plot_set_all(int val)
284{
285  int i;
286
287  for(i = 0; i < plot_width; i++)
288    _plot_line(i, 0, i, plot_height - 1, COLOR(val));
289}
290
291
292void plot_point(double x, double y, int val)
293{
294  int xi, yi;
295 
296  xi = NORMX(x); xi = LIMX(xi);
297  yi = NORMY(y); yi = LIMY(yi);
298  if(!(xi < 0 || xi >= plot_width || yi < 0 || yi >= plot_height))
299    _plot_point(xi, yi, COLOR(val));
300}
301
302
303void plot_line(double x1, double y1, double x2, double y2, int val)
304{
305  int ax, ay, bx, by;
306 
307  ax = NORMX(x1); ax = LIMX(ax);
308  ay = NORMY(y1); ay = LIMY(ay);
309  bx = NORMX(x2); bx = LIMX(bx);
310  by = NORMY(y2); by = LIMY(by);
311  _plot_line(ax, ay, bx, by, COLOR(val));
312}
313
314
315void plot_finish(void)
316{
317  _plot_finish();
318}
319
320
321static void plot_line_internal(int ax, int ay, int bx, int by, int val)
322{
323  double tx, ty, t, dt;
324  int len, i;
325 
326  if(ax == bx && ay == by)
327    _plot_point(ax, ay, val);
328  else {
329    len = MAX(ABS(ax - bx), ABS(ay - by));
330    dt = 1.0 / len;
331    for(i = 0, t = 0.0; i < len + 1; i++, t += dt) {
332      tx = t * ax + (1.0 - t) * bx + 0.5;
333      ty = t * ay + (1.0 - t) * by + 0.5;
334      _plot_point(tx, ty, val);
335    }
336  }
337}
338
339
340void plot_box(double ulx, double uly, double lrx, double lry, int lwidth)
341{
342  int i, ulxi, ulyi, lrxi, lryi;
343
344  ulxi = NORMX(ulx); ulxi = LIMX(ulxi);
345  ulyi = NORMY(uly); ulyi = LIMY(ulyi);
346  lrxi = NORMX(lrx); lrxi = LIMX(lrxi);
347  lryi = NORMY(lry); lryi = LIMY(lryi);
348
349  _plot_line(ulxi, ulyi, lrxi, ulyi, COLOR(plot_levels - 1));
350  _plot_line(lrxi, ulyi, lrxi, lryi, COLOR(plot_levels - 1));
351  _plot_line(lrxi, lryi, ulxi, lryi, COLOR(plot_levels - 1));
352  _plot_line(ulxi, lryi, ulxi, ulyi, COLOR(plot_levels - 1));
353
354  for(i = 1; i < lwidth + 1; i++) {
355    _plot_line(ulxi - i, ulyi - i, lrxi + i, ulyi - i, COLOR(0));
356    _plot_line(lrxi + i, ulyi - i, lrxi + i, lryi + i, COLOR(0));
357    _plot_line(lrxi + i, lryi + i, ulxi - i, lryi + i, COLOR(0));
358    _plot_line(ulxi - i, lryi + i, ulxi - i, ulyi - i, COLOR(0));
359  }
360
361  _plot_line(ulxi - i, ulyi - i, lrxi + i, ulyi - i, COLOR(plot_levels - 1));
362  _plot_line(lrxi + i, ulyi - i, lrxi + i, lryi + i, COLOR(plot_levels - 1));
363  _plot_line(lrxi + i, lryi + i, ulxi - i, lryi + i, COLOR(plot_levels - 1));
364  _plot_line(ulxi - i, lryi + i, ulxi - i, ulyi - i, COLOR(plot_levels - 1));
365}
Note: See TracBrowser for help on using the repository browser.