pgplot 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1268 @@
1
+ /*
2
+ rb_pgplot.c : Ruby/PGPLOT extension library
3
+
4
+ Copyright (c) 2000,2001 Masahiro TANAKA <masa@ir.isas.ac.jp>
5
+
6
+ This program is free software.
7
+ You can distribute/modify this program
8
+ under the same terms as Ruby itself.
9
+ NO WARRANTY.
10
+ */
11
+ #include <stdio.h>
12
+ #include <cpgplot.h>
13
+ #include <ruby.h>
14
+ #include "narray.h"
15
+ #include "version.h"
16
+
17
+ #define min(a,b) (((a)<(b))?(a):(b))
18
+ #define rb_pgplot_fltary(obj) na_cast_object(obj,NA_SFLOAT)
19
+ #define rb_pgplot_intary(obj) na_cast_object(obj,NA_LINT)
20
+ #define rb_pgplot_newary(rank,shape) na_make_object(NA_SFLOAT,rank,shape,cNArray)
21
+
22
+ #define NA_PTR_FLT(dta) (float*)(((struct NARRAY*)DATA_PTR(dta))->ptr)
23
+ #define NA_PTR_INT(dta) (int*)(((struct NARRAY*)DATA_PTR(dta))->ptr)
24
+ #ifndef NA_RANK
25
+ #define NA_RANK(dta) (((struct NARRAY*)DATA_PTR(dta))->rank)
26
+ #endif
27
+ #ifndef NA_TYPE
28
+ #define NA_TYPE(dta) (((struct NARRAY*)DATA_PTR(dta))->type)
29
+ #endif
30
+ #ifndef NA_TOTAL
31
+ #define NA_TOTAL(dta) (((struct NARRAY*)DATA_PTR(dta))->total)
32
+ #endif
33
+ #ifndef NA_SHAPE0
34
+ #define NA_SHAPE0(dta) (((struct NARRAY*)DATA_PTR(dta))->shape[0])
35
+ #endif
36
+ #ifndef NA_SHAPE1
37
+ #define NA_SHAPE1(dta) (((struct NARRAY*)DATA_PTR(dta))->shape[1])
38
+ #endif
39
+
40
+ static VALUE mPgplot;
41
+ static VALUE cPgCursor;
42
+ static VALUE ePgCursorError;
43
+ static ID id_beg, id_end, id_x, id_y, id_char;
44
+
45
+ #ifdef GNU_FORTRAN
46
+ void MAIN__() {} /* Ruby has no 'MAIN__'! ; How should I handle this??? */
47
+ #endif
48
+
49
+ /* Search Minimum and Maximum values of array */
50
+ static void
51
+ rb_pgplot_minmax(VALUE na, float range[])
52
+ {
53
+ int i;
54
+ float *ptr = NA_PTR_FLT(na);
55
+
56
+ range[0] = range[1] = *ptr;
57
+ ptr++;
58
+ for (i=NA_TOTAL(na)-1; i>0; i--,ptr++) {
59
+ if (*ptr<range[0]) range[0] = *ptr; /* min */
60
+ if (*ptr>range[1]) range[1] = *ptr; /* max */
61
+ }
62
+ }
63
+
64
+
65
+ /* PGASK -- control new page prompting
66
+ pgask [true|false]
67
+ */
68
+ static VALUE
69
+ rb_pgplot_pgask( int argc, VALUE *argv, VALUE self)
70
+ {
71
+ VALUE vflag;
72
+
73
+ rb_scan_args(argc, argv, "01", &vflag);
74
+
75
+ if (RTEST(vflag))
76
+ cpgask(1);
77
+ else
78
+ cpgask(0);
79
+ return Qnil;
80
+ }
81
+
82
+
83
+ /* PGOPEN -- open a graphics device
84
+ stat = pgopen [device]
85
+ */
86
+ static VALUE
87
+ rb_pgplot_pgopen( int argc, VALUE *argv, VALUE self )
88
+ {
89
+ VALUE vdev;
90
+ const char *dev="?";
91
+
92
+ rb_scan_args(argc,argv, "01", &vdev);
93
+ if (vdev!=Qnil) dev = StringValuePtr(vdev);
94
+
95
+ return INT2NUM(cpgopen(dev));
96
+ }
97
+
98
+
99
+ /* PGBEG -- open a graphics device */
100
+ static VALUE
101
+ rb_pgplot_pgbeg( int argc, VALUE *argv, VALUE self )
102
+ {
103
+ VALUE vdev, vnxs, vnys;
104
+ int nxsub=1, nysub=1;
105
+ const char *dev="?";
106
+
107
+ rb_scan_args(argc, argv, "03", &vdev,&vnxs,&vnys);
108
+ if (vdev!=Qnil) dev = StringValuePtr(vdev);
109
+ if (vnxs!=Qnil) nxsub = NUM2INT(vnxs);
110
+ if (vnys!=Qnil) nysub = NUM2INT(vnys);
111
+
112
+ if (cpgbeg(0, dev, nxsub, nysub) != 1)
113
+ return Qnil;
114
+ else
115
+ return Qtrue;
116
+ }
117
+
118
+
119
+ /* PGENV -- set window and viewport and draw labeled frame
120
+ pgenv xmin,xmax,ymin,ymax [, just [, axis]]
121
+ xmin: the left of the viewport.
122
+ xmax: the right of the viewport.
123
+ ymin: the bottom of the viewport.
124
+ ymax: the top of the viewport
125
+ just: if just=1, the x and y axes is scaled equally,
126
+ otherwise scaled independently.
127
+ axis: controls of axes.
128
+ */
129
+ static VALUE
130
+ rb_pgplot_pgenv( int argc, VALUE *argv, VALUE self )
131
+ {
132
+ VALUE x0, x1, y0, y1, vjust, vaxis;
133
+ int just=0, axis=0;
134
+
135
+ rb_scan_args(argc, argv, "42", &x0,&x1,&y0,&y1,&vjust,&vaxis);
136
+ if (vjust!=Qnil) just = NUM2INT(vjust);
137
+ if (vaxis!=Qnil) axis = NUM2INT(vaxis);
138
+
139
+ cpgenv( NUM2DBL(x0), NUM2DBL(x1), NUM2DBL(y0), NUM2DBL(y1), just, axis );
140
+ return Qtrue;
141
+ }
142
+
143
+
144
+ /* PGLINE -- draw a polyline (curve defined by line-segments)
145
+ pgline xarray, yarray
146
+ */
147
+ static VALUE
148
+ rb_pgplot_pgline(VALUE obj, VALUE v1, VALUE v2)
149
+ {
150
+ VALUE x, y;
151
+
152
+ x = rb_pgplot_fltary( v1 );
153
+ y = rb_pgplot_fltary( v2 );
154
+
155
+ cpgline( min(NA_TOTAL(x),NA_TOTAL(y)), NA_PTR_FLT(x), NA_PTR_FLT(y) );
156
+
157
+ return Qtrue;
158
+ }
159
+
160
+ /* PGPOLY -- draw a polygon, using fill-area attributes
161
+ pgpoly xarray, yarray
162
+ */
163
+ static VALUE
164
+ rb_pgplot_pgpoly(VALUE obj, VALUE v1, VALUE v2)
165
+ {
166
+ VALUE x, y;
167
+
168
+ x = rb_pgplot_fltary( v1 );
169
+ y = rb_pgplot_fltary( v2 );
170
+
171
+ cpgpoly( min(NA_TOTAL(x),NA_TOTAL(y)), NA_PTR_FLT(x), NA_PTR_FLT(y) );
172
+
173
+ return Qtrue;
174
+ }
175
+
176
+
177
+ /* PGPT -- draw several graph markers
178
+ pgpt xarray, yarray [,symbol]
179
+ */
180
+ static VALUE
181
+ rb_pgplot_pgpt( int argc, VALUE *argv, VALUE self )
182
+ {
183
+ VALUE vx, vy, vsym;
184
+ VALUE x, y;
185
+ int sym=0;
186
+
187
+ rb_scan_args(argc,argv, "21", &vx,&vy,&vsym);
188
+ if (vsym!=Qnil) sym = NUM2INT(vsym);
189
+
190
+ x = rb_pgplot_fltary( vx );
191
+ y = rb_pgplot_fltary( vy );
192
+
193
+ cpgpt( min(NA_TOTAL(x),NA_TOTAL(y)), NA_PTR_FLT(x), NA_PTR_FLT(y), sym );
194
+
195
+ return Qtrue;
196
+ }
197
+
198
+ /* PGPNTS -- draw several graph markers, not all the same
199
+ pgpnts xarray, yarray, symarray
200
+ */
201
+ static VALUE
202
+ rb_pgplot_pgpnts( VALUE obj, VALUE vx, VALUE vy, VALUE vs )
203
+ {
204
+ VALUE x, y, s;
205
+
206
+ x = rb_pgplot_fltary( vx );
207
+ y = rb_pgplot_fltary( vy );
208
+ s = rb_pgplot_intary( vs );
209
+
210
+ cpgpnts( min(NA_TOTAL(x),NA_TOTAL(y)), NA_PTR_FLT(x), NA_PTR_FLT(y),
211
+ NA_PTR_INT(s), NA_TOTAL(s) );
212
+
213
+ return Qtrue;
214
+ }
215
+
216
+ /* PGBIN -- histogram of binned data
217
+ pgbin xarray, yarray [,center]
218
+ x : abscissae of bins.
219
+ y : data values of bins.
220
+ center : if true, the X values denote the center of the bin;
221
+ if false, the X values denote the lower edge (in X) of the bin.
222
+ */
223
+ static VALUE
224
+ rb_pgplot_pgbin( int argc, VALUE *argv, VALUE self )
225
+ {
226
+ VALUE vx, vy, vcent;
227
+ VALUE x, y;
228
+ int cent;
229
+
230
+ rb_scan_args(argc,argv, "21", &vx,&vy,&vcent);
231
+ if (RTEST(vcent)) cent=1; else cent=0;
232
+
233
+ x = rb_pgplot_fltary( vx );
234
+ y = rb_pgplot_fltary( vy );
235
+
236
+ cpgbin( min(NA_TOTAL(x),NA_TOTAL(y)), NA_PTR_FLT(x), NA_PTR_FLT(y), cent );
237
+
238
+ return Qtrue;
239
+ }
240
+
241
+ /* PGHIST -- histogram of unbinned data
242
+ pghist, data, nbin [,range, flag]
243
+ data : the data values. NBIN may not exceed 200.
244
+ nbin : the number of bins to use
245
+ range : the range for the histogram.
246
+ flag : = 0 PGENV is called automatically
247
+ = 1 the histogram is plotted in the current window.
248
+ = 2,3 with a filled area style.
249
+ = 4,5 simple line.
250
+ */
251
+ static VALUE
252
+ rb_pgplot_pghist( int argc, VALUE *argv, VALUE self )
253
+ {
254
+ VALUE vdat,vnbin,vrange,vflag;
255
+ VALUE na_dat;
256
+ int flag=0;
257
+ float range[2];
258
+
259
+ rb_scan_args(argc,argv, "22", &vdat,&vnbin,&vrange,&vflag);
260
+ na_dat = rb_pgplot_fltary( vdat );
261
+
262
+ /* Data Range */
263
+ if (vrange!=Qnil) {
264
+ range[0] = NUM2DBL(rb_funcall(vrange, id_beg, 0));
265
+ range[1] = NUM2DBL(rb_funcall(vrange, id_end, 0));
266
+ } else {
267
+ rb_pgplot_minmax(na_dat,range);
268
+ }
269
+ /* PGFLAG */
270
+ if (vflag!=Qnil) flag = NUM2INT(vflag);
271
+
272
+ cpghist( NA_TOTAL(na_dat), NA_PTR_FLT(na_dat),
273
+ range[0], range[1], NUM2INT(vnbin), flag );
274
+ return Qtrue;
275
+ }
276
+
277
+
278
+ /* Collection of Error bars
279
+ */
280
+ static void
281
+ rb_pgplot_errorbar( int argc, VALUE *argv, int callid, int dir )
282
+ {
283
+ VALUE v1,v2,v3,vt;
284
+ VALUE a1,a2,a3;
285
+ int size;
286
+ float tlen=1;
287
+
288
+ rb_scan_args(argc,argv, "31", &v1,&v2,&v3,&vt);
289
+ a1 = rb_pgplot_fltary( v1 );
290
+ a2 = rb_pgplot_fltary( v2 );
291
+ a3 = rb_pgplot_fltary( v3 );
292
+ size = min(NA_TOTAL(a1),NA_TOTAL(a2));
293
+ size = min(size,NA_TOTAL(a3));
294
+ if (vt!=Qnil) tlen = NUM2DBL(vt);
295
+
296
+ if (callid==1)
297
+ cpgerrx( size,
298
+ NA_PTR_FLT(a1), NA_PTR_FLT(a2), NA_PTR_FLT(a3),
299
+ tlen );
300
+ else if (callid==2)
301
+ cpgerry( size,
302
+ NA_PTR_FLT(a1), NA_PTR_FLT(a2), NA_PTR_FLT(a3),
303
+ tlen );
304
+ else
305
+ cpgerrb( dir, size,
306
+ NA_PTR_FLT(a1), NA_PTR_FLT(a2), NA_PTR_FLT(a3),
307
+ tlen );
308
+ }
309
+
310
+ /* PGERRB -- horizontal or vertical error bar
311
+ pgerrb, dir, x, y, err [,tlen]
312
+
313
+ dir : direction to plot the error bar relative to the data point.
314
+ One-sided error bar:
315
+ DIR is 1 for +X (X to X+E);
316
+ 2 for +Y (Y to Y+E);
317
+ 3 for -X (X to X-E);
318
+ 4 for -Y (Y to Y-E).
319
+ Two-sided error bar:
320
+ DIR is 5 for +/-X (X-E to X+E);
321
+ 6 for +/-Y (Y-E to Y+E).
322
+ x : world x-coordinates of the data.
323
+ y : world y-coordinates of the data.
324
+ err : value of error bar distance to be added to the
325
+ data position in world coordinates.
326
+ tlen: length of terminals to be drawn at the ends of the error bar,
327
+ as a multiple of the default length.
328
+ */
329
+ static VALUE
330
+ rb_pgplot_pgerrb( int argc, VALUE *argv, VALUE self )
331
+ {
332
+ rb_pgplot_errorbar( argc-1, argv+1, 0, NUM2INT(argv[0]) );
333
+ return Qtrue;
334
+ }
335
+
336
+ /* PGERRX -- horizontal error bar
337
+ pgerrx, x1, x2, y [,tlen]
338
+
339
+ x1 : world x-coordinates of lower end of the error bars.
340
+ x2 : world x-coordinates of upper end of the error bars.
341
+ */
342
+ static VALUE
343
+ rb_pgplot_pgerrx( int argc, VALUE *argv, VALUE self )
344
+ {
345
+ rb_pgplot_errorbar( argc, argv, 1, 0 );
346
+ return Qtrue;
347
+ }
348
+
349
+ /* PGERRY -- vertical error bar
350
+ pgerry, x, y1, y2 [,tlen]
351
+
352
+ y1 : world y-coordinates of top end of the error bars.
353
+ y2 : world y-coordinates of bottom end of the error bars.
354
+ */
355
+ static VALUE
356
+ rb_pgplot_pgerry( int argc, VALUE *argv, VALUE self )
357
+ {
358
+ rb_pgplot_errorbar( argc, argv, 2, 0 );
359
+ return Qtrue;
360
+ }
361
+
362
+
363
+ static float *
364
+ rb_pgplot_transform( VALUE val_tr )
365
+ {
366
+ static float tr_default[6] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
367
+ static float tr[6] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
368
+ VALUE na_tr;
369
+
370
+ /* Transform */
371
+ if (val_tr!=Qnil) {
372
+ na_tr = rb_pgplot_fltary( val_tr );
373
+ if (NA_TOTAL(na_tr) != 6)
374
+ rb_raise(rb_eArgError, "TR argument must be 6-elm (N)Array");
375
+ MEMCPY(tr, NA_PTR_FLT(na_tr), float, 6);
376
+ return tr;
377
+ } else {
378
+ return tr_default;
379
+ }
380
+ }
381
+
382
+ static void
383
+ rb_pgplot_find_range(VALUE na, VALUE vrange, float range[])
384
+ {
385
+ /* if Range class is set, extrant begin&end */
386
+ if (vrange!=Qnil) {
387
+ range[0] = NUM2DBL(rb_funcall(vrange, id_beg, 0));
388
+ range[1] = NUM2DBL(rb_funcall(vrange, id_end, 0));
389
+ } else {
390
+ /* if Range is not set, search min&max of array */
391
+ rb_pgplot_minmax(na,range);
392
+ }
393
+ }
394
+
395
+ /* contour routine collection */
396
+ static void
397
+ rb_pgplot_contour( int argc, VALUE *argv, int callid )
398
+ {
399
+ VALUE vmap, vtr, vcont, vblank, vtmp;
400
+ VALUE na_map, na_cont;
401
+ float blank=0, *tr;
402
+
403
+ rb_scan_args(argc, argv, "22", &vmap, &vcont, &vtr, &vblank );
404
+
405
+ if (callid==2) { /* for PGCONB */
406
+ /* Exchange */
407
+ vtmp=vblank; vblank=vtr; vtr=vtmp;
408
+ /* Blanking */
409
+ if (vblank!=Qnil) blank=NUM2DBL(vblank);
410
+ }
411
+
412
+ /* Map Data */
413
+ na_map = rb_pgplot_fltary( vmap );
414
+ if (NA_RANK(na_map) != 2)
415
+ rb_raise(rb_eArgError, "Image must be 2-D (N)Array");
416
+ /* Contour levels */
417
+ na_cont = rb_pgplot_fltary( vcont );
418
+
419
+ /* Transform */
420
+ tr = rb_pgplot_transform( vtr );
421
+ /* Show Contour */
422
+ if (callid==1)
423
+ cpgcons( NA_PTR_FLT(na_map), NA_SHAPE0(na_map), NA_SHAPE1(na_map),
424
+ 1, NA_SHAPE0(na_map), 1, NA_SHAPE1(na_map),
425
+ NA_PTR_FLT(na_cont), NA_TOTAL(na_cont), tr );
426
+ else if (callid==2)
427
+ cpgconb( NA_PTR_FLT(na_map), NA_SHAPE0(na_map), NA_SHAPE1(na_map),
428
+ 1, NA_SHAPE0(na_map), 1, NA_SHAPE1(na_map),
429
+ NA_PTR_FLT(na_cont), NA_TOTAL(na_cont), tr, blank );
430
+ else
431
+ cpgcont( NA_PTR_FLT(na_map), NA_SHAPE0(na_map), NA_SHAPE1(na_map),
432
+ 1, NA_SHAPE0(na_map), 1, NA_SHAPE1(na_map),
433
+ NA_PTR_FLT(na_cont), NA_TOTAL(na_cont), tr );
434
+ }
435
+
436
+ /* PGCONT -- contour map of a 2D data array (contour-following)
437
+ pgcont, map, cont [,tr]
438
+ map : 2-D array of map data
439
+ cont : array of contour levels
440
+ tr : transformation matrix between array grid and world coordinates.
441
+ */
442
+ static VALUE
443
+ rb_pgplot_pgcont( int argc, VALUE *argv, VALUE self )
444
+ {
445
+ rb_pgplot_contour( argc, argv, 0 );
446
+ return Qtrue;
447
+ }
448
+ /* PGCONS -- contour map of a 2D data array (fast algorithm)
449
+ pgcons, map, cont [,tr]
450
+ map : 2-D array of map data
451
+ cont : array of contour levels
452
+ tr : transformation matrix
453
+ */
454
+ static VALUE
455
+ rb_pgplot_pgcons( int argc, VALUE *argv, VALUE self )
456
+ {
457
+ rb_pgplot_contour( argc, argv, 1 );
458
+ return Qtrue;
459
+ }
460
+ /* PGCONB -- contour map of a 2D data array, with blanking
461
+ pgconb, map, cont [, blank, tr]
462
+ map : 2-D array of map data
463
+ cont : array of contour levels
464
+ tr : transformation matrix
465
+ blank : elements of array A that are equal to this value are blanked.
466
+ */
467
+ static VALUE
468
+ rb_pgplot_pgconb( int argc, VALUE *argv, VALUE self )
469
+ {
470
+ rb_pgplot_contour( argc, argv, 2 );
471
+ return Qtrue;
472
+ }
473
+
474
+ /* PGCONF -- fill between two contours
475
+ pgconf, map, cont_range [,tr]
476
+ map : 2-D array of map data
477
+ cont_range : range of two contour levels
478
+ tr : transformation matrix
479
+ */
480
+ static VALUE
481
+ rb_pgplot_pgconf( int argc, VALUE *argv, VALUE self )
482
+ {
483
+ VALUE vmap, vtr, vcont;
484
+ VALUE na_map;
485
+ float crange[2], *tr;
486
+
487
+ rb_scan_args(argc, argv, "21", &vmap, &vcont, &vtr );
488
+
489
+ /* Map Data */
490
+ na_map = rb_pgplot_fltary( vmap );
491
+ if (NA_RANK(na_map) != 2)
492
+ rb_raise(rb_eArgError, "Image must be 2-D (N)Array");
493
+ /* Contour range */
494
+ rb_pgplot_find_range( na_map, vcont, crange );
495
+ /* Transform */
496
+ tr = rb_pgplot_transform( vtr );
497
+ /* Show Contour */
498
+ cpgconf( NA_PTR_FLT(na_map), NA_SHAPE0(na_map), NA_SHAPE1(na_map),
499
+ 1, NA_SHAPE0(na_map), 1, NA_SHAPE1(na_map),
500
+ crange[0], crange[1], tr );
501
+ return Qtrue;
502
+ }
503
+
504
+ /* PGCONL -- label contour map of a 2D data array
505
+ pgconl, map, cont, label [,intval, minint, tr]
506
+ map : 2-D array of map data
507
+ cont : contour level tobe labeld
508
+ label : label string
509
+ intval : spacing along the contour between labels, in grid cells.
510
+ minint : contours that cross less than MININT cells will not be labelled.
511
+ tr : transformation matrix
512
+ */
513
+ static VALUE
514
+ rb_pgplot_pgconl( int argc, VALUE *argv, VALUE self )
515
+ {
516
+ VALUE vmap, vcnt, vlab, vint, vmin, vtr;
517
+ VALUE na_map;
518
+ float *tr;
519
+ int intval=20, minint=10; /* recomended default */
520
+
521
+ rb_scan_args(argc, argv, "33", &vmap,&vcnt,&vlab,&vint,&vmin,&vtr );
522
+
523
+ /* Map Data */
524
+ na_map = rb_pgplot_fltary( vmap );
525
+ if (NA_RANK(na_map) != 2)
526
+ rb_raise(rb_eArgError, "Image must be 2-D (N)Array");
527
+ /* spacing of labels */
528
+ if (vint!=Qnil) intval = NUM2INT(vint);
529
+ if (vmin!=Qnil) minint = NUM2INT(vmin);
530
+ /* Transform */
531
+ tr = rb_pgplot_transform( vtr );
532
+ /* Show Contour */
533
+ cpgconl( NA_PTR_FLT(na_map), NA_SHAPE0(na_map), NA_SHAPE1(na_map),
534
+ 1, NA_SHAPE0(na_map), 1, NA_SHAPE1(na_map),
535
+ NUM2DBL(vcnt), tr, StringValuePtr(vlab), intval, minint);
536
+ return Qtrue;
537
+ }
538
+
539
+
540
+ /* PGVECT -- vector map of a 2D data array, with blanking
541
+ pgvect, x, y [, scale, pos, tr, blank ]
542
+
543
+ x : horizontal component data array.
544
+ y : vertical component data array.
545
+ scale : scale factor for vector lengths, if 0.0, C will be
546
+ set so that the longest vector is equal to the
547
+ smaller of TR(2)+TR(3) and TR(5)+TR(6).
548
+ pos : vector positioning code.
549
+ <0 vector head positioned on coordinates
550
+ >0 vector base positioned on coordinates
551
+ =0 vector centered on the coordinates
552
+ tr : transformation matrix
553
+ blank : elements of arrays A or B that are exactly equal to
554
+ this value are ignored (blanked).
555
+ */
556
+ static VALUE
557
+ rb_pgplot_pgvect( int argc, VALUE *argv, VALUE self )
558
+ {
559
+ VALUE vx,vy,vscl,vpos,vtr,vblank;
560
+ VALUE na_x, na_y;
561
+ int pos=0;
562
+ float scale=0, blank=0, *tr;
563
+
564
+ rb_scan_args(argc, argv, "24", &vx,&vy,&vscl,&vpos,&vtr,&vblank);
565
+
566
+ /* Vector Data */
567
+ na_x = rb_pgplot_fltary( vx );
568
+ na_y = rb_pgplot_fltary( vy );
569
+ if (NA_RANK(na_x) != 2 || NA_RANK(na_y) != 2 )
570
+ rb_raise(rb_eArgError, "Vector arrays must be 2-D (N)Array");
571
+ if (NA_SHAPE0(na_x) != NA_SHAPE0(na_y) || NA_SHAPE1(na_x) != NA_SHAPE1(na_y) )
572
+ rb_raise(rb_eArgError, "Vector array sizes must be same");
573
+ /* Options */
574
+ if (vscl!=Qnil) scale = NUM2DBL(vscl);
575
+ if (vpos!=Qnil) pos = NUM2INT(vpos);
576
+ if (vblank!=Qnil) blank = NUM2DBL(vblank);
577
+ /* Transform */
578
+ tr = rb_pgplot_transform( vtr );
579
+ /* Show Contour */
580
+ cpgvect( NA_PTR_FLT(na_x), NA_PTR_FLT(na_y),
581
+ NA_SHAPE0(na_x), NA_SHAPE1(na_x),
582
+ 1, NA_SHAPE0(na_x), 1, NA_SHAPE1(na_x),
583
+ scale, pos, tr, blank );
584
+ return Qtrue;
585
+ }
586
+
587
+ /*
588
+ static void
589
+ rb_pgplot_palett()
590
+ {
591
+ float gl[2]={0.,1.};
592
+ float gr[2]={0.,1.};
593
+ float gg[2]={0.,1.};
594
+ float gb[2]={0.,1.};
595
+ float contra=1.0, bright=0.5;
596
+ cpgctab(gl, gr, gg, gb, 2, contra, bright);
597
+ }
598
+ */
599
+
600
+ /* collection of PGIMAG and PGGRAY
601
+ */
602
+ static VALUE
603
+ rb_pgplot_mapimage( int argc, VALUE *argv, VALUE self, int callid )
604
+ {
605
+ VALUE vimage, vtr, vrange;
606
+ VALUE na;
607
+ float range[2], *tr;
608
+
609
+ rb_scan_args(argc,argv, "12", &vimage, &vrange, &vtr );
610
+
611
+ /* Image */
612
+ na = rb_pgplot_fltary( vimage );
613
+ if (NA_RANK(na) != 2)
614
+ rb_raise(rb_eArgError, "Image must be 2-D (N)Array");
615
+ /* Transform */
616
+ tr = rb_pgplot_transform( vtr );
617
+ /* Range */
618
+ rb_pgplot_find_range(na, vrange, range);
619
+ /* Show Image */
620
+ /*rb_pgplot_palett();*/
621
+ if (callid==0)
622
+ cpgimag( NA_PTR_FLT(na), NA_SHAPE0(na), NA_SHAPE1(na),
623
+ 1, NA_SHAPE0(na), 1, NA_SHAPE1(na),
624
+ range[0], range[1], tr );
625
+ else
626
+ cpggray( NA_PTR_FLT(na), NA_SHAPE0(na), NA_SHAPE1(na),
627
+ 1, NA_SHAPE0(na), 1, NA_SHAPE1(na),
628
+ range[0], range[1], tr );
629
+ return Qtrue;
630
+ }
631
+
632
+
633
+ /* PGIMAG -- color image from a 2D data array
634
+ pgimag, array [,range ,tr]
635
+ range : range of array value to be drawn
636
+ TR : transformation matrix.
637
+ */
638
+ static VALUE
639
+ rb_pgplot_pgimag( int argc, VALUE *argv, VALUE self )
640
+ {
641
+ rb_pgplot_mapimage( argc, argv, self, 0 );
642
+ return Qtrue;
643
+ }
644
+ /* PGGRAY -- gray-scale map of a 2D data array
645
+ pggray, array [, range, tr]
646
+ range : range of array value to be drawn
647
+ TR : transformation matrix.
648
+ */
649
+ static VALUE
650
+ rb_pgplot_pggray( int argc, VALUE *argv, VALUE self )
651
+ {
652
+ rb_pgplot_mapimage( argc, argv, self, 1 );
653
+ return Qtrue;
654
+ }
655
+
656
+ /* PGCTAB -- install the color table to be used by PGIMAG
657
+ pgctab, l,r,g,b [,contra,bright]
658
+ l : An array of NC normalized ramp-intensity levels
659
+ corresponding to the RGB primary color intensities
660
+ in R(),G(),B(). Colors on the ramp are linearly
661
+ interpolated from neighbouring levels.
662
+ Levels must be sorted in increasing order.
663
+ 0.0 places a color at the beginning of the ramp.
664
+ 1.0 places a color at the end of the ramp.
665
+ Colors outside these limits are legal, but will
666
+ not be visible if CONTRA=1.0 and BRIGHT=0.5.
667
+ r,g,b : array of normalized red,green,blue intensities.
668
+ contra : The contrast of the color ramp (normally 1.0).
669
+ Negative values reverse the direction of the ramp.
670
+ bright : The brightness of the color ramp. This is normally 0.5
671
+ but can sensibly hold any value between 0.0 and 1.0.
672
+ */
673
+
674
+ static VALUE
675
+ rb_pgplot_pgctab( int argc, VALUE *argv, VALUE self )
676
+ {
677
+ VALUE vl, vr, vg, vb, vcnt, vbrt;
678
+ VALUE l, r, g, b;
679
+ float contra=1.0, bright=0.5;
680
+ int n;
681
+
682
+ rb_scan_args(argc,argv, "42", &vl,&vr,&vg,&vb,&vcnt,&vbrt);
683
+
684
+ l = rb_pgplot_fltary( vl );
685
+ r = rb_pgplot_fltary( vr );
686
+ g = rb_pgplot_fltary( vg );
687
+ b = rb_pgplot_fltary( vb );
688
+
689
+ /* Optional Args */
690
+ if (vcnt!=Qnil) contra = NUM2INT(vcnt);
691
+ if (vbrt!=Qnil) bright = NUM2INT(vbrt);
692
+
693
+ n = min(NA_TOTAL(l),NA_TOTAL(r));
694
+ n = min(NA_TOTAL(g),n);
695
+ n = min(NA_TOTAL(b),n);
696
+ cpgctab( NA_PTR_FLT(l), NA_PTR_FLT(r), NA_PTR_FLT(g), NA_PTR_FLT(b),
697
+ n, contra, bright);
698
+ return Qtrue;
699
+ }
700
+
701
+
702
+ /* PGWEDG -- annotate an image plot with a wedge
703
+ pgwedg side, disp, width, fg, bg, label
704
+ side : The first character must be one of the characters
705
+ 'B', 'L', 'T', or 'R' signifying the Bottom, Left,
706
+ Top, or Right edge of the viewport.
707
+ The second character should be 'I' to use PGIMAG
708
+ to draw the wedge, or 'G' to use PGGRAY.
709
+ disp : the displacement of the wedge from the specified
710
+ edge of the viewport, measured outwards from the
711
+ viewport in units of the character height. Use a
712
+ negative value to write inside the viewport, a
713
+ positive value to write outside.
714
+ width : The total width of the wedge including annotation,
715
+ in units of the character height.
716
+ fg : The value which is to appear with shade
717
+ 1 ("foreground"). Use the values of FG and BG
718
+ that were supplied to PGGRAY or PGIMAG.
719
+ bg : the value which is to appear with shade
720
+ 0 ("background").
721
+ label : Optional units label.
722
+ */
723
+
724
+
725
+ /*
726
+ PGPIXL -- draw pixels
727
+ pgpixl, array [,x1,x2,y1,y2]
728
+
729
+ x1, y1 : world coordinates of one corner of the output region
730
+ x2, y2 : world coordinates of the opposite corner of the output region
731
+ */
732
+
733
+ static VALUE
734
+ rb_pgplot_pgpixl( int argc, VALUE *argv, VALUE self )
735
+ {
736
+ VALUE na;
737
+ float x1, x2, y1, y2;
738
+
739
+ if (argc<1)
740
+ rb_raise(rb_eArgError, "wrong # of arguments (%d for 1 or 5)", argc);
741
+ na = rb_pgplot_intary(argv[0]);
742
+
743
+ if (NA_RANK(na) != 2)
744
+ rb_raise(rb_eArgError, "Image must be 2-D (N)Array");
745
+
746
+ if (argc==5) {
747
+ x1 = NUM2DBL(argv[1]);
748
+ x2 = NUM2DBL(argv[2]);
749
+ y1 = NUM2DBL(argv[3]);
750
+ y2 = NUM2DBL(argv[4]);
751
+ } else if (argc==1) {
752
+ x1 = 0;
753
+ x2 = NA_SHAPE0(na);
754
+ y1 = 0;
755
+ y2 = NA_SHAPE1(na);
756
+ } else
757
+ rb_raise(rb_eArgError, "wrong # of arguments (%d for 1 or 5)", argc);
758
+
759
+ cpgpixl( NA_PTR_INT(na), NA_SHAPE0(na), NA_SHAPE1(na),
760
+ 1, NA_SHAPE0(na), 1, NA_SHAPE1(na),
761
+ x1, x2, y1, y2 );
762
+ return Qtrue;
763
+ }
764
+
765
+
766
+
767
+ /* PGQINF -- inquire PGPLOT general information
768
+ value = pgqinf item
769
+ item : character string defining the information
770
+ value : character string containing the requested information.
771
+ */
772
+ static VALUE
773
+ rb_pgplot_pgqinf( VALUE obj, VALUE vitem )
774
+ {
775
+ int value_len=20;
776
+ char *item, *value;
777
+
778
+ item = StringValuePtr(vitem);
779
+ value = ALLOCA_N(char,value_len);
780
+ cpgqinf( item, value, &value_len );
781
+
782
+ return rb_str_new(value,value_len);
783
+ }
784
+
785
+ /* PGQDT -- inquire name of nth available device type
786
+ type, descr, inter = pgqdt [,ndev]
787
+ ndev : the number of the device type (1..maximum).
788
+ type : receives the character device-type code of the
789
+ Nth device type.
790
+ descr : receives a description of the device type.
791
+ inter : receives 1 if the device type is an interactive
792
+ one, 0 otherwise.
793
+ */
794
+ static VALUE
795
+ rb_pgplot_pgqdt( int argc, VALUE *argv, VALUE self )
796
+ {
797
+ VALUE vdev;
798
+ int ndev=1, type_len=9, descr_len=65, inter;
799
+ char *type, *descr;
800
+
801
+ type = ALLOCA_N(char,type_len);
802
+ descr = ALLOCA_N(char,descr_len);
803
+ rb_scan_args(argc, argv, "01", &vdev);
804
+ if (vdev!=Qnil) ndev = NUM2INT(vdev);
805
+ cpgqdt( ndev, type, &type_len, descr, &descr_len, &inter );
806
+
807
+ return rb_ary_new3( 3, rb_str_new(type,type_len),
808
+ rb_str_new(descr,descr_len),
809
+ INT2NUM(inter) );
810
+ }
811
+
812
+
813
+ /* PGQTXT -- find bounding box of text string
814
+ xbox, ybox = pgqtxt(x,y,angle,fjust,text)
815
+ */
816
+ static VALUE
817
+ rb_pgplot_pgqtxt(VALUE obj, VALUE x, VALUE y,
818
+ VALUE ang, VALUE fjust, VALUE text)
819
+ {
820
+ VALUE vx,vy;
821
+ int i;
822
+ float xbox[4], ybox[4];
823
+ char *txt = StringValuePtr(text);
824
+
825
+ cpgqtxt( NUM2DBL(x),NUM2DBL(y),NUM2DBL(ang),NUM2DBL(fjust),txt,
826
+ xbox, ybox );
827
+ vx = rb_ary_new2(4);
828
+ vy = rb_ary_new2(4);
829
+ for (i=0;i<4;i++) {
830
+ rb_ary_push(vx, rb_float_new(xbox[i]));
831
+ rb_ary_push(vy, rb_float_new(ybox[i]));
832
+ }
833
+ return rb_ary_new3(2,vx,vy);
834
+ }
835
+
836
+
837
+ /* Construct PgCursor-class instance */
838
+ static void pgcursor_init(VALUE obj, VALUE x, VALUE y, VALUE ch)
839
+ {
840
+ rb_ivar_set(obj, id_x, x);
841
+ rb_ivar_set(obj, id_y, y);
842
+ rb_ivar_set(obj, id_char, ch);
843
+ }
844
+
845
+ static VALUE pgcursor_initialize(int argc, VALUE *argv, VALUE obj)
846
+ {
847
+ VALUE x, y, ch;
848
+
849
+ rb_scan_args(argc,argv, "21", &x,&y,&ch);
850
+ pgcursor_init(obj,x,y,ch);
851
+ return Qnil;
852
+ }
853
+
854
+ static VALUE pgcursor_new(VALUE x, VALUE y, VALUE ch)
855
+ {
856
+ VALUE obj;
857
+
858
+ obj = rb_obj_alloc(cPgCursor);
859
+ pgcursor_init(obj,x,y,ch);
860
+ return obj;
861
+ }
862
+
863
+ static VALUE pgcursor_to_ary(VALUE obj)
864
+ {
865
+ return rb_ary_new3( 3, rb_ivar_get(obj, id_x),
866
+ rb_ivar_get(obj, id_y),
867
+ rb_ivar_get(obj, id_char) );
868
+ }
869
+
870
+
871
+ /*
872
+ PGCURS -- read cursor position
873
+ result = pgcurs([x,y])
874
+
875
+ PgCursorError is raised if some error occurs.
876
+
877
+ result : instance of PgCursor-class. Attrs are;
878
+ x : the world x-coordinate of the cursor.
879
+ y : the world y-coordinate of the cursor.
880
+ char : the character typed by the user;
881
+ nil if the device has no cursor or if some other error occurs.
882
+ */
883
+ static VALUE
884
+ rb_pgplot_pgcurs( int argc, VALUE *argv, VALUE self )
885
+ {
886
+ float x, y, x2, y2;
887
+ char ch[2] = " ";
888
+
889
+ switch (argc) {
890
+ case 0:
891
+ cpgqwin(&x,&x2,&y,&y2);
892
+ x = (x+x2)/2;
893
+ y = (y+y2)/2;
894
+ break;
895
+ case 2:
896
+ x = NUM2DBL(argv[0]);
897
+ y = NUM2DBL(argv[1]);
898
+ break;
899
+ default:
900
+ rb_raise(rb_eArgError, "wrong # of arguments (%d for 0 or 2)", argc);
901
+ }
902
+
903
+ if (!cpgcurs(&x, &y, ch))
904
+ rb_raise(ePgCursorError, "failure in getting cursor position");
905
+
906
+ return pgcursor_new( rb_float_new(x), rb_float_new(y),
907
+ (ch[0]==0) ? Qnil : rb_str_new(ch,1) );
908
+ }
909
+
910
+ /*
911
+ PGBAND -- read cursor position, with anchor
912
+ result = pgband( mode, [xref, yref, [x, y, [posn]]] )
913
+
914
+ PgCursorError is raised if some error occurs.
915
+
916
+ result : instance of PgCursor-class. see pgcurs.
917
+ */
918
+ static VALUE
919
+ rb_pgplot_pgband( int argc, VALUE *argv, VALUE self )
920
+ {
921
+ int mode=0, posn=0;
922
+ float x, y, xr, yr;
923
+ char ch[2] = " ";
924
+
925
+ if (argc<5) {
926
+ cpgqwin(&x,&xr,&y,&yr);
927
+ xr = x = (x+xr)/2;
928
+ yr = y = (y+yr)/2;
929
+ }
930
+ switch (argc) {
931
+ case 6:
932
+ if (RTEST(argv[5])) {
933
+ if (argv[5]==Qtrue)
934
+ posn = 1;
935
+ else
936
+ posn = NUM2INT(argv[5]);
937
+ }
938
+ case 5:
939
+ x = NUM2DBL(argv[3]);
940
+ y = NUM2DBL(argv[4]);
941
+ case 3:
942
+ xr = NUM2DBL(argv[1]);
943
+ yr = NUM2DBL(argv[2]);
944
+ case 1:
945
+ mode = NUM2INT(argv[0]);
946
+ break;
947
+ default:
948
+ rb_raise(rb_eArgError, "wrong # of arguments (%d for 1/3/5)", argc);
949
+ }
950
+
951
+ if (!cpgband(mode, posn, xr, yr, &x, &y, ch))
952
+ rb_raise(ePgCursorError, "failure in getting cursor position");
953
+
954
+ return pgcursor_new( rb_float_new(x), rb_float_new(y),
955
+ (ch[0]==0) ? Qnil : rb_str_new(ch,1) );
956
+ }
957
+
958
+
959
+ /*
960
+ PGOLIN -- mark a set of points using the cursor
961
+ result = pgolin( x, y, [sym, [npt]] )
962
+
963
+ x : NArray.sfloat of x-coordinates.
964
+ y : NArray.sfloat of y-coordinates.
965
+ sym : code number of symbol to use for marking entered points (see PGPT).
966
+ npt : number of points entered; should be zero on first call.
967
+
968
+ result: number of points entered.
969
+ */
970
+ static VALUE
971
+ rb_pgplot_pgolin( int argc, VALUE *argv, VALUE self )
972
+ {
973
+ VALUE x, y, vsym, vnpt;
974
+ int sym=0, npt=0;
975
+
976
+ rb_scan_args(argc,argv, "22", &x,&y,&vsym,&vnpt);
977
+ if (vsym!=Qnil) sym = NUM2INT(vsym);
978
+ if (vnpt!=Qnil) npt = NUM2INT(vnpt);
979
+
980
+ if (NA_TYPE(x)!=NA_SFLOAT || NA_TYPE(y)!=NA_SFLOAT)
981
+ rb_raise(rb_eArgError, "Array must NArray.sfloat");
982
+
983
+ cpgolin( min(NA_TOTAL(x),NA_TOTAL(y)), &npt,
984
+ NA_PTR_FLT(x), NA_PTR_FLT(y), sym );
985
+
986
+ return INT2NUM(npt);
987
+ }
988
+
989
+ /*
990
+ PGNCUR -- mark a set of points using the cursor
991
+ result = pgncur( x, y, [sym, [npt]] )
992
+
993
+ x : NArray.sfloat of x-coordinates.
994
+ y : NArray.sfloat of y-coordinates.
995
+ sym : code number of symbol to use for marking entered points (see PGPT).
996
+ npt : number of points entered; should be zero on first call.
997
+
998
+ result: number of points entered.
999
+ */
1000
+ static VALUE
1001
+ rb_pgplot_pgncur( int argc, VALUE *argv, VALUE self )
1002
+ {
1003
+ VALUE x, y, vsym, vnpt;
1004
+ int sym=0, npt=0;
1005
+
1006
+ rb_scan_args(argc,argv, "22", &x,&y,&vsym,&vnpt);
1007
+ if (vsym!=Qnil) sym = NUM2INT(vsym);
1008
+ if (vnpt!=Qnil) npt = NUM2INT(vnpt);
1009
+
1010
+ if (NA_TYPE(x)!=NA_SFLOAT || NA_TYPE(y)!=NA_SFLOAT)
1011
+ rb_raise(rb_eArgError, "Array must NArray.sfloat");
1012
+
1013
+ cpgncur( min(NA_TOTAL(x),NA_TOTAL(y)), &npt,
1014
+ NA_PTR_FLT(x), NA_PTR_FLT(y), sym );
1015
+
1016
+ return INT2NUM(npt);
1017
+ }
1018
+
1019
+ /*
1020
+ PGLCUR -- PGLCUR -- draw a line using the cursor
1021
+ result = pglcur( x, y, [npt] )
1022
+
1023
+ x : NArray.sfloat of x-coordinates.
1024
+ y : NArray.sfloat of y-coordinates.
1025
+ npt : number of points entered; should be zero on first call.
1026
+
1027
+ result: number of points entered.
1028
+ */
1029
+ static VALUE
1030
+ rb_pgplot_pglcur( int argc, VALUE *argv, VALUE self )
1031
+ {
1032
+ VALUE x, y, vnpt;
1033
+ int npt=0;
1034
+
1035
+ rb_scan_args(argc,argv, "21", &x,&y,&vnpt);
1036
+ if (vnpt!=Qnil) npt = NUM2INT(vnpt);
1037
+
1038
+ if (NA_TYPE(x)!=NA_SFLOAT || NA_TYPE(y)!=NA_SFLOAT)
1039
+ rb_raise(rb_eArgError, "Array must NArray.sfloat");
1040
+
1041
+ cpglcur( min(NA_TOTAL(x),NA_TOTAL(y)), &npt,
1042
+ NA_PTR_FLT(x), NA_PTR_FLT(y) );
1043
+
1044
+ return INT2NUM(npt);
1045
+ }
1046
+
1047
+
1048
+ void rb_scan_kw_args __((VALUE, ...));
1049
+
1050
+ /* PGTICK -- draw a single tick mark on an axis
1051
+ pgtick( x1, y1, x2, y2, v, [str], {"tickl", "tickr", "disp", "orient"})
1052
+
1053
+ Example:
1054
+ pgtick( 0,0,0,1, 0.5, "half", "tickr"=>1, "disp"=>2, "orient"=>90 )
1055
+
1056
+ Draw and label single tick mark on a graph axis. The tick mark is
1057
+ a short line perpendicular to the direction of the axis (which is not
1058
+ drawn by this routine). The optional text label is drawn with its
1059
+ baseline parallel to the axis and reading in the same direction as
1060
+ the axis (from point 1 to point 2). Current line and text attributes
1061
+ are used.
1062
+
1063
+ Arguments:
1064
+ X1, Y1 : world coordinates of one endpoint of the axis.
1065
+ X2, Y2 : world coordinates of the other endpoint of the axis.
1066
+ V : draw the tick mark at fraction V (0<=V<=1) along
1067
+ the line from (X1,Y1) to (X2,Y2).
1068
+ STR : text of label (may be blank).
1069
+ Keyword Arguments:
1070
+ TICKL : length of tick mark drawn to left of axis
1071
+ (as seen looking from first endpoint to second), in
1072
+ units of the character height.
1073
+ TICKR : length of major tick marks drawn to right of axis,
1074
+ in units of the character height.
1075
+ DISP : displacement of label text to
1076
+ right of axis, in units of the character height.
1077
+ ORIENT : orientation of label text, in degrees; angle between
1078
+ baseline of text and direction of axis (0-360 deg)
1079
+ */
1080
+
1081
+ static VALUE
1082
+ rb_pgplot_pgtick( int argc, VALUE *argv, VALUE self )
1083
+ {
1084
+ const char *str="";
1085
+ VALUE val=Qnil;
1086
+ VALUE x1, y1, x2, y2, v, vstr;
1087
+ VALUE tickl, tickr, disp, orient;
1088
+
1089
+ if (argc>0 && TYPE(argv[argc-1]) == T_HASH)
1090
+ val = argv[--argc];
1091
+ rb_scan_kw_args( val, "tickl", &tickl, "tickr", &tickr,
1092
+ "disp", &disp, "orient", &orient, (char *)0);
1093
+ rb_scan_args(argc,argv, "51", &x1,&y1, &x2,&y2, &v, &vstr);
1094
+
1095
+ if (tickl ==Qnil) tickl = INT2FIX(0);
1096
+ if (tickr ==Qnil) tickr = INT2FIX(0);
1097
+ if (disp ==Qnil) disp = INT2FIX(1);
1098
+ if (orient==Qnil) orient= INT2FIX(0);
1099
+ if (vstr !=Qnil) str = StringValuePtr(vstr);
1100
+
1101
+ cpgtick( NUM2DBL(x1),NUM2DBL(y1),NUM2DBL(x2),NUM2DBL(y2),
1102
+ NUM2DBL(v), NUM2DBL(tickl),NUM2DBL(tickr),
1103
+ NUM2DBL(disp), NUM2DBL(orient), str );
1104
+ return Qnil;
1105
+ }
1106
+
1107
+
1108
+ /*
1109
+ PGAXIS -- draw an axis
1110
+
1111
+ pgaxis( x1, y1, x2, y2, v1, v2,
1112
+ {opt, step, nsub, tickl, tickr, frac, disp, orient} )
1113
+ Example:
1114
+ pgaxis( 1, 1, 9, 5, 0, 3, "tickl"=>1, "opt"=>"NL2" )
1115
+
1116
+ Draw a labelled graph axis from world-coordinate position (X1,Y1) to
1117
+ (X2,Y2).
1118
+
1119
+ Normally, this routine draws a standard LINEAR axis with equal
1120
+ subdivisions. The quantity described by the axis runs from V1 to V2;
1121
+ this may be, but need not be, the same as X or Y.
1122
+
1123
+ If the 'L' option is specified, the routine draws a LOGARITHMIC axis.
1124
+ In this case, the quantity described by the axis runs from 10**V1 to
1125
+ 10**V2. A logarithmic axis always has major, labeled, tick marks
1126
+ spaced by one or more decades. If the major tick marks are spaced
1127
+ by one decade (as specified by the STEP argument), then minor
1128
+ tick marks are placed at 2, 3, .., 9 times each power of 10;
1129
+ otherwise minor tick marks are spaced by one decade. If the axis
1130
+ spans less than two decades, numeric labels are placed at 1, 2, and
1131
+ 5 times each power of ten.
1132
+
1133
+ If the axis spans less than one decade, or if it spans many decades,
1134
+ it is preferable to use a linear axis labeled with the logarithm of
1135
+ the quantity of interest.
1136
+
1137
+ Arguments:
1138
+ x1, y1 : world coordinates of one endpoint of the axis.
1139
+ x2, y2 : world coordinates of the other endpoint of the axis.
1140
+ v1 : axis value at first endpoint.
1141
+ v2 : axis value at second endpoint.
1142
+
1143
+ Keyword Argnuments:
1144
+ opt : a string containing single-letter codes for
1145
+ various options. The options currently
1146
+ recognized are:
1147
+ L : draw a logarithmic axis
1148
+ N : write numeric labels
1149
+ 1 : force decimal labelling, instead of automatic
1150
+ choice (see PGNUMB).
1151
+ 2 : force exponential labelling, instead of
1152
+ automatic.
1153
+ step : major tick marks are drawn at axis value 0.0 plus
1154
+ or minus integer multiples of STEP. If STEP=0.0,
1155
+ a value is chosen automatically.
1156
+ nsub : minor tick marks are drawn to divide the major
1157
+ divisions into NSUB equal subdivisions (ignored if
1158
+ STEP=0.0). If NSUB <= 1, no minor tick marks are
1159
+ drawn. NSUB is ignored for a logarithmic axis.
1160
+ tickl : length of major tick marks drawn to left of axis
1161
+ (as seen looking from first endpoint to second), in
1162
+ units of the character height.
1163
+ tickr : length of major tick marks drawn to right of axis,
1164
+ in units of the character height.
1165
+ frac : length of minor tick marks, as fraction of major.
1166
+ disp : displacement of baseline of tick labels to
1167
+ right of axis, in units of the character height.
1168
+ orient : orientation of label text, in degrees; angle between
1169
+ baseline of text and direction of axis (0-360
1170
+ */
1171
+
1172
+ static VALUE
1173
+ rb_pgplot_pgaxis( int argc, VALUE *argv, VALUE self )
1174
+ {
1175
+ const char *opt="";
1176
+ float frac=0.5;
1177
+ VALUE val=Qnil;
1178
+ VALUE x1, y1, x2, y2, v1, v2;
1179
+ VALUE vopt, step, nsub, tickl, tickr, vfrac, disp, orient;
1180
+
1181
+ if (argc>0 && TYPE(argv[argc-1]) == T_HASH)
1182
+ val = argv[--argc];
1183
+
1184
+ rb_scan_kw_args( val,
1185
+ "opt",&vopt, "step",&step, "nsub",&nsub,
1186
+ "tickl",&tickl, "tickr",&tickr,
1187
+ "frac",&vfrac, "disp",&disp, "orient",&orient, (char *)0);
1188
+ rb_scan_args(argc,argv, "60", &x1,&y1, &x2,&y2, &v1,&v2);
1189
+
1190
+ if (step ==Qnil) step = INT2FIX(0);
1191
+ if (nsub ==Qnil) nsub = INT2FIX(0);
1192
+ if (tickl ==Qnil) tickl = INT2FIX(0);
1193
+ if (tickr ==Qnil) tickr = INT2FIX(0);
1194
+ if (disp ==Qnil) disp = INT2FIX(1);
1195
+ if (orient==Qnil) orient= INT2FIX(0);
1196
+ if (vopt !=Qnil) opt = StringValuePtr(vopt);
1197
+ if (vfrac !=Qnil) frac = NUM2DBL(vfrac);
1198
+
1199
+ cpgaxis( opt, NUM2DBL(x1),NUM2DBL(y1),NUM2DBL(x2),NUM2DBL(y2),
1200
+ NUM2DBL(v1),NUM2DBL(v2),NUM2DBL(step),NUM2INT(nsub),
1201
+ NUM2DBL(tickl),NUM2DBL(tickr), frac,
1202
+ NUM2DBL(disp), NUM2DBL(orient) );
1203
+ return Qnil;
1204
+ }
1205
+
1206
+
1207
+ /*--- auto-generated funcs will be placed here ---*/
1208
+
1209
+
1210
+ void
1211
+ Init_pgplot()
1212
+ {
1213
+ mPgplot = rb_define_module("Pgplot");
1214
+ rb_define_const(mPgplot, "VERSION", rb_str_new2(RUBY_PGPLOT_VERSION));
1215
+
1216
+ /* The C application programming interface */
1217
+ rb_define_module_function(mPgplot, "pgopen", rb_pgplot_pgopen,-1);
1218
+ rb_define_module_function(mPgplot, "pgbeg", rb_pgplot_pgbeg, -1);
1219
+ rb_define_module_function(mPgplot, "pgenv", rb_pgplot_pgenv, -1);
1220
+ rb_define_module_function(mPgplot, "pgask", rb_pgplot_pgask, -1);
1221
+ rb_define_module_function(mPgplot, "pgline", rb_pgplot_pgline, 2);
1222
+ rb_define_module_function(mPgplot, "pgpoly", rb_pgplot_pgpoly, 2);
1223
+ rb_define_module_function(mPgplot, "pgpt", rb_pgplot_pgpt, -1);
1224
+ rb_define_module_function(mPgplot, "pgpnts", rb_pgplot_pgpnts, 3);
1225
+ rb_define_module_function(mPgplot, "pgbin", rb_pgplot_pgbin, -1);
1226
+ rb_define_module_function(mPgplot, "pghist", rb_pgplot_pghist, -1);
1227
+ rb_define_module_function(mPgplot, "pgerrb", rb_pgplot_pgerrb, -1);
1228
+ rb_define_module_function(mPgplot, "pgerrx", rb_pgplot_pgerrx, -1);
1229
+ rb_define_module_function(mPgplot, "pgerry", rb_pgplot_pgerry, -1);
1230
+ rb_define_module_function(mPgplot, "pgcont", rb_pgplot_pgcont, -1);
1231
+ rb_define_module_function(mPgplot, "pgcons", rb_pgplot_pgcons, -1);
1232
+ rb_define_module_function(mPgplot, "pgconb", rb_pgplot_pgconb, -1);
1233
+ rb_define_module_function(mPgplot, "pgconf", rb_pgplot_pgconf, -1);
1234
+ rb_define_module_function(mPgplot, "pgconl", rb_pgplot_pgconl, -1);
1235
+ rb_define_module_function(mPgplot, "pgvect", rb_pgplot_pgvect, -1);
1236
+ rb_define_module_function(mPgplot, "pgimag", rb_pgplot_pgimag, -1);
1237
+ rb_define_module_function(mPgplot, "pggray", rb_pgplot_pggray, -1);
1238
+ rb_define_module_function(mPgplot, "pgctab", rb_pgplot_pgctab, -1);
1239
+ rb_define_module_function(mPgplot, "pgpixl", rb_pgplot_pgpixl, -1);
1240
+ rb_define_module_function(mPgplot, "pgqinf", rb_pgplot_pgqinf, 1);
1241
+ rb_define_module_function(mPgplot, "pgqdt", rb_pgplot_pgqdt, -1);
1242
+ rb_define_module_function(mPgplot, "pgqtxt", rb_pgplot_pgqtxt, 5);
1243
+ rb_define_module_function(mPgplot, "pgcurs", rb_pgplot_pgcurs, -1);
1244
+ rb_define_module_function(mPgplot, "pgband", rb_pgplot_pgband, -1);
1245
+ rb_define_module_function(mPgplot, "pgolin", rb_pgplot_pgolin, -1);
1246
+ rb_define_module_function(mPgplot, "pgncur", rb_pgplot_pgncur, -1);
1247
+ rb_define_module_function(mPgplot, "pglcur", rb_pgplot_pglcur, -1);
1248
+ rb_define_module_function(mPgplot, "pgtick", rb_pgplot_pgtick, -1);
1249
+ rb_define_module_function(mPgplot, "pgaxis", rb_pgplot_pgaxis, -1);
1250
+
1251
+ /*--- auto-generated defs will be placed here ---*/
1252
+
1253
+ rb_set_end_proc((void(*)(VALUE))(cpgend), Qnil);
1254
+ id_beg = rb_intern("begin");
1255
+ id_end = rb_intern("end");
1256
+ id_x = rb_intern("@x");
1257
+ id_y = rb_intern("@y");
1258
+ id_char = rb_intern("@char");
1259
+
1260
+ /*--- PgCursor ---*/
1261
+ cPgCursor = rb_define_class_under(mPgplot, "PgCursor", rb_cObject);
1262
+ rb_define_method(cPgCursor, "initialize", pgcursor_initialize, -1);
1263
+ rb_define_method(cPgCursor, "to_ary", pgcursor_to_ary, 0);
1264
+ rb_attr(cPgCursor, rb_intern("x"), 1, 0, Qtrue);
1265
+ rb_attr(cPgCursor, rb_intern("y"), 1, 0, Qtrue);
1266
+ rb_attr(cPgCursor, rb_intern("char"), 1, 0, Qtrue);
1267
+ ePgCursorError = rb_define_class("PgCursorError", rb_eStandardError);
1268
+ }