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