1
2 /*
3 PGPLOT.xs
4
5 A few routines in C to speed up PDL access to PGPLOT primitives.
6
7 */
8
9 #include "EXTERN.h" /* std perl include */
10 #include "perl.h" /* std perl include */
11 #include "XSUB.h" /* XSUB include */
12 #include "ppport.h" /* for backwards comaptibility */
13
14 struct PGPLOT_function_handle {
15 I32 binversion;
16 void (*cpgmove) (float x, float y);
17 void (*cpgdraw) (float x, float y);
18 void (*cpgqcir) (int *icilo, int *icihi);
19 void (*cpgsci) (int ci);
20 void (*cpgpt1) (float x, float y, int sym);
21 };
22
23 typedef struct PGPLOT_function_handle PGPLOT_function_handle;
24
25 static I32 PGPLOT_structure_version = 20000302; /* The date the PGPLOT structure changed */
26 static PGPLOT_function_handle *myhandle;
27 SV *ptr;
28
29 MODULE = PDL::Graphics::PGPLOT::Window PACKAGE = PDL::Graphics::PGPLOT::Window
30
31 void
pggapline(n,msgval,xpts,ypts)32 pggapline(n,msgval,xpts,ypts)
33 int n
34 float msgval
35 float * xpts
36 float * ypts
37 CODE:
38 { int i;
39 int start = 0;
40 while (xpts[start] == msgval) start++; /* make sure we have a good starting point */
41 myhandle->cpgmove (xpts[start], ypts[start]);
42 for (i=start+1;i<n;i++) {
43 if (ypts[i] == msgval) {
44 /* check we are not at end of array and we don't move to a missing value */
45 if (i != n-1 && ypts[i+1] != msgval) {
46 myhandle->cpgmove (xpts[i+1], ypts[i+1]);
47 }
48 }
49 else {
50 myhandle->cpgdraw (xpts[i], ypts[i]);
51 }
52 }
53 }
54
55
56
57 void
pgcolorpnts(n,x,y,z,sym)58 pgcolorpnts(n,x,y,z,sym)
59 int n
60 float * x
61 float * y
62 float * z
63 int sym
64 CODE:
65 {
66 /* find range of color pallette */
67 int icilo, icihi, i, cirange, ci;
68 float minz, maxz, zrange;
69
70 /* If the structure read from the PGPLOT module is too old */
71 if (myhandle->binversion < PGPLOT_structure_version) {
72 char msg[128];
73 sprintf (msg, "This function requires PGPLOT with a structure version at least %d.\nPlease upgrade your PGPLOT package.",
74 PGPLOT_structure_version);
75
76 Perl_croak(aTHX_ "%s", msg);
77 }
78
79 myhandle->cpgqcir(&icilo, &icihi);
80
81 /* find min and max values of zpts variable */
82 minz = 9.99e30;
83 maxz = -9.99e30;
84 for (i=0;i<n;i++) {
85 if (z[i] < minz) minz = z[i];
86 if (z[i] > maxz) maxz = z[i];
87 }
88
89 /* determine range of available z indices and range of input 'z' values */
90 cirange = icihi - icilo;
91 zrange = maxz - minz;
92
93 /* printf ("cilo = %d, cihi = %d\n", icilo, icihi); */
94
95 /* for each input point, compute a scaled color index and plot the point */
96 for (i=0;i<n;i++) {
97 ci = (int)(icilo + (z[i] - minz) * (float)(cirange/zrange));
98 /* printf ("x = %f, y = %f, ci = %d\n", x[i], y[i], ci); */
99 myhandle->cpgsci(ci);
100 myhandle->cpgpt1(x[i], y[i], sym);
101 }
102 }
103
104
105
106 BOOT:
107
108 /* Get pointer to structure of core shared C routines */
109 ptr = get_sv("PGPLOT::HANDLE",FALSE | GV_ADDMULTI); /* SV* value */
110 #ifndef aTHX_
111 #define aTHX_
112 #endif
113 if (ptr==NULL)
114 Perl_croak(aTHX_ "This module requires PGPLOT version 2.16 or later.\nPlease install/upgrade PGPLOT (see the PDL/DEPENDENCIES file).");
115 myhandle = INT2PTR(PGPLOT_function_handle*,SvIV( ptr ));
116
117
118
119