1 /*
2 * Copyright (c) 1996-2000 Lucent Technologies.
3 * See README file for details.
4 *
5 *
6 * print a plot structure in the format of various graph packages
7 */
8
9 #include "local.h"
10
11 #ifdef CVERSION
12
13 #define XCON(x) (INT)(i0+(i1-i0)*(x-px[0])/(px[1]-px[0]))
14 #define YCON(y) (INT)(k0+(k1-k0)*(y-py[0])/(py[1]-py[0]))
15
16 extern double sin(), cos(), sqrt(), atan2(), ceil(), floor(), log10(), pow();
17 static INT i0, i1, k0, k1, cw, ch;
18 #ifdef YAWN
19 static FILE *plf;
20 #endif
21 extern INT curwin, lfcm[10];
22
23 #ifdef NOPIPES
popen(const char * cmd,const char * mode)24 FILE *popen(const char *cmd,const char *mode) { return(NULL); }
pclose(FILE * file)25 int pclose(FILE *file) { return(0); }
26 #endif
27
28 extern device devps, devwin;
29
f2(fmt)30 char f2(fmt)
31 char *fmt;
32 { char *z;
33 z = strchr(fmt,',');
34 if (z==NULL) return('d');
35 z++;
36 return(*z);
37 }
38
pretty(xl,k,z)39 INT pretty(xl,k,z)
40 double *xl, *z;
41 INT k;
42 { double dlt, m;
43 INT i, j, u;
44 if (k<=0) return(0);
45 dlt = (xl[1]-xl[0])/k;
46 m = floor(log10(dlt));
47 dlt *= pow(10.0,-m);
48 if (dlt<2) u = 2;
49 else if (dlt<5) u = 5;
50 else { u = 1; m++; } /* increments should be u*10^m; */
51 dlt = u*pow(10.0,m);
52 i = (INT)ceil(xl[0]/dlt);
53 j = 0;
54 while ((j<k) && ((i+j)*dlt<=xl[1]))
55 { z[j] = (i+j)*dlt;
56 j++;
57 }
58 return(j);
59 }
60
isgrid(xyz)61 void isgrid(xyz)
62 plxyz *xyz;
63 { INT i, n;
64 vari *x, *y, *z;
65 x = xyz->x; y = xyz->y; z = xyz->z;
66 if ((x!=NULL) & (y!=NULL) & (z!=NULL))
67 { if ((x->n*y->n)==z->n)
68 { xyz->nx = x->n;
69 xyz->ny = y->n;
70 xyz->n = z->n;
71 xyz->t = 1;
72 return;
73 }
74 if ((x->n>1) & (y->n>1))
75 { i = 0; n = z->n;
76 while ((i<y->n) && (vitem(y,0)==vitem(y,i))) i++;
77 if ((i>1) && (i*(n/i)==n))
78 { xyz->nx = n/i;
79 xyz->ny = i;
80 xyz->n = n;
81 xyz->t = 1;
82 return;
83 }
84 }
85 }
86 xyz->t = 0;
87 xyz->n = 0;
88 if ((x!=NULL) && (x->n>xyz->n)) xyz->n = x->n;
89 if ((y!=NULL) && (y->n>xyz->n)) xyz->n = y->n;
90 if ((z!=NULL) && (z->n>xyz->n)) xyz->n = z->n;
91 }
92
getxyzitem(x,xyz,i)93 void getxyzitem(x,xyz,i)
94 plxyz *x;
95 double xyz[3];
96 int i;
97 { xyz[0] = vitem(x->x,i);
98 if (x->t==1)
99 xyz[1] = vitem(x->y,i/x->x->n);
100 else
101 xyz[1] = vitem(x->y,i);
102 xyz[2] = vitem(x->z,i);
103 }
104
105 static double xl[2], yl[2], zl[2], px[2], py[2];
106
project(z,x,theta,phi)107 void project(z,x,theta,phi)
108 double *z, *x, theta, phi;
109 { double z0, z1, z2;
110 z0 = (z[0]-xl[0])/(xl[1]-xl[0]);
111 z1 = (z[1]-yl[0])/(yl[1]-yl[0]);
112 z2 = (z[2]-zl[0])/(zl[1]-zl[0]);
113 x[0] = cos(theta)*z0-sin(theta)*z1;
114 x[1] = (sin(theta)*z0+cos(theta)*z1)*cos(phi)+sin(phi)*z2;
115 }
116
iproject(z,i,theta,phi)117 void iproject(z,i,theta,phi)
118 double *z, theta, phi;
119 INT *i;
120 { double x[2];
121 project(z,x,theta,phi);
122 i[0] = XCON(x[0]); i[1] = YCON(x[1]);
123 }
124
line3d(z1,z2,theta,phi,dev,col)125 void line3d(z1,z2,theta,phi,dev,col)
126 double *z1, *z2, theta, phi;
127 device *dev;
128 INT col;
129 { INT x1[2], x2[2];
130 iproject(z1,x1,theta,phi);
131 iproject(z2,x2,theta,phi);
132 dev->SetColor(lfcm[col]);
133 dev->DrawLine(x1[0],x1[1],x2[0],x2[1]);
134 }
135
xyztext(tx,x,ah,av,theta,phi,dev,col)136 void xyztext(tx,x,ah,av,theta,phi,dev,col)
137 double *x, theta, phi;
138 INT ah, av, col;
139 char *tx;
140 device *dev;
141 { INT xy[2];
142 iproject(x,xy,theta,phi);
143 dev->SetColor(lfcm[col]);
144 dev->DoText(0,xy[0],xy[1],tx,ah,av);
145 }
146
getgreylevel(z)147 int getgreylevel(z)
148 double z;
149 { int c;
150 c = 8+11*(z-zl[0])/(zl[1]-zl[0]);
151 if (c<8) return(8);
152 if (c>18)return(18);
153 return(c);
154 }
155
points3d(x,theta,phi,dev,type)156 void points3d(x,theta,phi,dev,type)
157 plxyz *x;
158 double theta, phi;
159 char type;
160 device *dev;
161 { INT i, xy[2];
162 double xyz[3];
163 for (i=0; i<x->n; i++)
164 {
165 getxyzitem(x,xyz,i);
166 iproject(xyz,xy,theta,phi);
167 if (type=='q')
168 dev->SetColor(getgreylevel(xyz[2]));
169 else
170 dev->SetColor(lfcm[CPOI]);
171 dev->DrawPoint(xy[0],xy[1],x->pch);
172 }
173 }
174
lines3d(xyz,theta,phi,dev)175 void lines3d(xyz,theta,phi,dev)
176 plxyz *xyz;
177 double theta, phi;
178 device *dev;
179 { INT i;
180 double x0[3], x1[3];
181 getxyzitem(xyz,x0,0);
182 for (i=1; i<xyz->n; i++)
183 { if (i&1)
184 { getxyzitem(xyz,x1,i);
185 line3d(x0,x1,theta,phi,dev,CLIN);
186 }
187 else
188 { getxyzitem(xyz,x0,i);
189 line3d(x1,x0,theta,phi,dev,CLIN);
190 }
191 }
192 }
193
segments(xyz0,xyz1,theta,phi,dev)194 void segments(xyz0,xyz1,theta,phi,dev)
195 plxyz *xyz0, *xyz1;
196 double theta, phi;
197 device *dev;
198 { INT i, n;
199 double x0[3], x1[3];
200 n = xyz0->n;
201 if (xyz1->n>n) n = xyz1->n;
202 for (i=0; i<n; i++)
203 { getxyzitem(xyz0,x0,i);
204 getxyzitem(xyz1,x1,i);
205 line3d(x0,x1,theta,phi,dev,CSEG);
206 }
207 }
208
spl(z0,z1)209 double spl(z0,z1)
210 double z0, z1;
211 { if (z0-z1==0.0) return(0.5);
212 return(z0/(z0-z1));
213 }
214
contour3d(x,theta,phi,dev,sl,nsl)215 void contour3d(x,theta,phi,dev,sl,nsl)
216 plxyz *x;
217 double theta, phi, *sl;
218 INT nsl;
219 device *dev;
220 { INT i, j, k, nx, ny, s;
221 double xyz[4][3], u[4], x0[3], x1[3], x2[3], x3[3], r;
222 char lb[20];
223 if (x->t==0) ERROR(("Contour: not a grid"));
224 if (lf_error) return;
225 if (nsl==0) nsl = pretty(zl,10,sl);
226 nx = x->nx; ny = x->ny;
227 for (k=0; k<nsl; k++)
228 { x0[2] = x1[2] = x2[2] = x3[2] = sl[k];
229 for (i=0; i<nx-1; i++)
230 for (j=0; j<ny-1; j++)
231 { sprintf(lb,"%g",sl[k]);
232 getxyzitem(x,xyz[0],i+j*nx);
233 getxyzitem(x,xyz[1],(i+1)+j*nx);
234 getxyzitem(x,xyz[2],i+(j+1)*nx);
235 getxyzitem(x,xyz[3],i+1+(j+1)*nx);
236 u[0] = xyz[0][2]-sl[k];
237 u[1] = xyz[1][2]-sl[k];
238 u[2] = xyz[2][2]-sl[k];
239 u[3] = xyz[3][2]-sl[k];
240 if (u[0]*u[1]<=0) /* bottom of cell */
241 { r = spl(u[0],u[1]);
242 x0[0] = (1-r)*xyz[0][0]+r*xyz[1][0];
243 x0[1] = xyz[0][1];
244 if (j==0) xyztext(lb,x0,-1,-1,theta,phi,dev,CCLA);
245 }
246 if (u[1]*u[3]<=0) /* right of cell */
247 { r = spl(u[1],u[3]);
248 x1[0] = xyz[1][0];
249 x1[1] = (1-r)*xyz[1][1]+r*xyz[3][1];
250 if (i==nx-2) xyztext(lb,x1,-1,0,theta,phi,dev,CCLA);
251 }
252 if (u[2]*u[3]<=0) /* top of cell */
253 { r = spl(u[2],u[3]);
254 x2[0] = (1-r)*xyz[2][0]+r*xyz[3][0];
255 x2[1] = xyz[2][1];
256 if (j==ny-2) xyztext(lb,x2,-1,1,theta,phi,dev,CCLA);
257 }
258 if (u[0]*u[2]<=0) /* left of cell */
259 { r = spl(u[0],u[2]);
260 x3[0] = xyz[0][0];
261 x3[1] = (1-r)*xyz[0][1]+r*xyz[2][1];
262 if (i==0) xyztext(lb,x3,-1,0,theta,phi,dev,CCLA);
263 }
264
265 s = 8*(u[3]>0)+4*(u[2]>0)+2*(u[1]>0)+(u[0]>0);
266 switch(s)
267 { case 0:
268 case 15: break;
269 case 1:
270 case 14:
271 line3d(x0,x3,theta,phi,dev,CCON);
272 break;
273 case 2:
274 case 13:
275 line3d(x0,x1,theta,phi,dev,CCON);
276 break;
277 case 3:
278 case 12:
279 line3d(x3,x1,theta,phi,dev,CCON);
280 break;
281 case 4:
282 case 11:
283 line3d(x3,x2,theta,phi,dev,CCON);
284 break;
285 case 5:
286 case 10:
287 line3d(x0,x2,theta,phi,dev,CCON);
288 break;
289 case 6:
290 case 9:
291 line3d(x0,x1,theta,phi,dev,CCON);
292 break;
293 case 7:
294 case 8:
295 line3d(x1,x2,theta,phi,dev,CCON);
296 break;
297 default: ERROR(("severe contouring error..."));
298 }
299 }
300 }
301 }
302
angle(x0,x1,x2)303 double angle(x0,x1,x2) /* rotation angle from (x0,x1) to (x0,x2) */
304 double *x0, *x1, *x2;
305 /* If x0=0, ||x1=1|| then express
306 x2 = u x1 + v y1 where y1=(-x11,x10) = 90 deg anticlk rot.
307 i.e. u = <x1,x2> v = <y1,x2>
308 tan(theta) = v/u
309 atan2(v,u) returns positive for anticlkws rot;
310 negative for clockwise rot.
311 */
312 { double u, v;
313 u = (x1[0]-x0[0])*(x2[0]-x0[0]) + (x1[1]-x0[1])*(x2[1]-x0[1]);
314 v = -(x1[1]-x0[1])*(x2[0]-x0[0]) + (x1[0]-x0[0])*(x2[1]-x0[1]);
315 return(atan2(v,u));
316 }
317
persp3d(xyz,theta,phi,DP,sl,nsl)318 void persp3d(xyz,theta,phi,DP,sl,nsl)
319 plxyz *xyz;
320 double theta, phi, *sl;
321 void (*DP)();
322 INT nsl;
323 { INT i, j, k, m, nx, ny, ii, jj, cb, cp, cx[4], cy[4], xhi, yhi;
324 double u[4][3], w[4][2], r;
325 if (xyz->t==0) ERROR(("persp3d: not a grid"));
326 if (lf_error) return;
327 /* theta=135 --- 225
328 | |
329 45 --- 315;
330 i.e start at top right for theta=45 e.t.c. Reverse if sin(phi)<0.
331 x starts hi if cos(theta)>0
332 y starts hi if sin(theta)>0
333 */
334 xhi = (cos(theta)*sin(phi)) > 0;
335 yhi = (sin(theta)*sin(phi)) > 0;
336 nx = xyz->nx; ny = xyz->ny;
337 for (i=0; i<nx-1; i++)
338 for (j=0; j<ny-1; j++)
339 { for (k=0; k<4; k++)
340 { /* 1 -- 2
341 | |
342 0 -- 3 */
343 ii = (xhi) ? nx-2-i : i;
344 jj = (yhi) ? ny-2-j : j;
345 ii += (k>1);
346 jj += (k==1)+(k==2);
347 m = jj*nx+ii;
348 getxyzitem(xyz,u[k],m);
349 project(u[k],w[k],theta,phi);
350 cx[k] = XCON(w[k][0]); cy[k] = YCON(w[k][1]);
351 }
352
353 switch(xyz->type)
354 { case 'w':
355 /* wireframe:
356 from top, use color CPA1 for border, CPA2 for patch
357 angles are anti-clock from top; r approx 2pi
358 clock from bot; r approx -2pi
359 */
360 r = angle(w[0],w[3],w[1])+angle(w[1],w[0],w[2])
361 +angle(w[2],w[1],w[3])+angle(w[3],w[2],w[0]);
362 if (r>0) { cb = lfcm[CPA1]; cp = lfcm[CPA2]; }
363 else { cp = lfcm[CPA1]; cb = lfcm[CPA2]; }
364 DP(cx,cy,cp,cb);
365 break;
366 case 'i': /* image */
367 if (nsl==0) nsl = pretty(zl,10,sl);
368 r = u[0][2] + u[1][2] + u[2][2] + u[3][2];
369 cb = cp = getgreylevel(r/4);
370 DP(cx,cy,cp,cb);
371 break;
372 }
373 }
374 }
375
updatelim(v,xl)376 void updatelim(v,xl)
377 vari *v;
378 double *xl;
379 { INT i;
380 if ((v==NULL) || (vlength(v)==0)) return;
381 if (xl[0]==xl[1])
382 xl[0] = xl[1] = vitem(v,0);
383 for (i=0; i<vlength(v); i++)
384 { if (vitem(v,i)<xl[0]) xl[0] = vitem(v,i);
385 if (vitem(v,i)>xl[1]) xl[1] = vitem(v,i);
386 }
387 }
388
axis(z1,z2,zl,lab,theta,phi,a,s,dev)389 void axis(z1,z2,zl,lab,theta,phi,a,s,dev)
390 double *z1, *z2, *zl, theta, phi;
391 char *lab;
392 INT a, s;
393 device *dev;
394 { double x1[3], x2[3], z[50];
395 INT i, u0, u1, v0, v1, n, horiz;
396 char lb[20];
397 dev->SetColor(lfcm[CAXI]);
398 project(z1,x1,theta,phi);
399 project(z2,x2,theta,phi);
400 u0 = XCON(x1[0]); v0 = XCON(x2[0]);
401 u1 = YCON(x1[1]); v1 = YCON(x2[1]);
402 horiz = abs(v0-u0)>abs(v1-u1);
403 dev->DrawLine(u0,u1,v0,v1);
404 n = (INT)sqrt((double)((v0-u0)*(v0-u0)+(v1-u1)*(v1-u1)))/((horiz) ? 5*cw : 2*ch);
405 if (n>50) n = 50;
406 n = pretty(zl,n,z);
407 if (n==0) return;
408 x1[0] = z1[0]; x1[1] = z1[1]; x1[2] = z1[2];
409 if (abs(v0-u0)>abs(v1-u1)) /* horizontal axis */
410 { dev->SetColor(lfcm[CTEX]);
411 if (lab!=NULL)
412 dev->DoText(0,(u0+v0)/2,(u1+v1)/2+s*(dev->ticklength+ch),lab,0,s);
413 for (i=0; i<n; i++)
414 { x1[a] = z[i];
415 project(x1,x2,theta,phi);
416 u0 = XCON(x2[0]); u1 = YCON(x2[1]);
417 v0 = u0; v1 = u1+s*dev->ticklength;
418 sprintf(lb,"%g",z[i]);
419 dev->SetColor(lfcm[CAXI]);
420 dev->DrawLine(u0,u1,v0,v1);
421 dev->SetColor(lfcm[CTEX]);
422 dev->DoText(0,v0,v1,lb,0,s);
423 } }
424 else /* vertical axis */
425 { s = 2*((2*v0)>(i0+i1))-1;
426 dev->SetColor(lfcm[CTEX]);
427 if (lab!=NULL)
428 dev->DoText(0,v0,v1-ch,lab,-s,-1);
429 for (i=0; i<n; i++)
430 { x1[a] = z[i];
431 project(x1,x2,theta,phi);
432 u0 = XCON(x2[0]); u1 = YCON(x2[1]);
433 v0 = u0+s*dev->ticklength; v1 = u1;
434 sprintf(lb,"%g",z[i]);
435 dev->SetColor(lfcm[CAXI]);
436 dev->DrawLine(u0,u1,v0,v1);
437 dev->SetColor(lfcm[CTEX]);
438 dev->DoText(0,v0,v1,lb,-s,0);
439 } }
440 }
441
plotxwin(pl,dev,wn,w,h,rd)442 void plotxwin(pl,dev,wn,w,h,rd)
443 plots *pl;
444 device *dev;
445 INT wn, w, h, rd;
446 { INT i, j, k, s;
447 double z[3], z2[3], xx[2], vx, vy, vz;
448 static double theta, phi;
449 plxyz *xyz;
450 if (pl->ty==PLNONE) return;
451 if (h<=0) h = dev->defth;
452 if (w<=0) w = dev->deftw;
453 if (!dev->makewin(&w,&h,wn,rd)) return;
454 dev->TextDim(0,"0",&cw,&ch);
455 i0 = 4*cw+dev->ticklength; i1 = w-2*cw;
456 k0 = h-3*ch-dev->ticklength; k1 = 3*ch;
457 dev->ClearScreen(lfcm[CBAK]);
458 if (pl->xl[0]<pl->xl[1])
459 { xl[0] = pl->xl[0]; xl[1] = pl->xl[1]; }
460 else
461 { xl[0] = xl[1] = 0.0;
462 for (i=0; i<pl->xyzs->n; i++)
463 { xyz = (plxyz *)viptr(pl->xyzs,i);
464 updatelim(xyz->x,xl);
465 }
466 if (xl[0]==xl[1]) { xl[0] -= 0.5; xl[1] += 0.5; }
467 }
468 if (pl->yl[0]<pl->yl[1])
469 { yl[0] = pl->yl[0]; yl[1] = pl->yl[1]; }
470 else
471 { yl[0] = yl[1] = 0.0;
472 for (i=0; i<pl->xyzs->n; i++)
473 { xyz = (plxyz *)viptr(pl->xyzs,i);
474 updatelim(xyz->y,yl);
475 }
476 if (yl[0]==yl[1]) { yl[0] -= 0.5; yl[1] += 0.5; }
477 }
478 if (pl->zl[0]<pl->zl[1])
479 { zl[0] = pl->zl[0]; zl[1] = pl->zl[1]; }
480 else
481 { zl[0] = zl[1] = 0.0;
482 for (i=0; i<pl->xyzs->n; i++)
483 { xyz = (plxyz *)viptr(pl->xyzs,i);
484 updatelim(xyz->z,zl);
485 }
486 if (zl[0]==zl[1]) { zl[0] -= 0.5; zl[1] += 0.5; }
487 }
488 theta = pl->theta*PI/180; phi = pl->phi*PI/180;
489 vx = -sin(theta)*sin(phi);
490 vy = -cos(theta)*sin(phi);
491 vz = cos(phi);
492
493 for (i=0; i<2; i++)
494 for (j=0; j<2; j++)
495 for (k=0; k<2; k++)
496 { z[0] = xl[i]; z[1] = yl[j]; z[2] = zl[k];
497 project(z,xx,theta,phi);
498 if ((i+j+k==0) | (xx[0]<px[0])) px[0]=xx[0];
499 if ((i+j+k==0) | (xx[0]>px[1])) px[1]=xx[0];
500 if ((i+j+k==0) | (xx[1]<py[0])) py[0]=xx[1];
501 if ((i+j+k==0) | (xx[1]>py[1])) py[1]=xx[1];
502 }
503 s = 1-2*((cos(phi)<0)^(sin(phi)<0));
504 z[0] = xl[0]; z2[0] = xl[1];
505 z[1] = z2[1] = yl[(cos(theta)<0)^(sin(phi)<0)];
506 z[2] = z2[2] = zl[cos(phi)<0];
507 axis(z,z2,xl,pl->xlab,theta,phi,0,s,dev);
508 z[0] = z2[0] = xl[(sin(theta)<0)^(sin(phi)<0)];
509 z[1] = yl[0]; z2[1] = yl[1];
510 z[2] = z2[2] = zl[cos(phi)<0];
511 axis(z,z2,yl,pl->ylab,theta,phi,1,s,dev);
512 z[0] = z2[0] = xl[cos(theta)<0];
513 z[1] = z2[1] = yl[sin(theta)>0];
514 z[2] = zl[0]; z2[2] = zl[1];
515 axis(z,z2,zl,pl->zlab,theta,phi,2,s,dev);
516 if (strlen(pl->main)>0) dev->DoText(1,(i0+i1)/2,2*ch,pl->main,0,-1);
517
518 for (i=0; i<pl->xyzs->n; i++)
519 { xyz = viptr(pl->xyzs,i);
520 isgrid(xyz);
521 switch (xyz->type)
522 { case 'c':
523 contour3d(xyz,theta,phi,dev,pl->sl,pl->nsl);
524 break;
525 case 'i':
526 persp3d(xyz,theta,phi,dev->DrawPatch,pl->sl,pl->nsl);
527 break;
528 case 'b':
529 points3d(xyz,theta,phi,dev,'p');
530 case 'l':
531 lines3d(xyz,theta,phi,dev);
532 break;
533 case 'p':
534 points3d(xyz,theta,phi,dev,'p');
535 break;
536 case 'q':
537 points3d(xyz,theta,phi,dev,'q');
538 break;
539 case 's':
540 if (i==0) { ERROR(("invalid segements")); }
541 else
542 segments(viptr(pl->xyzs,i-1),xyz,theta,phi,dev);
543 break;
544 case 'w':
545 persp3d(xyz,theta,phi,dev->DrawPatch,pl->sl,pl->nsl);
546 break;
547 } }
548
549 dev->wrapup(rd);
550 }
551
552 #ifdef YAWN
plotmaple(pl)553 void plotmaple(pl)
554 plots *pl;
555 { INT i, j;
556 plf = fopen("lfplot","w");
557 switch(pl->d)
558 { case 1:
559 fprintf(plf,"PLOT(\n");
560 for (j=0; j<pl->r; j++)
561 { fprintf(plf,"CURVES([\n");
562 for (i=0; i<pl->mx[j]; i++)
563 { if (i>0) fprintf(plf,",\n");
564 fprintf(plf,"[%f,%f]",pl->x[j][i],pl->y[j][i]);
565 }
566 fprintf(plf,"],\nCOLOUR(RGB,0,0,0)),\n");
567 }
568 if (pl->type[0]=='p') fprintf(plf,"STYLE(POINT),");
569 if (pl->main!=NULL) fprintf(plf,"TITLE(%s),",pl->main);
570 fprintf(plf,"AXESLABELS(%s,%s)",pl->xlab,pl->ylab);
571 fprintf(plf,");\n");
572
573 break;
574 case 2:
575 fprintf(plf,"PLOT3D(GRID(%f..%f,%f..%f,[[\n",pl->x[0][0],pl->x[0][pl->mx[0]-1],pl->y[0][0],pl->y[0][pl->my[0]-1]);
576 for (i=0; i<pl->mx[0]; i++)
577 { if (i>0) fprintf(plf,"],\n[");
578 for (j=0; j<pl->my[0]; j++)
579 { if (j>0) fprintf(plf,",\n");
580 fprintf(plf,"%f",pl->z[0][i*pl->my[0]+j]);
581 }
582 }
583 fprintf(plf,"]]),\nAXESLABELS(%s,%s,%s),AXESSTYLE(FRAME)",pl->xlab,pl->ylab,pl->zlab);
584 if (pl->type[0]=='c') fprintf(plf,",STYLE(CONTOUR),CONTOURS(DEFAULT),ORIENTATION(-90,0.1),COLOUR(ZSHADING)");
585 if (pl->main!=NULL) fprintf(plf,",\nTITLE(%s)\n",pl->main);
586 fprintf(plf,");\n");
587 break;
588 }
589 fclose(plf);
590 printf("Created lfplot file; Maple format.\n");
591 }
592
plotmathe(pl,fmt)593 void plotmathe(pl,fmt)
594 plots *pl;
595 char *fmt;
596 { INT i, j, aut;
597 static FILE *plm=NULL;
598 aut = f2(fmt)!='m';
599 #ifdef NOPIPES
600 aut = 0;
601 #endif
602 if (aut)
603 { if (plm==NULL) plm = (FILE *)popen("math >/dev/null","w");
604 plf = plm;
605 }
606 else
607 plf = fopen("lfplot","w");
608 switch(pl->d)
609 { case 1:
610 fprintf(plf,"ListPlot[{{\n");
611 for (i=0; i<pl->mx[0]; i++)
612 { if (i>0) fprintf(plf,"},\n{");
613 fprintf(plf,"%f,%f",pl->x[0][i],pl->y[0][i]);
614 }
615 fprintf(plf,"}}");
616 fprintf(plf,",AxesLabel->{%s,%s}",pl->xlab,pl->ylab);
617 if (pl->type[0]=='l') fprintf(plf,",PlotJoined->True");
618 break;
619 case 2:
620 if (pl->type[0]=='c') fprintf(plf,"ListContourPlot[{{");
621 else fprintf(plf,"ListPlot3D[{{");
622 for (j=0; j<pl->my[0]; j++)
623 { if (j>0) fprintf(plf,"},\n{");
624 for (i=0; i<pl->mx[0]; i++)
625 { if (i>0) fprintf(plf,",\n");
626 fprintf(plf,"%f",pl->z[0][i*pl->my[0]+j]);
627 }
628 }
629 fprintf(plf,"}},\nMeshRange->{{");
630 fprintf(plf,"%f,%f},{%f,%f}}\n",pl->x[0][0],pl->x[0][pl->mx[0]-1],pl->y[0][0],pl->y[0][pl->my[0]-1]);
631 if (pl->type[0]=='c') fprintf(plf,",FrameLabel->{%s,%s}",pl->xlab,pl->ylab);
632 else fprintf(plf,",AxesLabel->{%s,%s,%s}",pl->xlab,pl->ylab,pl->zlab);
633 break;
634 }
635 if (pl->main!=NULL) fprintf(plf,",PlotLabel->%s\n",pl->main);
636 fprintf(plf,"];\n");
637 if (aut)
638 fflush(plf);
639 else
640 { fclose(plf);
641 printf("Created lfplot file; Mathematica format.\n");
642 }
643 }
644
plotmatlb(pl)645 void plotmatlb(pl) /* Matlab */
646 plots *pl;
647 { INT i, j;
648 plf = fopen("lfplot.m","w");
649 switch(pl->d)
650 { case 1:
651 fprintf(plf,"plot([");
652 for (i=0; i<pl->mx[0]; i++)
653 { if (i>0) putc(',',plf);
654 fprintf(plf,"%f",pl->x[0][i]);
655 }
656 fprintf(plf,"],[");
657 for (i=0; i<pl->mx[0]; i++)
658 { if (i>0) putc(',',plf);
659 fprintf(plf,"%f",pl->y[0][i]);
660 }
661 fprintf(plf,"])\n");
662 break;
663 case 2:
664 if (pl->type[0]=='c') fprintf(plf,"contour([");
665 else fprintf(plf,"mesh([");
666 for (i=0; i<pl->my[0]; i++) fprintf(plf,"%f ",pl->y[0][i]);
667 fprintf(plf,"],[");
668 for (i=0; i<pl->mx[0]; i++) fprintf(plf,"%f ",pl->x[0][i]);
669 fprintf(plf,"],[\n");
670 for (j=0; j<pl->my[0]; j++)
671 { fprintf(plf,"[");
672 for (i=0; i<pl->mx[0]; i++)
673 fprintf(plf,"%f ",pl->z[0][i*pl->my[0]+j]);
674 fprintf(plf,"]\n");
675 }
676 fprintf(plf,"])\n");
677 fprintf(plf,"xlabel('%s')\n",pl->xlab);
678 fprintf(plf,"ylabel('%s')\n",pl->ylab);
679 break;
680 default: ERROR(("plotmatlb: invalid dimension %d",pl->d));
681 }
682 if (pl->main!=NULL) fprintf(plf,"title('%s')\n",pl->main);
683 fclose(plf);
684 printf("Created lfplot.m file; matlab format.\n");
685 }
686
plotgnup(pl,fmt)687 void plotgnup(pl,fmt)
688 plots *pl;
689 char *fmt;
690 { INT i, j, z, aut;
691 char m;
692 static FILE *plc=NULL;
693
694 /* first, the data file */
695 plf=fopen("lfplot.dat","w");
696 switch(pl->d)
697 { case 1:
698 z = pl->mx[0];
699 for (j=0; j<pl->r; j++) if (pl->mx[j]>z) z = pl->mx[j];
700 for (i=0; i<z; i++)
701 { for (j=0; j<pl->r; j++)
702 if (i<pl->mx[j])
703 fprintf(plf,"%f %f ",pl->x[j][i],pl->y[j][i]);
704 else
705 fprintf(plf,"%f %f ",pl->x[j][pl->mx[j]-1],pl->y[j][pl->mx[j]-1]);
706 fprintf(plf,"\n");
707 }
708 break;
709 case 2:
710 for (j=0; j<pl->my[0]; j++)
711 { for (i=0; i<pl->mx[0]; i++)
712 fprintf(plf,"%f %f %f\n",pl->x[0][i],pl->y[0][j],pl->z[0][i*pl->my[0]+j]);
713 fprintf(plf,"\n");
714 }
715 }
716 fclose(plf);
717
718 /* second, the command file */
719 m = f2(fmt);
720 aut = (m!='m');
721 #ifdef NOPIPES
722 aut = 0;
723 #endif
724 if (aut)
725 { if ((m=='s') && (plc!=NULL)) pclose(plc);
726 if ((m=='s') || (plc==NULL))
727 plc = (FILE *)popen("gnuplot","w");
728 plf = plc;
729 }
730 else plf = fopen("lfplot","w");
731 switch(pl->d)
732 { case 1:
733 fprintf(plf,"set nokey\n");
734 fprintf(plf,"set xlab \"%s\"\n",pl->xlab);
735 fprintf(plf,"set ylab \"%s\"\n",pl->ylab);
736 if (pl->main != NULL)
737 fprintf(plf,"set title \"%s\"\n",pl->main);
738 fprintf(plf,"plot ");
739 for (i=0; i<pl->r; i++)
740 { if (i>0) fprintf(plf,", ");
741 fprintf(plf,"\"lfplot.dat\" using %d:%d ",2*i+1,2*i+2);
742 switch(pl->type[i])
743 { case 'l': fprintf(plf,"with lines"); break;
744 case 'p': fprintf(plf,"with points"); break;
745 case 'b': fprintf(plf,"with linespoints"); break;
746 }
747 }
748 fprintf(plf,"\n");
749 break;
750 case 2:
751 fprintf(plf,"set xlab \"%s\"\n",pl->xlab);
752 fprintf(plf,"set ylab \"%s\"\n",pl->ylab);
753 fprintf(plf,"set zlab \"%s\"\n",pl->zlab);
754 if (pl->type[0]=='c')
755 { fprintf(plf,"set contour\n");
756 fprintf(plf,"set nosurface\n");
757 fprintf(plf,"set key\n");
758 }
759 else
760 { fprintf(plf,"set nocontour\n");
761 fprintf(plf,"set surface\n");
762 fprintf(plf,"set nokey\n");
763 }
764 fprintf(plf,"set view %g,%g\n",pl->phi,pl->theta);
765 fprintf(plf,"set parametric\n");
766 if (pl->main != NULL)
767 fprintf(plf,"set title \"%s\"\n",pl->main);
768 fprintf(plf,"splot \"lfplot.dat\" with lines\n");
769 break;
770 }
771 if (aut)
772 fflush(plf);
773 else
774 { fclose(plf);
775 printf("Created lfplot, lfplot.dat files; gnuplot format.\n");
776 }
777 }
778 #endif
779
780 #endif
781