1 4314729d 2004-04-14 devnull #include <u.h>
2 4314729d 2004-04-14 devnull #include <libc.h>
3 4314729d 2004-04-14 devnull #include <stdio.h>
4 4314729d 2004-04-14 devnull #include "iplot.h"
5 4314729d 2004-04-14 devnull #define INF 1.e+37
6 4314729d 2004-04-14 devnull #define F .25
8 4314729d 2004-04-14 devnull struct xy {
9 4314729d 2004-04-14 devnull int xlbf; /*flag:explicit lower bound*/
10 4314729d 2004-04-14 devnull int xubf; /*flag:explicit upper bound*/
11 4314729d 2004-04-14 devnull int xqf; /*flag:explicit quantum*/
12 4314729d 2004-04-14 devnull double (*xf)(double); /*transform function, e.g. log*/
13 4314729d 2004-04-14 devnull float xa,xb; /*scaling coefficients*/
14 4314729d 2004-04-14 devnull float xlb,xub; /*lower and upper bound*/
15 4314729d 2004-04-14 devnull float xquant; /*quantum*/
16 4314729d 2004-04-14 devnull float xoff; /*screen offset fraction*/
17 4314729d 2004-04-14 devnull float xsize; /*screen fraction*/
18 4314729d 2004-04-14 devnull int xbot,xtop; /*screen coords of border*/
19 4314729d 2004-04-14 devnull float xmult; /*scaling constant*/
21 4314729d 2004-04-14 devnull struct val {
22 4314729d 2004-04-14 devnull float xv;
23 4314729d 2004-04-14 devnull float yv;
24 4314729d 2004-04-14 devnull int lblptr;
27 4314729d 2004-04-14 devnull char *labels;
28 4314729d 2004-04-14 devnull int labelsiz;
30 4314729d 2004-04-14 devnull int tick = 50;
31 4314729d 2004-04-14 devnull int top = 4000;
32 4314729d 2004-04-14 devnull int bot = 200;
33 4314729d 2004-04-14 devnull float absbot;
35 4314729d 2004-04-14 devnull int erasf = 1;
36 4314729d 2004-04-14 devnull int gridf = 2;
37 4314729d 2004-04-14 devnull int symbf = 0;
38 4314729d 2004-04-14 devnull int absf = 0;
39 4314729d 2004-04-14 devnull int transf;
40 4314729d 2004-04-14 devnull int equf;
41 4314729d 2004-04-14 devnull int brkf;
42 4314729d 2004-04-14 devnull int ovlay = 1;
43 4314729d 2004-04-14 devnull float dx;
44 4314729d 2004-04-14 devnull char *plotsymb;
46 4314729d 2004-04-14 devnull #define BSIZ 80
47 4314729d 2004-04-14 devnull char labbuf[BSIZ];
48 4314729d 2004-04-14 devnull char titlebuf[BSIZ];
50 4314729d 2004-04-14 devnull char *modes[] = {
51 4314729d 2004-04-14 devnull "disconnected",
53 4314729d 2004-04-14 devnull "dotted",
54 4314729d 2004-04-14 devnull "dotdashed",
55 4314729d 2004-04-14 devnull "shortdashed",
56 4314729d 2004-04-14 devnull "longdashed"
58 4314729d 2004-04-14 devnull int mode = 1;
59 4314729d 2004-04-14 devnull double ident(double x){
60 4314729d 2004-04-14 devnull return(x);
63 4314729d 2004-04-14 devnull struct z {
64 4314729d 2004-04-14 devnull float lb,ub,mult,quant;
66 4314729d 2004-04-14 devnull void init(struct xy *);
67 4314729d 2004-04-14 devnull void setopt(int, char *[]);
68 4314729d 2004-04-14 devnull void readin(void);
69 4314729d 2004-04-14 devnull void transpose(void);
70 4314729d 2004-04-14 devnull void getlim(struct xy *, struct val *);
71 4314729d 2004-04-14 devnull void equilibrate(struct xy *, struct xy *);
72 4314729d 2004-04-14 devnull void scale(struct xy *);
73 4314729d 2004-04-14 devnull void limread(struct xy *, int *, char ***);
74 4314729d 2004-04-14 devnull int numb(float *, int *, char ***);
75 4314729d 2004-04-14 devnull int copystring(int);
76 4314729d 2004-04-14 devnull struct z setloglim(int, int, float, float);
77 4314729d 2004-04-14 devnull struct z setlinlim(int, int, float, float);
78 4314729d 2004-04-14 devnull void axes(void);
79 4314729d 2004-04-14 devnull int setmark(int *, struct xy *);
80 4314729d 2004-04-14 devnull void submark(int *, int *, float, struct xy *);
81 4314729d 2004-04-14 devnull void plot(void);
82 4314729d 2004-04-14 devnull int getfloat(float *);
83 4314729d 2004-04-14 devnull int getstring(void);
84 4314729d 2004-04-14 devnull void title(void);
85 4314729d 2004-04-14 devnull void badarg(void);
86 4314729d 2004-04-14 devnull int conv(float, struct xy *, int *);
87 4314729d 2004-04-14 devnull int symbol(int, int, int);
88 4314729d 2004-04-14 devnull void axlab(char, struct xy *, char *);
90 4314729d 2004-04-14 devnull void main(int argc,char *argv[]){
92 4314729d 2004-04-14 devnull openpl();
93 4314729d 2004-04-14 devnull range(0,0,4096,4096);
94 4314729d 2004-04-14 devnull init(&xd);
95 4314729d 2004-04-14 devnull init(&yd);
96 4314729d 2004-04-14 devnull xd.xsize = yd.xsize = 1.;
97 4314729d 2004-04-14 devnull xx = (struct val *)malloc((unsigned)sizeof(struct val));
98 4314729d 2004-04-14 devnull labels = malloc(1);
99 4314729d 2004-04-14 devnull labels[labelsiz++] = 0;
100 4314729d 2004-04-14 devnull setopt(argc,argv);
101 4314729d 2004-04-14 devnull if(erasf)
102 4314729d 2004-04-14 devnull erase();
103 4314729d 2004-04-14 devnull readin();
104 4314729d 2004-04-14 devnull transpose();
105 4314729d 2004-04-14 devnull getlim(&xd,(struct val *)&xx->xv);
106 4314729d 2004-04-14 devnull getlim(&yd,(struct val *)&xx->yv);
107 4314729d 2004-04-14 devnull if(equf) {
108 4314729d 2004-04-14 devnull equilibrate(&xd,&yd);
109 4314729d 2004-04-14 devnull equilibrate(&yd,&xd);
111 4314729d 2004-04-14 devnull scale(&xd);
112 4314729d 2004-04-14 devnull scale(&yd);
114 4314729d 2004-04-14 devnull title();
116 4314729d 2004-04-14 devnull closepl();
117 4314729d 2004-04-14 devnull exits(0);
120 4314729d 2004-04-14 devnull void init(struct xy *p){
121 4314729d 2004-04-14 devnull p->xf = ident;
122 4314729d 2004-04-14 devnull p->xmult = 1;
125 4314729d 2004-04-14 devnull void setopt(int argc, char *argv[]){
126 4314729d 2004-04-14 devnull char *p1, *p2;
127 4314729d 2004-04-14 devnull float temp;
129 4314729d 2004-04-14 devnull xd.xlb = yd.xlb = INF;
130 4314729d 2004-04-14 devnull xd.xub = yd.xub = -INF;
131 4314729d 2004-04-14 devnull while(--argc > 0) {
133 4314729d 2004-04-14 devnull again: switch(argv[0][0]) {
134 4314729d 2004-04-14 devnull case '-':
135 4314729d 2004-04-14 devnull argv[0]++;
136 4314729d 2004-04-14 devnull goto again;
137 4314729d 2004-04-14 devnull case 'l': /* label for plot */
138 4314729d 2004-04-14 devnull p1 = titlebuf;
139 4314729d 2004-04-14 devnull if (argc>=2) {
142 4314729d 2004-04-14 devnull p2 = argv[0];
143 4314729d 2004-04-14 devnull while (*p1++ = *p2++);
147 4314729d 2004-04-14 devnull case 'd': /*disconnected,obsolete option*/
148 4314729d 2004-04-14 devnull case 'm': /*line mode*/
149 4314729d 2004-04-14 devnull mode = 0;
150 4314729d 2004-04-14 devnull if(!numb(&temp,&argc,&argv))
152 4314729d 2004-04-14 devnull if(temp>=sizeof(modes)/sizeof(*modes))
153 4314729d 2004-04-14 devnull mode = 1;
154 4314729d 2004-04-14 devnull else if(temp>=-1)
155 4314729d 2004-04-14 devnull mode = temp;
158 4314729d 2004-04-14 devnull case 'o':
159 4314729d 2004-04-14 devnull if(numb(&temp,&argc,&argv) && temp>=1)
160 4314729d 2004-04-14 devnull ovlay = temp;
162 4314729d 2004-04-14 devnull case 'a': /*automatic abscissas*/
163 4314729d 2004-04-14 devnull absf = 1;
165 4314729d 2004-04-14 devnull if(!numb(&dx,&argc,&argv))
167 4314729d 2004-04-14 devnull if(numb(&absbot,&argc,&argv))
168 4314729d 2004-04-14 devnull absf = 2;
171 4314729d 2004-04-14 devnull case 's': /*save screen, overlay plot*/
172 4314729d 2004-04-14 devnull erasf = 0;
175 4314729d 2004-04-14 devnull case 'g': /*grid style 0 none, 1 ticks, 2 full*/
176 4314729d 2004-04-14 devnull gridf = 0;
177 4314729d 2004-04-14 devnull if(!numb(&temp,&argc,&argv))
178 4314729d 2004-04-14 devnull temp = argv[0][1]-'0'; /*for caompatibility*/
179 4314729d 2004-04-14 devnull if(temp>=0&&temp<=2)
180 4314729d 2004-04-14 devnull gridf = temp;
183 4314729d 2004-04-14 devnull case 'c': /*character(s) for plotting*/
184 4314729d 2004-04-14 devnull if(argc >= 2) {
185 4314729d 2004-04-14 devnull symbf = 1;
186 4314729d 2004-04-14 devnull plotsymb = argv[1];
192 4314729d 2004-04-14 devnull case 't': /*transpose*/
193 4314729d 2004-04-14 devnull transf = 1;
195 4314729d 2004-04-14 devnull case 'e': /*equal scales*/
196 4314729d 2004-04-14 devnull equf = 1;
198 4314729d 2004-04-14 devnull case 'b': /*breaks*/
199 4314729d 2004-04-14 devnull brkf = 1;
201 4314729d 2004-04-14 devnull case 'x': /*x limits */
202 4314729d 2004-04-14 devnull limread(&xd,&argc,&argv);
204 4314729d 2004-04-14 devnull case 'y':
205 4314729d 2004-04-14 devnull limread(&yd,&argc,&argv);
207 4314729d 2004-04-14 devnull case 'h': /*set height of plot */
208 4314729d 2004-04-14 devnull if(!numb(&yd.xsize, &argc,&argv))
209 4314729d 2004-04-14 devnull badarg();
211 4314729d 2004-04-14 devnull case 'w': /*set width of plot */
212 4314729d 2004-04-14 devnull if(!numb(&xd.xsize, &argc, &argv))
213 4314729d 2004-04-14 devnull badarg();
215 4314729d 2004-04-14 devnull case 'r': /* set offset to right */
216 4314729d 2004-04-14 devnull if(!numb(&xd.xoff, &argc, &argv))
217 4314729d 2004-04-14 devnull badarg();
219 4314729d 2004-04-14 devnull case 'u': /*set offset up the screen*/
220 4314729d 2004-04-14 devnull if(!numb(&yd.xoff,&argc,&argv))
221 4314729d 2004-04-14 devnull badarg();
223 4314729d 2004-04-14 devnull default:
224 4314729d 2004-04-14 devnull badarg();
229 4314729d 2004-04-14 devnull void limread(struct xy *p, int *argcp, char ***argvp){
230 4314729d 2004-04-14 devnull if(*argcp>1 && (*argvp)[1][0]=='l') {
231 4314729d 2004-04-14 devnull (*argcp)--;
232 4314729d 2004-04-14 devnull (*argvp)++;
233 4314729d 2004-04-14 devnull p->xf = log10;
235 4314729d 2004-04-14 devnull if(!numb(&p->xlb,argcp,argvp))
237 4314729d 2004-04-14 devnull p->xlbf = 1;
238 4314729d 2004-04-14 devnull if(!numb(&p->xub,argcp,argvp))
240 4314729d 2004-04-14 devnull p->xubf = 1;
241 4314729d 2004-04-14 devnull if(!numb(&p->xquant,argcp,argvp))
243 4314729d 2004-04-14 devnull p->xqf = 1;
247 4314729d 2004-04-14 devnull isdigit(char c){
248 4314729d 2004-04-14 devnull return '0'<=c && c<='9';
252 4314729d 2004-04-14 devnull numb(float *np, int *argcp, char ***argvp){
255 4314729d 2004-04-14 devnull if(*argcp <= 1)
256 4314729d 2004-04-14 devnull return(0);
257 4314729d 2004-04-14 devnull while((c=(*argvp)[1][0]) == '+')
258 4314729d 2004-04-14 devnull (*argvp)[1]++;
259 4314729d 2004-04-14 devnull if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.'))
260 4314729d 2004-04-14 devnull return(0);
261 4314729d 2004-04-14 devnull *np = atof((*argvp)[1]);
262 4314729d 2004-04-14 devnull (*argcp)--;
263 4314729d 2004-04-14 devnull (*argvp)++;
264 4314729d 2004-04-14 devnull return(1);
267 4314729d 2004-04-14 devnull void readin(void){
268 4314729d 2004-04-14 devnull int i, t;
269 4314729d 2004-04-14 devnull struct val *temp;
271 4314729d 2004-04-14 devnull if(absf==1) {
272 4314729d 2004-04-14 devnull if(xd.xlbf)
273 4314729d 2004-04-14 devnull absbot = xd.xlb;
274 4314729d 2004-04-14 devnull else if(xd.xf==log10)
275 4314729d 2004-04-14 devnull absbot = 1;
277 4314729d 2004-04-14 devnull for(;;) {
278 4314729d 2004-04-14 devnull temp = (struct val *)realloc((char*)xx,
279 4314729d 2004-04-14 devnull (unsigned)(n+ovlay)*sizeof(struct val));
280 4314729d 2004-04-14 devnull if(temp==0)
282 4314729d 2004-04-14 devnull xx = temp;
283 4314729d 2004-04-14 devnull if(absf)
284 4314729d 2004-04-14 devnull xx[n].xv = n*dx/ovlay + absbot;
286 4314729d 2004-04-14 devnull if(!getfloat(&xx[n].xv))
288 4314729d 2004-04-14 devnull t = 0; /* silence compiler */
289 4314729d 2004-04-14 devnull for(i=0;i<ovlay;i++) {
290 4314729d 2004-04-14 devnull xx[n+i].xv = xx[n].xv;
291 4314729d 2004-04-14 devnull if(!getfloat(&xx[n+i].yv))
293 4314729d 2004-04-14 devnull xx[n+i].lblptr = -1;
294 4314729d 2004-04-14 devnull t = getstring();
296 4314729d 2004-04-14 devnull xx[n+i].lblptr = copystring(t);
297 4314729d 2004-04-14 devnull if(t<0 && i+1<ovlay)
300 4314729d 2004-04-14 devnull n += ovlay;
306 4314729d 2004-04-14 devnull void transpose(void){
308 4314729d 2004-04-14 devnull float f;
309 4314729d 2004-04-14 devnull struct xy t;
310 4314729d 2004-04-14 devnull if(!transf)
312 4314729d 2004-04-14 devnull t = xd; xd = yd; yd = t;
313 4314729d 2004-04-14 devnull for(i= 0;i<n;i++) {
314 4314729d 2004-04-14 devnull f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f;
318 4314729d 2004-04-14 devnull int copystring(int k){
319 4314729d 2004-04-14 devnull char *temp;
323 4314729d 2004-04-14 devnull temp = realloc(labels,(unsigned)(labelsiz+1+k));
324 4314729d 2004-04-14 devnull if(temp==0)
325 4314729d 2004-04-14 devnull return(0);
326 4314729d 2004-04-14 devnull labels = temp;
327 4314729d 2004-04-14 devnull q = labelsiz;
328 4314729d 2004-04-14 devnull for(i=0;i<=k;i++)
329 4314729d 2004-04-14 devnull labels[labelsiz++] = labbuf[i];
330 4314729d 2004-04-14 devnull return(q);
333 4314729d 2004-04-14 devnull float modceil(float f, float t){
335 4314729d 2004-04-14 devnull t = fabs(t);
336 4314729d 2004-04-14 devnull return(ceil(f/t)*t);
340 4314729d 2004-04-14 devnull modfloor(float f, float t){
341 4314729d 2004-04-14 devnull t = fabs(t);
342 4314729d 2004-04-14 devnull return(floor(f/t)*t);
345 4314729d 2004-04-14 devnull void getlim(struct xy *p, struct val *v){
350 4314729d 2004-04-14 devnull if(!p->xlbf && p->xlb>v[i].xv)
351 4314729d 2004-04-14 devnull p->xlb = v[i].xv;
352 4314729d 2004-04-14 devnull if(!p->xubf && p->xub<v[i].xv)
353 4314729d 2004-04-14 devnull p->xub = v[i].xv;
355 4314729d 2004-04-14 devnull } while(i < n);
358 4314729d 2004-04-14 devnull void setlim(struct xy *p){
359 4314729d 2004-04-14 devnull float t,delta,sign;
360 4314729d 2004-04-14 devnull struct z z;
361 4314729d 2004-04-14 devnull int mark[50];
362 4314729d 2004-04-14 devnull float lb,ub;
363 4314729d 2004-04-14 devnull int lbf,ubf;
365 4314729d 2004-04-14 devnull lb = p->xlb;
366 4314729d 2004-04-14 devnull ub = p->xub;
367 4314729d 2004-04-14 devnull delta = ub-lb;
368 4314729d 2004-04-14 devnull if(p->xqf) {
369 4314729d 2004-04-14 devnull if(delta*p->xquant <=0 )
370 4314729d 2004-04-14 devnull badarg();
373 4314729d 2004-04-14 devnull sign = 1;
374 4314729d 2004-04-14 devnull lbf = p->xlbf;
375 4314729d 2004-04-14 devnull ubf = p->xubf;
376 4314729d 2004-04-14 devnull if(delta < 0) {
377 4314729d 2004-04-14 devnull sign = -1;
379 4314729d 2004-04-14 devnull lb = ub;
381 4314729d 2004-04-14 devnull t = lbf;
382 4314729d 2004-04-14 devnull lbf = ubf;
383 4314729d 2004-04-14 devnull ubf = t;
385 4314729d 2004-04-14 devnull else if(delta == 0) {
386 4314729d 2004-04-14 devnull if(ub > 0) {
387 4314729d 2004-04-14 devnull ub = 2*ub;
391 4314729d 2004-04-14 devnull if(lb < 0) {
392 4314729d 2004-04-14 devnull lb = 2*lb;
397 4314729d 2004-04-14 devnull lb = -1;
400 4314729d 2004-04-14 devnull if(p->xf==log10 && lb>0 && ub>lb) {
401 4314729d 2004-04-14 devnull z = setloglim(lbf,ubf,lb,ub);
402 4314729d 2004-04-14 devnull p->xlb = z.lb;
403 4314729d 2004-04-14 devnull p->xub = z.ub;
404 4314729d 2004-04-14 devnull p->xmult *= z.mult;
405 4314729d 2004-04-14 devnull p->xquant = z.quant;
406 4314729d 2004-04-14 devnull if(setmark(mark,p)<2) {
407 4314729d 2004-04-14 devnull p->xqf = lbf = ubf = 1;
408 4314729d 2004-04-14 devnull lb = z.lb; ub = z.ub;
412 4314729d 2004-04-14 devnull z = setlinlim(lbf,ubf,lb,ub);
413 4314729d 2004-04-14 devnull if(sign > 0) {
414 4314729d 2004-04-14 devnull p->xlb = z.lb;
415 4314729d 2004-04-14 devnull p->xub = z.ub;
416 4314729d 2004-04-14 devnull } else {
417 4314729d 2004-04-14 devnull p->xlb = z.ub;
418 4314729d 2004-04-14 devnull p->xub = z.lb;
420 4314729d 2004-04-14 devnull p->xmult *= z.mult;
421 4314729d 2004-04-14 devnull p->xquant = sign*z.quant;
424 4314729d 2004-04-14 devnull struct z
425 4314729d 2004-04-14 devnull setloglim(int lbf, int ubf, float lb, float ub){
426 4314729d 2004-04-14 devnull float r,s,t;
427 4314729d 2004-04-14 devnull struct z z;
429 4314729d 2004-04-14 devnull for(s=1; lb*s<1; s*=10) ;
430 4314729d 2004-04-14 devnull lb *= s;
431 4314729d 2004-04-14 devnull ub *= s;
432 4314729d 2004-04-14 devnull for(r=1; 10*r<=lb; r*=10) ;
433 4314729d 2004-04-14 devnull for(t=1; t<ub; t*=10) ;
434 4314729d 2004-04-14 devnull z.lb = !lbf ? r : lb;
435 4314729d 2004-04-14 devnull z.ub = !ubf ? t : ub;
436 4314729d 2004-04-14 devnull if(ub/lb<100) {
437 4314729d 2004-04-14 devnull if(!lbf) {
438 4314729d 2004-04-14 devnull if(lb >= 5*z.lb)
439 4314729d 2004-04-14 devnull z.lb *= 5;
440 4314729d 2004-04-14 devnull else if(lb >= 2*z.lb)
441 4314729d 2004-04-14 devnull z.lb *= 2;
443 4314729d 2004-04-14 devnull if(!ubf) {
444 4314729d 2004-04-14 devnull if(ub*5 <= z.ub)
445 4314729d 2004-04-14 devnull z.ub /= 5;
446 4314729d 2004-04-14 devnull else if(ub*2 <= z.ub)
447 4314729d 2004-04-14 devnull z.ub /= 2;
450 4314729d 2004-04-14 devnull z.mult = s;
451 4314729d 2004-04-14 devnull z.quant = r;
452 4314729d 2004-04-14 devnull return(z);
455 4314729d 2004-04-14 devnull struct z
456 4314729d 2004-04-14 devnull setlinlim(int lbf, int ubf, float xlb, float xub){
457 4314729d 2004-04-14 devnull struct z z;
458 4314729d 2004-04-14 devnull float r,s,delta;
459 4314729d 2004-04-14 devnull float ub,lb;
462 4314729d 2004-04-14 devnull ub = xub;
463 4314729d 2004-04-14 devnull lb = xlb;
464 4314729d 2004-04-14 devnull delta = ub - lb;
465 4314729d 2004-04-14 devnull /*scale up by s, a power of 10, so range (delta) exceeds 1*/
466 4314729d 2004-04-14 devnull /*find power of 10 quantum, r, such that delta/10<=r<delta*/
467 4314729d 2004-04-14 devnull r = s = 1;
468 4314729d 2004-04-14 devnull while(delta*s < 10)
469 4314729d 2004-04-14 devnull s *= 10;
470 4314729d 2004-04-14 devnull delta *= s;
471 4314729d 2004-04-14 devnull while(10*r < delta)
472 4314729d 2004-04-14 devnull r *= 10;
473 4314729d 2004-04-14 devnull lb *= s;
474 4314729d 2004-04-14 devnull ub *= s;
475 4314729d 2004-04-14 devnull /*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/
476 4314729d 2004-04-14 devnull if(r>=delta/2)
478 4314729d 2004-04-14 devnull else if(r<delta/5)
480 4314729d 2004-04-14 devnull z.ub = ubf? ub: modceil(ub,r);
481 4314729d 2004-04-14 devnull z.lb = lbf? lb: modfloor(lb,r);
482 4314729d 2004-04-14 devnull if(!lbf && z.lb<=r && z.lb>0) {
483 4314729d 2004-04-14 devnull xlb = 0;
484 4314729d 2004-04-14 devnull goto loop;
486 4314729d 2004-04-14 devnull else if(!ubf && z.ub>=-r && z.ub<0) {
487 4314729d 2004-04-14 devnull xub = 0;
488 4314729d 2004-04-14 devnull goto loop;
490 4314729d 2004-04-14 devnull z.quant = r;
491 4314729d 2004-04-14 devnull z.mult = s;
492 4314729d 2004-04-14 devnull return(z);
495 4314729d 2004-04-14 devnull void scale(struct xy *p){
496 4314729d 2004-04-14 devnull float edge;
498 4314729d 2004-04-14 devnull setlim(p);
499 4314729d 2004-04-14 devnull edge = top-bot;
500 4314729d 2004-04-14 devnull p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb));
501 4314729d 2004-04-14 devnull p->xbot = bot + edge*p->xoff;
502 4314729d 2004-04-14 devnull p->xtop = p->xbot + (top-bot)*p->xsize;
503 4314729d 2004-04-14 devnull p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5;
506 4314729d 2004-04-14 devnull void equilibrate(struct xy *p, struct xy *q){
507 4314729d 2004-04-14 devnull if(p->xlbf|| /* needn't test xubf; it implies xlbf*/
508 4314729d 2004-04-14 devnull q->xubf&&q->xlb>q->xub)
510 4314729d 2004-04-14 devnull if(p->xlb>q->xlb) {
511 4314729d 2004-04-14 devnull p->xlb = q->xlb;
512 4314729d 2004-04-14 devnull p->xlbf = q->xlbf;
514 4314729d 2004-04-14 devnull if(p->xub<q->xub) {
515 4314729d 2004-04-14 devnull p->xub = q->xub;
516 4314729d 2004-04-14 devnull p->xubf = q->xubf;
520 4314729d 2004-04-14 devnull void axes(void){
522 4314729d 2004-04-14 devnull int mark[50];
523 4314729d 2004-04-14 devnull int xn, yn;
524 4314729d 2004-04-14 devnull if(gridf==0)
527 4314729d 2004-04-14 devnull line(xd.xbot,yd.xbot,xd.xtop,yd.xbot);
528 4314729d 2004-04-14 devnull vec(xd.xtop,yd.xtop);
529 4314729d 2004-04-14 devnull vec(xd.xbot,yd.xtop);
530 4314729d 2004-04-14 devnull vec(xd.xbot,yd.xbot);
532 4314729d 2004-04-14 devnull xn = setmark(mark,&xd);
533 4314729d 2004-04-14 devnull for(i=0; i<xn; i++) {
534 4314729d 2004-04-14 devnull if(gridf==2)
535 4314729d 2004-04-14 devnull line(mark[i],yd.xbot,mark[i],yd.xtop);
536 4314729d 2004-04-14 devnull if(gridf==1) {
537 4314729d 2004-04-14 devnull line(mark[i],yd.xbot,mark[i],yd.xbot+tick);
538 4314729d 2004-04-14 devnull line(mark[i],yd.xtop-tick,mark[i],yd.xtop);
541 4314729d 2004-04-14 devnull yn = setmark(mark,&yd);
542 4314729d 2004-04-14 devnull for(i=0; i<yn; i++) {
543 4314729d 2004-04-14 devnull if(gridf==2)
544 4314729d 2004-04-14 devnull line(xd.xbot,mark[i],xd.xtop,mark[i]);
545 4314729d 2004-04-14 devnull if(gridf==1) {
546 4314729d 2004-04-14 devnull line(xd.xbot,mark[i],xd.xbot+tick,mark[i]);
547 4314729d 2004-04-14 devnull line(xd.xtop-tick,mark[i],xd.xtop,mark[i]);
553 4314729d 2004-04-14 devnull setmark(int *xmark, struct xy *p){
554 4314729d 2004-04-14 devnull int xn = 0;
555 4314729d 2004-04-14 devnull float x,xl,xu;
556 4314729d 2004-04-14 devnull float q;
557 4314729d 2004-04-14 devnull if(p->xf==log10&&!p->xqf) {
558 4314729d 2004-04-14 devnull for(x=p->xquant; x<p->xub; x*=10) {
559 4314729d 2004-04-14 devnull submark(xmark,&xn,x,p);
560 4314729d 2004-04-14 devnull if(p->xub/p->xlb<=100) {
561 4314729d 2004-04-14 devnull submark(xmark,&xn,2*x,p);
562 4314729d 2004-04-14 devnull submark(xmark,&xn,5*x,p);
565 4314729d 2004-04-14 devnull } else {
567 4314729d 2004-04-14 devnull q = p->xquant;
568 4314729d 2004-04-14 devnull if(q>0) {
569 4314729d 2004-04-14 devnull xl = modceil(p->xlb+q/6,q);
570 4314729d 2004-04-14 devnull xu = modfloor(p->xub-q/6,q)+q/2;
571 4314729d 2004-04-14 devnull } else {
572 4314729d 2004-04-14 devnull xl = modceil(p->xub-q/6,q);
573 4314729d 2004-04-14 devnull xu = modfloor(p->xlb+q/6,q)-q/2;
575 4314729d 2004-04-14 devnull for(x=xl; x<=xu; x+=fabs(p->xquant))
576 4314729d 2004-04-14 devnull xmark[xn++] = (*p->xf)(x)*p->xa + p->xb;
578 4314729d 2004-04-14 devnull return(xn);
580 4314729d 2004-04-14 devnull void submark(int *xmark, int *pxn, float x, struct xy *p){
581 4314729d 2004-04-14 devnull if(1.001*p->xlb < x && .999*p->xub > x)
582 4314729d 2004-04-14 devnull xmark[(*pxn)++] = log10(x)*p->xa + p->xb;
585 4314729d 2004-04-14 devnull void plot(void){
586 4314729d 2004-04-14 devnull int ix,iy;
587 4314729d 2004-04-14 devnull int i,j;
588 4314729d 2004-04-14 devnull int conn;
590 4314729d 2004-04-14 devnull for(j=0;j<ovlay;j++) {
591 4314729d 2004-04-14 devnull switch(mode) {
592 4314729d 2004-04-14 devnull case -1:
593 4314729d 2004-04-14 devnull pen(modes[j%(sizeof modes/sizeof *modes-1)+1]);
597 4314729d 2004-04-14 devnull default:
598 4314729d 2004-04-14 devnull pen(modes[mode]);
600 4314729d 2004-04-14 devnull conn = 0;
601 4314729d 2004-04-14 devnull for(i=j; i<n; i+=ovlay) {
602 4314729d 2004-04-14 devnull if(!conv(xx[i].xv,&xd,&ix) ||
603 4314729d 2004-04-14 devnull !conv(xx[i].yv,&yd,&iy)) {
604 4314729d 2004-04-14 devnull conn = 0;
605 4314729d 2004-04-14 devnull continue;
607 4314729d 2004-04-14 devnull if(mode!=0) {
608 4314729d 2004-04-14 devnull if(conn != 0)
609 4314729d 2004-04-14 devnull vec(ix,iy);
611 4314729d 2004-04-14 devnull move(ix,iy);
612 4314729d 2004-04-14 devnull conn = 1;
614 4314729d 2004-04-14 devnull conn &= symbol(ix,iy,xx[i].lblptr);
617 4314729d 2004-04-14 devnull pen(modes[1]);
621 4314729d 2004-04-14 devnull conv(float xv, struct xy *p, int *ip){
622 4314729d 2004-04-14 devnull long ix;
623 4314729d 2004-04-14 devnull ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb;
624 4314729d 2004-04-14 devnull if(ix<p->xbot || ix>p->xtop)
625 4314729d 2004-04-14 devnull return(0);
626 4314729d 2004-04-14 devnull *ip = ix;
627 4314729d 2004-04-14 devnull return(1);
631 4314729d 2004-04-14 devnull getfloat(float *p){
634 4314729d 2004-04-14 devnull i = scanf("%f",p);
635 4314729d 2004-04-14 devnull return(i==1);
638 4314729d 2004-04-14 devnull getstring(void){
640 4314729d 2004-04-14 devnull char junk[20];
641 4314729d 2004-04-14 devnull i = scanf("%1s",labbuf);
642 4314729d 2004-04-14 devnull if(i==-1)
643 4314729d 2004-04-14 devnull return(-1);
644 4314729d 2004-04-14 devnull switch(*labbuf) {
645 4314729d 2004-04-14 devnull default:
646 4314729d 2004-04-14 devnull if(!isdigit(*labbuf)) {
647 4314729d 2004-04-14 devnull ungetc(*labbuf,stdin);
648 4314729d 2004-04-14 devnull i = scanf("%s",labbuf);
651 4314729d 2004-04-14 devnull case '.':
652 4314729d 2004-04-14 devnull case '+':
653 4314729d 2004-04-14 devnull case '-':
654 4314729d 2004-04-14 devnull ungetc(*labbuf,stdin);
655 4314729d 2004-04-14 devnull return(0);
656 4314729d 2004-04-14 devnull case '"':
657 4314729d 2004-04-14 devnull i = scanf("%[^\"\n]",labbuf);
658 4314729d 2004-04-14 devnull scanf("%[\"]",junk);
661 4314729d 2004-04-14 devnull if(i==-1)
662 4314729d 2004-04-14 devnull return(-1);
663 4314729d 2004-04-14 devnull return(strlen(labbuf));
667 4314729d 2004-04-14 devnull symbol(int ix, int iy, int k){
669 4314729d 2004-04-14 devnull if(symbf==0&&k<0) {
670 4314729d 2004-04-14 devnull if(mode==0)
671 4314729d 2004-04-14 devnull point(ix,iy);
672 4314729d 2004-04-14 devnull return(1);
675 4314729d 2004-04-14 devnull move(ix,iy);
676 4314729d 2004-04-14 devnull text(k>=0?labels+k:plotsymb);
677 4314729d 2004-04-14 devnull move(ix,iy);
678 4314729d 2004-04-14 devnull return(!brkf|k<0);
682 4314729d 2004-04-14 devnull void title(void){
683 4314729d 2004-04-14 devnull char buf[BSIZ+100];
684 4314729d 2004-04-14 devnull buf[0] = ' ';
685 4314729d 2004-04-14 devnull buf[1] = ' ';
686 4314729d 2004-04-14 devnull buf[2] = ' ';
687 4314729d 2004-04-14 devnull strcpy(buf+3,titlebuf);
688 4314729d 2004-04-14 devnull if(erasf&&gridf) {
689 4314729d 2004-04-14 devnull axlab('x',&xd,buf);
690 4314729d 2004-04-14 devnull strcat(buf,",");
691 4314729d 2004-04-14 devnull axlab('y',&yd,buf);
693 4314729d 2004-04-14 devnull move(xd.xbot,yd.xbot-60);
694 4314729d 2004-04-14 devnull text(buf);
697 4314729d 2004-04-14 devnull void axlab(char c, struct xy *p, char *b){
698 4314729d 2004-04-14 devnull char *dir;
699 4314729d 2004-04-14 devnull dir = p->xlb<p->xub? "<=": ">=";
700 4314729d 2004-04-14 devnull sprintf(b+strlen(b), " %g %s %c%s %s %g", p->xlb/p->xmult,
701 4314729d 2004-04-14 devnull dir, c, p->xf==log10?" (log)":"", dir, p->xub/p->xmult);
704 4314729d 2004-04-14 devnull void badarg(void){
705 4314729d 2004-04-14 devnull fprintf(stderr,"graph: error in arguments\n");
706 4314729d 2004-04-14 devnull closepl();
707 4314729d 2004-04-14 devnull exits("bad arg");