import source from 1.3.40
[external/swig.git] / Examples / GIFPlot / Lib / plot2d.c
1 /* ----------------------------------------------------------------------------- 
2  * plot2d.c
3  *
4  *     2-Dimensional plotting
5  * 
6  * Author(s) : David Beazley (beazley@cs.uchicago.edu)
7  * Copyright (C) 1995-1996
8  *
9  * See the file LICENSE for information on usage and redistribution.    
10  * ----------------------------------------------------------------------------- */
11
12 #define PLOT2D
13
14 #include "gifplot.h"
15
16 /* ------------------------------------------------------------------------
17    Plot2D *new_Plot2D(FrameBuffer *frame, xmin, ymin, xmax, ymax)
18
19    Create a new 2D plot with given minimum and maximum coordinates.
20    ------------------------------------------------------------------------ */
21 Plot2D  *new_Plot2D(FrameBuffer *frame,double xmin,double ymin,double xmax,double ymax) {
22   Plot2D  *p2;
23   if (frame) {
24     if (xmax <= xmin) return (Plot2D *) 0;
25     if (ymax <= ymin) return (Plot2D *) 0;
26     p2 = (Plot2D *) malloc(sizeof(Plot2D));
27     p2->frame = frame;
28     p2->xmin = xmin;
29     p2->ymin = ymin;
30     p2->xmax = xmax;
31     p2->ymax = ymax;
32     p2->view_xmin = 0;
33     p2->view_xmax = frame->width;
34     p2->view_ymin = 0;
35     p2->view_ymax = frame->height;
36     p2->xscale = LINEAR;
37     p2->yscale = LINEAR;
38     p2->dx = (p2->view_xmax - p2->view_xmin)/(p2->xmax - p2->xmin);
39     p2->dy = (p2->view_ymax - p2->view_ymin)/(p2->ymax - p2->ymin);
40     return p2;
41   }
42   return (Plot2D *) 0;
43 }
44
45 /* ----------------------------------------------------------------------------
46    delete_Plot2D(Plot2D *p2)
47
48    Delete a 2D plot
49    ---------------------------------------------------------------------------- */
50 void
51 delete_Plot2D(Plot2D *p2) {
52   if (p2)
53     free((char *) p2);
54 }
55
56 /* -----------------------------------------------------------------------------
57    Plot2D *Plot2D_copy(Plot2D *p2)
58
59    Makes a copy of the Plot2D data structure.
60    ----------------------------------------------------------------------------- */
61
62 Plot2D *Plot2D_copy(Plot2D *p2) {
63   Plot2D *c2;
64   if (p2) {
65     c2 = (Plot2D *) malloc(sizeof(Plot2D));
66     if (c2) {
67       c2->frame = p2->frame;
68       c2->view_xmin = p2->view_xmin;
69       c2->view_ymin = p2->view_ymin;
70       c2->view_xmax = p2->view_xmax;
71       c2->view_ymax = p2->view_ymax;
72       c2->xmin = p2->xmin;
73       c2->ymin = p2->ymin;
74       c2->xmax = p2->xmax;
75       c2->ymax = p2->ymax;
76       c2->xscale = p2->xscale;
77       c2->yscale = p2->yscale;
78       c2->dx = p2->dx;
79       c2->dy = p2->dy;
80     }
81     return c2;
82   } else {
83     return (Plot2D *) 0;
84   }
85 }
86
87 /* -----------------------------------------------------------------------------
88    Plot2D_clear(Plot2D *p2, Pixel c)
89
90    Clear the region assigned to this plot to the given color.
91    -------------------------------------------------------------------------- */
92
93 void Plot2D_clear(Plot2D *p2, Pixel c) {
94   int i,j;
95   for (i = p2->view_xmin; i < p2->view_xmax; i++)
96     for (j = p2->view_ymin; j < p2->view_ymax; j++) {
97       p2->frame->pixels[j][i] = c;
98     }
99 }
100
101 /* ------------------------------------------------------------------------------
102    Plot2D_setview
103
104    Sets the plot region on the framebuffer
105    ------------------------------------------------------------------------------ */
106
107 void
108 Plot2D_setview(Plot2D *p2, int vxmin, int vymin, int vxmax, int vymax) {
109   if (p2) {
110     p2->view_xmin = vxmin;
111     p2->view_ymin = vymin;
112     p2->view_xmax = vxmax;
113     p2->view_ymax = vymax;
114     p2->dx = (p2->view_xmax - p2->view_xmin)/(p2->xmax - p2->xmin);
115     p2->dy = (p2->view_ymax - p2->view_ymin)/(p2->ymax - p2->ymin);
116     FrameBuffer_setclip(p2->frame,vxmin,vymin,vxmax,vymax);
117   }
118 }
119
120 /* -------------------------------------------------------------------------------
121    Plot2D_setrange(Plot2D *p2, double xmin, double ymin, double xmax, double ymax)
122
123    Sets the plotting range.
124    ------------------------------------------------------------------------------- */
125
126 void
127 Plot2D_setrange(Plot2D *p2, double xmin, double ymin, double xmax, double ymax) {
128   if (p2) {
129     p2->xmin = xmin;
130     p2->ymin = ymin;
131     p2->xmax = xmax;
132     p2->ymax = ymax;
133     p2->dx = (p2->view_xmax - p2->view_xmin)/(p2->xmax - p2->xmin);
134     p2->dy = (p2->view_ymax - p2->view_ymin)/(p2->ymax - p2->ymin);
135   }
136 }
137
138 /* -------------------------------------------------------------------------------
139    Plot2D_setscale(Plot2D *p2, int xscale, int yscale)
140
141    Sets the plotting scaling method
142    ------------------------------------------------------------------------------- */
143
144 void
145 Plot2D_setscale(Plot2D *p2, int xscale, int yscale) {
146   if (p2) {
147     p2->xscale = xscale;
148     p2->yscale = yscale;
149   }
150 }
151
152 /* ----------------------------------------------------------------------------
153    Plot2D_transform(Plot2D *p2, double x, double y, int *px, int *py)
154    
155    Transforms x,y into screen coordinates px and py.  Result is returned
156    in px and py.  Rounds to the nearest pixel instead of truncating.
157    ----------------------------------------------------------------------------- */
158
159 void
160 Plot2D_transform(Plot2D *p2, double x, double y, int *px, int *py) {
161   if (p2) {
162     *px = p2->view_xmin + (int) (p2->dx*(x-p2->xmin) + 0.5);
163     *py = p2->view_ymin + (int) (p2->dy*(y-p2->ymin) + 0.5);
164   }
165 }
166
167 /* -------------------------------------------------------------------------------
168    Plot2D_plot(Plot2D *p2, double x, double y, Pixel color)
169
170    Plot a 2D Point of a given color
171    ------------------------------------------------------------------------------- */
172 void
173 Plot2D_plot(Plot2D *p2, double x, double y, Pixel color) {
174   int px, py;
175
176   Plot2D_transform(p2,x,y,&px,&py);
177   FrameBuffer_plot(p2->frame, px, py, color);
178 }
179
180 /* -------------------------------------------------------------------------------
181    Plot2D_box(Plot2D *p2, double x1, double y1, double x2, double y2, Pixel Color)
182
183    Plot an outline box on the 2D plot
184    ------------------------------------------------------------------------------- */
185 void
186 Plot2D_box(Plot2D *p2, double x1, double y1,double x2, double y2, Pixel color) {
187   int ix1, ix2,iy1, iy2;
188
189   Plot2D_transform(p2,x1,y1,&ix1,&iy1);
190   Plot2D_transform(p2,x2,y2,&ix2,&iy2);
191   FrameBuffer_box(p2->frame,ix1,iy1,ix2,iy2,color);
192 }
193
194 /* -------------------------------------------------------------------------------
195    Plot2D_solidbox(Plot2D *p2, double x1, double y1, double x2, double y2, Pixel Color)
196
197    Plot a solid box box on the 2D plot
198    ------------------------------------------------------------------------------- */
199 void
200 Plot2D_solidbox(Plot2D *p2, double x1, double y1,double x2, double y2, Pixel color) {
201   int ix1, ix2,iy1, iy2;
202
203   Plot2D_transform(p2,x1,y1,&ix1,&iy1);
204   Plot2D_transform(p2,x2,y2,&ix2,&iy2);
205   FrameBuffer_solidbox(p2->frame,ix1,iy1,ix2,iy2,color);
206 }
207
208 /* -------------------------------------------------------------------------------
209    Plot2D_interpbox(Plot2D *p2, double x1, double y1, double x2, double y2,
210                     Pixel c1, Pixel c2, Pixel c3, Pixel c4)
211
212    Plot a color-interpolated box on the 2D plot
213    ------------------------------------------------------------------------------- */
214 void
215 Plot2D_interpbox(Plot2D *p2, double x1, double y1,double x2, double y2,
216                  Pixel c1, Pixel c2, Pixel c3, Pixel c4) {
217   int ix1, ix2,iy1, iy2;
218
219   Plot2D_transform(p2,x1,y1,&ix1,&iy1);
220   Plot2D_transform(p2,x2,y2,&ix2,&iy2);
221   FrameBuffer_interpbox(p2->frame,ix1,iy1,ix2,iy2,c1,c2,c3,c4);
222 }
223
224 /* -------------------------------------------------------------------------------
225    Plot2D_circle(Plot2D *p2, double x, double y, double radius, Pixel color)
226
227    Make an outline circle on the 2D plot.
228    ------------------------------------------------------------------------------- */
229 void
230 Plot2D_circle(Plot2D *p2, double x, double y, double radius, Pixel color) {
231   int ix, iy, ir;
232
233   Plot2D_transform(p2,x,y,&ix,&iy);
234   ir = p2->dx * radius;        /* This is really incorrect. Will need ellipse */
235   if (ir > 1) 
236     FrameBuffer_circle(p2->frame,ix,iy,ir,color);
237   else
238     FrameBuffer_plot(p2->frame,ix,iy,color);
239   
240 }
241   
242 /* -------------------------------------------------------------------------------
243    Plot2D_solidcircle(Plot2D *p2, double x, double y, double radius, Pixel color)
244
245    Make an solid circle on the 2D plot.
246    ------------------------------------------------------------------------------- */
247 void
248 Plot2D_solidcircle(Plot2D *p2, double x, double y, double radius, Pixel color) {
249   int ix, iy, ir;
250
251   Plot2D_transform(p2,x,y,&ix,&iy);
252   ir = p2->dx * radius;        /* This is really incorrect. Will need ellipse */
253   if (ir > 1) 
254     FrameBuffer_solidcircle(p2->frame,ix,iy,ir,color);
255   else
256     FrameBuffer_plot(p2->frame,ix,iy,color);
257 }
258
259 /* -------------------------------------------------------------------------------
260    Plot2D_line(Plot2D *p2, double x1, double y1, double x2, double y2, Pixel color)
261
262    Draw a line
263    ------------------------------------------------------------------------------- */
264
265 void
266 Plot2D_line(Plot2D *p2, double x1, double y1, double x2, double y2, Pixel color) {
267   int ix1, ix2, iy1, iy2;
268
269   Plot2D_transform(p2,x1,y1,&ix1,&iy1);
270   Plot2D_transform(p2,x2,y2,&ix2,&iy2);
271   FrameBuffer_line(p2->frame,ix1,iy1,ix2,iy2,color);
272 }
273
274
275
276 /* -------------------------------------------------------------------------------
277    Plot2D_start(Plot2D *p2)
278
279    This should be called before starting to make a 2D plot. It will change
280    the viewport coordinates for the framebuffer and do other stuff.
281    ------------------------------------------------------------------------------- */
282
283 void Plot2D_start(Plot2D *p2) {
284   if (p2) {
285     FrameBuffer_setclip(p2->frame, p2->view_xmin,p2->view_ymin,p2->view_xmax, p2->view_ymax);
286     p2->dx = (p2->view_xmax - p2->view_xmin)/(p2->xmax - p2->xmin);
287     p2->dy = (p2->view_ymax - p2->view_ymin)/(p2->ymax - p2->ymin);
288   }
289 }
290
291 /* --------------------------------------------------------------------------
292    void Plot2D_drawpixmap(Plot2D *p2, PixMap *pm, double x, double y, Pixel color, Pixel bgcolor)
293
294    Draw a pixel map at the given coordinates.  (Used for putting symbols on 2D
295    plots).
296    -------------------------------------------------------------------------- */
297 void
298 Plot2D_drawpixmap(Plot2D *p2, PixMap *pm, double x, double y, Pixel color, Pixel bgcolor) {
299   int ix, iy;
300
301   Plot2D_transform(p2,x,y,&ix,&iy);
302   FrameBuffer_drawpixmap(p2->frame,pm,ix,iy,color,bgcolor);
303 }
304
305 /* ----------------------------------------------------------------------------
306    void Plot2D_xaxis(Plot2D *p2, double x, double y, double xtick, int ticklength, Pixel color)
307
308    Draw an X axis bar at location x,y with ticks spaced every xtick units.
309    Ticks are spaced starting at "x"
310    ----------------------------------------------------------------------------- */
311
312 void Plot2D_xaxis(Plot2D *p2, double x, double y, double xtick, int ticklength, Pixel color) {
313   int ix, iy,iy2;
314   double xt;
315
316   /* Draw a line fox the axis */
317   
318   Plot2D_line(p2,p2->xmin,y,p2->xmax,y,color);
319   xt = x;
320   while (xt >= p2->xmin) {
321     Plot2D_transform(p2,xt,y,&ix,&iy);
322     iy2 = iy+ticklength;
323     iy = iy-ticklength;
324     FrameBuffer_line(p2->frame,ix,iy,ix,iy2,color);
325     xt = xt - xtick;
326   }
327   xt = x + xtick;
328   while (xt < p2->xmax) {
329     Plot2D_transform(p2,xt,y,&ix,&iy);
330     iy2 = iy+ticklength;
331     iy = iy-ticklength;
332     FrameBuffer_line(p2->frame,ix,iy,ix,iy2,color);
333     xt = xt + xtick;
334   }
335 }
336
337
338 /* ----------------------------------------------------------------------------
339    void Plot2D_yaxis(Plot2D *p2, double x, double y, double ytick, int ticklength, Pixel c)
340
341    Draw an Y axis bar at location x,y with ticks spaced every xtick units.
342    Ticks are spaced starting at "y"
343    ----------------------------------------------------------------------------- */
344
345 void Plot2D_yaxis(Plot2D *p2, double x, double y, double ytick, int ticklength, Pixel color) {
346   int ix, iy, ix2;
347   double yt;
348
349   /* Draw a line fox the axis */
350   
351   Plot2D_line(p2,x,p2->ymin,x,p2->ymax,color);
352   yt = y;
353   while (yt >= p2->ymin) {
354     Plot2D_transform(p2,x,yt,&ix,&iy);
355     ix2 = ix+ticklength;
356     ix = ix-ticklength;
357     FrameBuffer_line(p2->frame,ix,iy,ix2,iy,color);
358     yt = yt - ytick;
359   }
360   yt = y + ytick;
361   while (yt < p2->ymax) {
362     Plot2D_transform(p2,x,yt,&ix,&iy);
363     ix2 = ix+ticklength;
364     ix = ix-ticklength;
365     FrameBuffer_line(p2->frame,ix,iy,ix2,iy,color);
366     yt = yt + ytick;
367   }
368 }
369
370
371 /* -------------------------------------------------------------------------
372    Plot2D_triangle(Plot2D *p2, double x1, double y1, 
373                                double x2, double y2, 
374                                double x3, double y3, 
375                                Pixel fillcolor)
376
377    This function draws a 2D outline triangle.
378    -------------------------------------------------------------------------- */
379
380 void Plot2D_triangle(Plot2D *p2, double x1, double y1,
381                      double x2, double y2, 
382                      double x3, double y3, Pixel color) {
383
384   Plot2D_line(p2,x1,y1,x2,y2,color);
385   Plot2D_line(p2,x2,y2,x3,y3,color);
386   Plot2D_line(p2,x3,y3,x1,y1,color);
387
388 }
389
390
391 /* -------------------------------------------------------------------------
392    Plot2D_solidtriangle(Plot2D *p2, double x1, double y1, 
393                                double x2, double y2, 
394                                double x3, double y3, 
395                                Pixel color)
396
397    This function draws a 2D filled triangle.    Can be used to
398    draw other primitives such as quadralaterals, etc...
399
400    -------------------------------------------------------------------------- */
401
402 void Plot2D_solidtriangle(Plot2D *p2, double x1, double y1, 
403
404                           double x2, double y2, 
405                           double x3, double y3, Pixel color) {
406
407   int        tx1, tx2, tx3, ty1, ty2, ty3;
408   
409   /* Transform the three points into screen coordinates */
410
411   Plot2D_transform(p2,x1,y1,&tx1,&ty1);
412   Plot2D_transform(p2,x2,y2,&tx2,&ty2);
413   Plot2D_transform(p2,x3,y3,&tx3,&ty3);
414
415   FrameBuffer_solidtriangle(p2->frame,tx1,ty1,tx2,ty2,tx3,ty3,color);
416   
417 }    
418
419 /* -------------------------------------------------------------------------
420    Plot2D_interptriangle(Plot2D *p2, double x1, double y1, Pixel c1,
421                                double x2, double y2, Pixel c2,
422                                double x3, double y3, Pixel c3);
423
424    This function draws a 2D filled triangle with color interpolation.
425    Can be used to draw other primitives such as quadralaterals, etc...
426    -------------------------------------------------------------------------- */
427
428 void Plot2D_interptriangle(Plot2D *p2, double x1, double y1, Pixel c1,
429                            double x2, double y2, Pixel c2,
430                            double x3, double y3, Pixel c3) {
431
432   int        tx1, tx2, tx3, ty1, ty2, ty3;
433   
434   /* Transform the three points into screen coordinates */
435
436   Plot2D_transform(p2,x1,y1,&tx1,&ty1);
437   Plot2D_transform(p2,x2,y2,&tx2,&ty2);
438   Plot2D_transform(p2,x3,y3,&tx3,&ty3);
439
440   FrameBuffer_interptriangle(p2->frame,tx1,ty1,c1,tx2,ty2,c2,tx3,ty3,c3);
441   
442 }    
443   
444   
445