Blame


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
7 4314729d 2004-04-14 devnull
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*/
20 4314729d 2004-04-14 devnull } xd,yd;
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;
25 4314729d 2004-04-14 devnull } *xx;
26 4314729d 2004-04-14 devnull
27 4314729d 2004-04-14 devnull char *labels;
28 4314729d 2004-04-14 devnull int labelsiz;
29 4314729d 2004-04-14 devnull
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;
34 4314729d 2004-04-14 devnull int n;
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;
45 4314729d 2004-04-14 devnull
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];
49 4314729d 2004-04-14 devnull
50 4314729d 2004-04-14 devnull char *modes[] = {
51 4314729d 2004-04-14 devnull "disconnected",
52 4314729d 2004-04-14 devnull "solid",
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"
57 4314729d 2004-04-14 devnull };
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);
61 4314729d 2004-04-14 devnull }
62 4314729d 2004-04-14 devnull
63 4314729d 2004-04-14 devnull struct z {
64 4314729d 2004-04-14 devnull float lb,ub,mult,quant;
65 4314729d 2004-04-14 devnull };
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 *);
89 4314729d 2004-04-14 devnull
90 b237df90 2004-05-16 devnull int main(int argc,char *argv[]){
91 4314729d 2004-04-14 devnull
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);
110 4314729d 2004-04-14 devnull }
111 4314729d 2004-04-14 devnull scale(&xd);
112 4314729d 2004-04-14 devnull scale(&yd);
113 4314729d 2004-04-14 devnull axes();
114 4314729d 2004-04-14 devnull title();
115 4314729d 2004-04-14 devnull plot();
116 4314729d 2004-04-14 devnull closepl();
117 4314729d 2004-04-14 devnull exits(0);
118 b237df90 2004-05-16 devnull return 0; /* gcc */
119 4314729d 2004-04-14 devnull }
120 4314729d 2004-04-14 devnull
121 4314729d 2004-04-14 devnull void init(struct xy *p){
122 4314729d 2004-04-14 devnull p->xf = ident;
123 4314729d 2004-04-14 devnull p->xmult = 1;
124 4314729d 2004-04-14 devnull }
125 4314729d 2004-04-14 devnull
126 4314729d 2004-04-14 devnull void setopt(int argc, char *argv[]){
127 4314729d 2004-04-14 devnull char *p1, *p2;
128 4314729d 2004-04-14 devnull float temp;
129 4314729d 2004-04-14 devnull
130 4314729d 2004-04-14 devnull xd.xlb = yd.xlb = INF;
131 4314729d 2004-04-14 devnull xd.xub = yd.xub = -INF;
132 4314729d 2004-04-14 devnull while(--argc > 0) {
133 4314729d 2004-04-14 devnull argv++;
134 4314729d 2004-04-14 devnull again: switch(argv[0][0]) {
135 4314729d 2004-04-14 devnull case '-':
136 4314729d 2004-04-14 devnull argv[0]++;
137 4314729d 2004-04-14 devnull goto again;
138 4314729d 2004-04-14 devnull case 'l': /* label for plot */
139 4314729d 2004-04-14 devnull p1 = titlebuf;
140 4314729d 2004-04-14 devnull if (argc>=2) {
141 4314729d 2004-04-14 devnull argv++;
142 4314729d 2004-04-14 devnull argc--;
143 4314729d 2004-04-14 devnull p2 = argv[0];
144 4314729d 2004-04-14 devnull while (*p1++ = *p2++);
145 4314729d 2004-04-14 devnull }
146 4314729d 2004-04-14 devnull break;
147 4314729d 2004-04-14 devnull
148 4314729d 2004-04-14 devnull case 'd': /*disconnected,obsolete option*/
149 4314729d 2004-04-14 devnull case 'm': /*line mode*/
150 4314729d 2004-04-14 devnull mode = 0;
151 4314729d 2004-04-14 devnull if(!numb(&temp,&argc,&argv))
152 4314729d 2004-04-14 devnull break;
153 4314729d 2004-04-14 devnull if(temp>=sizeof(modes)/sizeof(*modes))
154 4314729d 2004-04-14 devnull mode = 1;
155 4314729d 2004-04-14 devnull else if(temp>=-1)
156 4314729d 2004-04-14 devnull mode = temp;
157 4314729d 2004-04-14 devnull break;
158 4314729d 2004-04-14 devnull
159 4314729d 2004-04-14 devnull case 'o':
160 4314729d 2004-04-14 devnull if(numb(&temp,&argc,&argv) && temp>=1)
161 4314729d 2004-04-14 devnull ovlay = temp;
162 4314729d 2004-04-14 devnull break;
163 4314729d 2004-04-14 devnull case 'a': /*automatic abscissas*/
164 4314729d 2004-04-14 devnull absf = 1;
165 4314729d 2004-04-14 devnull dx = 1;
166 4314729d 2004-04-14 devnull if(!numb(&dx,&argc,&argv))
167 4314729d 2004-04-14 devnull break;
168 4314729d 2004-04-14 devnull if(numb(&absbot,&argc,&argv))
169 4314729d 2004-04-14 devnull absf = 2;
170 4314729d 2004-04-14 devnull break;
171 4314729d 2004-04-14 devnull
172 4314729d 2004-04-14 devnull case 's': /*save screen, overlay plot*/
173 4314729d 2004-04-14 devnull erasf = 0;
174 4314729d 2004-04-14 devnull break;
175 4314729d 2004-04-14 devnull
176 4314729d 2004-04-14 devnull case 'g': /*grid style 0 none, 1 ticks, 2 full*/
177 4314729d 2004-04-14 devnull gridf = 0;
178 4314729d 2004-04-14 devnull if(!numb(&temp,&argc,&argv))
179 4314729d 2004-04-14 devnull temp = argv[0][1]-'0'; /*for caompatibility*/
180 4314729d 2004-04-14 devnull if(temp>=0&&temp<=2)
181 4314729d 2004-04-14 devnull gridf = temp;
182 4314729d 2004-04-14 devnull break;
183 4314729d 2004-04-14 devnull
184 4314729d 2004-04-14 devnull case 'c': /*character(s) for plotting*/
185 4314729d 2004-04-14 devnull if(argc >= 2) {
186 4314729d 2004-04-14 devnull symbf = 1;
187 4314729d 2004-04-14 devnull plotsymb = argv[1];
188 4314729d 2004-04-14 devnull argv++;
189 4314729d 2004-04-14 devnull argc--;
190 4314729d 2004-04-14 devnull }
191 4314729d 2004-04-14 devnull break;
192 4314729d 2004-04-14 devnull
193 4314729d 2004-04-14 devnull case 't': /*transpose*/
194 4314729d 2004-04-14 devnull transf = 1;
195 4314729d 2004-04-14 devnull break;
196 4314729d 2004-04-14 devnull case 'e': /*equal scales*/
197 4314729d 2004-04-14 devnull equf = 1;
198 4314729d 2004-04-14 devnull break;
199 4314729d 2004-04-14 devnull case 'b': /*breaks*/
200 4314729d 2004-04-14 devnull brkf = 1;
201 4314729d 2004-04-14 devnull break;
202 4314729d 2004-04-14 devnull case 'x': /*x limits */
203 4314729d 2004-04-14 devnull limread(&xd,&argc,&argv);
204 4314729d 2004-04-14 devnull break;
205 4314729d 2004-04-14 devnull case 'y':
206 4314729d 2004-04-14 devnull limread(&yd,&argc,&argv);
207 4314729d 2004-04-14 devnull break;
208 4314729d 2004-04-14 devnull case 'h': /*set height of plot */
209 4314729d 2004-04-14 devnull if(!numb(&yd.xsize, &argc,&argv))
210 4314729d 2004-04-14 devnull badarg();
211 4314729d 2004-04-14 devnull break;
212 4314729d 2004-04-14 devnull case 'w': /*set width of plot */
213 4314729d 2004-04-14 devnull if(!numb(&xd.xsize, &argc, &argv))
214 4314729d 2004-04-14 devnull badarg();
215 4314729d 2004-04-14 devnull break;
216 4314729d 2004-04-14 devnull case 'r': /* set offset to right */
217 4314729d 2004-04-14 devnull if(!numb(&xd.xoff, &argc, &argv))
218 4314729d 2004-04-14 devnull badarg();
219 4314729d 2004-04-14 devnull break;
220 4314729d 2004-04-14 devnull case 'u': /*set offset up the screen*/
221 4314729d 2004-04-14 devnull if(!numb(&yd.xoff,&argc,&argv))
222 4314729d 2004-04-14 devnull badarg();
223 4314729d 2004-04-14 devnull break;
224 4314729d 2004-04-14 devnull default:
225 4314729d 2004-04-14 devnull badarg();
226 4314729d 2004-04-14 devnull }
227 4314729d 2004-04-14 devnull }
228 4314729d 2004-04-14 devnull }
229 4314729d 2004-04-14 devnull
230 4314729d 2004-04-14 devnull void limread(struct xy *p, int *argcp, char ***argvp){
231 4314729d 2004-04-14 devnull if(*argcp>1 && (*argvp)[1][0]=='l') {
232 4314729d 2004-04-14 devnull (*argcp)--;
233 4314729d 2004-04-14 devnull (*argvp)++;
234 4314729d 2004-04-14 devnull p->xf = log10;
235 4314729d 2004-04-14 devnull }
236 4314729d 2004-04-14 devnull if(!numb(&p->xlb,argcp,argvp))
237 4314729d 2004-04-14 devnull return;
238 4314729d 2004-04-14 devnull p->xlbf = 1;
239 4314729d 2004-04-14 devnull if(!numb(&p->xub,argcp,argvp))
240 4314729d 2004-04-14 devnull return;
241 4314729d 2004-04-14 devnull p->xubf = 1;
242 4314729d 2004-04-14 devnull if(!numb(&p->xquant,argcp,argvp))
243 4314729d 2004-04-14 devnull return;
244 4314729d 2004-04-14 devnull p->xqf = 1;
245 b237df90 2004-05-16 devnull }
246 b237df90 2004-05-16 devnull
247 b237df90 2004-05-16 devnull #ifdef NOTDEF
248 b237df90 2004-05-16 devnull isdigit(char c){
249 b237df90 2004-05-16 devnull return '0'<=c && c<='9';
250 4314729d 2004-04-14 devnull }
251 b237df90 2004-05-16 devnull #endif
252 4314729d 2004-04-14 devnull
253 4314729d 2004-04-14 devnull int
254 4314729d 2004-04-14 devnull numb(float *np, int *argcp, char ***argvp){
255 4314729d 2004-04-14 devnull char c;
256 4314729d 2004-04-14 devnull
257 4314729d 2004-04-14 devnull if(*argcp <= 1)
258 4314729d 2004-04-14 devnull return(0);
259 4314729d 2004-04-14 devnull while((c=(*argvp)[1][0]) == '+')
260 4314729d 2004-04-14 devnull (*argvp)[1]++;
261 4314729d 2004-04-14 devnull if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.'))
262 4314729d 2004-04-14 devnull return(0);
263 4314729d 2004-04-14 devnull *np = atof((*argvp)[1]);
264 4314729d 2004-04-14 devnull (*argcp)--;
265 4314729d 2004-04-14 devnull (*argvp)++;
266 4314729d 2004-04-14 devnull return(1);
267 4314729d 2004-04-14 devnull }
268 4314729d 2004-04-14 devnull
269 4314729d 2004-04-14 devnull void readin(void){
270 4314729d 2004-04-14 devnull int i, t;
271 4314729d 2004-04-14 devnull struct val *temp;
272 4314729d 2004-04-14 devnull
273 4314729d 2004-04-14 devnull if(absf==1) {
274 4314729d 2004-04-14 devnull if(xd.xlbf)
275 4314729d 2004-04-14 devnull absbot = xd.xlb;
276 4314729d 2004-04-14 devnull else if(xd.xf==log10)
277 4314729d 2004-04-14 devnull absbot = 1;
278 4314729d 2004-04-14 devnull }
279 4314729d 2004-04-14 devnull for(;;) {
280 4314729d 2004-04-14 devnull temp = (struct val *)realloc((char*)xx,
281 4314729d 2004-04-14 devnull (unsigned)(n+ovlay)*sizeof(struct val));
282 4314729d 2004-04-14 devnull if(temp==0)
283 4314729d 2004-04-14 devnull return;
284 4314729d 2004-04-14 devnull xx = temp;
285 4314729d 2004-04-14 devnull if(absf)
286 4314729d 2004-04-14 devnull xx[n].xv = n*dx/ovlay + absbot;
287 4314729d 2004-04-14 devnull else
288 4314729d 2004-04-14 devnull if(!getfloat(&xx[n].xv))
289 4314729d 2004-04-14 devnull return;
290 4314729d 2004-04-14 devnull t = 0; /* silence compiler */
291 4314729d 2004-04-14 devnull for(i=0;i<ovlay;i++) {
292 4314729d 2004-04-14 devnull xx[n+i].xv = xx[n].xv;
293 4314729d 2004-04-14 devnull if(!getfloat(&xx[n+i].yv))
294 4314729d 2004-04-14 devnull return;
295 4314729d 2004-04-14 devnull xx[n+i].lblptr = -1;
296 4314729d 2004-04-14 devnull t = getstring();
297 4314729d 2004-04-14 devnull if(t>0)
298 4314729d 2004-04-14 devnull xx[n+i].lblptr = copystring(t);
299 4314729d 2004-04-14 devnull if(t<0 && i+1<ovlay)
300 4314729d 2004-04-14 devnull return;
301 4314729d 2004-04-14 devnull }
302 4314729d 2004-04-14 devnull n += ovlay;
303 4314729d 2004-04-14 devnull if(t<0)
304 4314729d 2004-04-14 devnull return;
305 4314729d 2004-04-14 devnull }
306 4314729d 2004-04-14 devnull }
307 4314729d 2004-04-14 devnull
308 4314729d 2004-04-14 devnull void transpose(void){
309 4314729d 2004-04-14 devnull int i;
310 4314729d 2004-04-14 devnull float f;
311 4314729d 2004-04-14 devnull struct xy t;
312 4314729d 2004-04-14 devnull if(!transf)
313 4314729d 2004-04-14 devnull return;
314 4314729d 2004-04-14 devnull t = xd; xd = yd; yd = t;
315 4314729d 2004-04-14 devnull for(i= 0;i<n;i++) {
316 4314729d 2004-04-14 devnull f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f;
317 4314729d 2004-04-14 devnull }
318 4314729d 2004-04-14 devnull }
319 4314729d 2004-04-14 devnull
320 4314729d 2004-04-14 devnull int copystring(int k){
321 4314729d 2004-04-14 devnull char *temp;
322 4314729d 2004-04-14 devnull int i;
323 4314729d 2004-04-14 devnull int q;
324 4314729d 2004-04-14 devnull
325 4314729d 2004-04-14 devnull temp = realloc(labels,(unsigned)(labelsiz+1+k));
326 4314729d 2004-04-14 devnull if(temp==0)
327 4314729d 2004-04-14 devnull return(0);
328 4314729d 2004-04-14 devnull labels = temp;
329 4314729d 2004-04-14 devnull q = labelsiz;
330 4314729d 2004-04-14 devnull for(i=0;i<=k;i++)
331 4314729d 2004-04-14 devnull labels[labelsiz++] = labbuf[i];
332 4314729d 2004-04-14 devnull return(q);
333 4314729d 2004-04-14 devnull }
334 4314729d 2004-04-14 devnull
335 4314729d 2004-04-14 devnull float modceil(float f, float t){
336 4314729d 2004-04-14 devnull
337 4314729d 2004-04-14 devnull t = fabs(t);
338 4314729d 2004-04-14 devnull return(ceil(f/t)*t);
339 4314729d 2004-04-14 devnull }
340 4314729d 2004-04-14 devnull
341 4314729d 2004-04-14 devnull float
342 4314729d 2004-04-14 devnull modfloor(float f, float t){
343 4314729d 2004-04-14 devnull t = fabs(t);
344 4314729d 2004-04-14 devnull return(floor(f/t)*t);
345 4314729d 2004-04-14 devnull }
346 4314729d 2004-04-14 devnull
347 4314729d 2004-04-14 devnull void getlim(struct xy *p, struct val *v){
348 4314729d 2004-04-14 devnull int i;
349 4314729d 2004-04-14 devnull
350 4314729d 2004-04-14 devnull i = 0;
351 4314729d 2004-04-14 devnull do {
352 4314729d 2004-04-14 devnull if(!p->xlbf && p->xlb>v[i].xv)
353 4314729d 2004-04-14 devnull p->xlb = v[i].xv;
354 4314729d 2004-04-14 devnull if(!p->xubf && p->xub<v[i].xv)
355 4314729d 2004-04-14 devnull p->xub = v[i].xv;
356 4314729d 2004-04-14 devnull i++;
357 4314729d 2004-04-14 devnull } while(i < n);
358 4314729d 2004-04-14 devnull }
359 4314729d 2004-04-14 devnull
360 4314729d 2004-04-14 devnull void setlim(struct xy *p){
361 4314729d 2004-04-14 devnull float t,delta,sign;
362 4314729d 2004-04-14 devnull struct z z;
363 4314729d 2004-04-14 devnull int mark[50];
364 4314729d 2004-04-14 devnull float lb,ub;
365 4314729d 2004-04-14 devnull int lbf,ubf;
366 4314729d 2004-04-14 devnull
367 4314729d 2004-04-14 devnull lb = p->xlb;
368 4314729d 2004-04-14 devnull ub = p->xub;
369 4314729d 2004-04-14 devnull delta = ub-lb;
370 4314729d 2004-04-14 devnull if(p->xqf) {
371 4314729d 2004-04-14 devnull if(delta*p->xquant <=0 )
372 4314729d 2004-04-14 devnull badarg();
373 4314729d 2004-04-14 devnull return;
374 4314729d 2004-04-14 devnull }
375 4314729d 2004-04-14 devnull sign = 1;
376 4314729d 2004-04-14 devnull lbf = p->xlbf;
377 4314729d 2004-04-14 devnull ubf = p->xubf;
378 4314729d 2004-04-14 devnull if(delta < 0) {
379 4314729d 2004-04-14 devnull sign = -1;
380 4314729d 2004-04-14 devnull t = lb;
381 4314729d 2004-04-14 devnull lb = ub;
382 4314729d 2004-04-14 devnull ub = t;
383 4314729d 2004-04-14 devnull t = lbf;
384 4314729d 2004-04-14 devnull lbf = ubf;
385 4314729d 2004-04-14 devnull ubf = t;
386 4314729d 2004-04-14 devnull }
387 4314729d 2004-04-14 devnull else if(delta == 0) {
388 4314729d 2004-04-14 devnull if(ub > 0) {
389 4314729d 2004-04-14 devnull ub = 2*ub;
390 4314729d 2004-04-14 devnull lb = 0;
391 4314729d 2004-04-14 devnull }
392 4314729d 2004-04-14 devnull else
393 4314729d 2004-04-14 devnull if(lb < 0) {
394 4314729d 2004-04-14 devnull lb = 2*lb;
395 4314729d 2004-04-14 devnull ub = 0;
396 4314729d 2004-04-14 devnull }
397 4314729d 2004-04-14 devnull else {
398 4314729d 2004-04-14 devnull ub = 1;
399 4314729d 2004-04-14 devnull lb = -1;
400 4314729d 2004-04-14 devnull }
401 4314729d 2004-04-14 devnull }
402 4314729d 2004-04-14 devnull if(p->xf==log10 && lb>0 && ub>lb) {
403 4314729d 2004-04-14 devnull z = setloglim(lbf,ubf,lb,ub);
404 4314729d 2004-04-14 devnull p->xlb = z.lb;
405 4314729d 2004-04-14 devnull p->xub = z.ub;
406 4314729d 2004-04-14 devnull p->xmult *= z.mult;
407 4314729d 2004-04-14 devnull p->xquant = z.quant;
408 4314729d 2004-04-14 devnull if(setmark(mark,p)<2) {
409 4314729d 2004-04-14 devnull p->xqf = lbf = ubf = 1;
410 4314729d 2004-04-14 devnull lb = z.lb; ub = z.ub;
411 4314729d 2004-04-14 devnull } else
412 4314729d 2004-04-14 devnull return;
413 4314729d 2004-04-14 devnull }
414 4314729d 2004-04-14 devnull z = setlinlim(lbf,ubf,lb,ub);
415 4314729d 2004-04-14 devnull if(sign > 0) {
416 4314729d 2004-04-14 devnull p->xlb = z.lb;
417 4314729d 2004-04-14 devnull p->xub = z.ub;
418 4314729d 2004-04-14 devnull } else {
419 4314729d 2004-04-14 devnull p->xlb = z.ub;
420 4314729d 2004-04-14 devnull p->xub = z.lb;
421 4314729d 2004-04-14 devnull }
422 4314729d 2004-04-14 devnull p->xmult *= z.mult;
423 4314729d 2004-04-14 devnull p->xquant = sign*z.quant;
424 4314729d 2004-04-14 devnull }
425 4314729d 2004-04-14 devnull
426 4314729d 2004-04-14 devnull struct z
427 4314729d 2004-04-14 devnull setloglim(int lbf, int ubf, float lb, float ub){
428 4314729d 2004-04-14 devnull float r,s,t;
429 4314729d 2004-04-14 devnull struct z z;
430 4314729d 2004-04-14 devnull
431 4314729d 2004-04-14 devnull for(s=1; lb*s<1; s*=10) ;
432 4314729d 2004-04-14 devnull lb *= s;
433 4314729d 2004-04-14 devnull ub *= s;
434 4314729d 2004-04-14 devnull for(r=1; 10*r<=lb; r*=10) ;
435 4314729d 2004-04-14 devnull for(t=1; t<ub; t*=10) ;
436 4314729d 2004-04-14 devnull z.lb = !lbf ? r : lb;
437 4314729d 2004-04-14 devnull z.ub = !ubf ? t : ub;
438 4314729d 2004-04-14 devnull if(ub/lb<100) {
439 4314729d 2004-04-14 devnull if(!lbf) {
440 4314729d 2004-04-14 devnull if(lb >= 5*z.lb)
441 4314729d 2004-04-14 devnull z.lb *= 5;
442 4314729d 2004-04-14 devnull else if(lb >= 2*z.lb)
443 4314729d 2004-04-14 devnull z.lb *= 2;
444 4314729d 2004-04-14 devnull }
445 4314729d 2004-04-14 devnull if(!ubf) {
446 4314729d 2004-04-14 devnull if(ub*5 <= z.ub)
447 4314729d 2004-04-14 devnull z.ub /= 5;
448 4314729d 2004-04-14 devnull else if(ub*2 <= z.ub)
449 4314729d 2004-04-14 devnull z.ub /= 2;
450 4314729d 2004-04-14 devnull }
451 4314729d 2004-04-14 devnull }
452 4314729d 2004-04-14 devnull z.mult = s;
453 4314729d 2004-04-14 devnull z.quant = r;
454 4314729d 2004-04-14 devnull return(z);
455 4314729d 2004-04-14 devnull }
456 4314729d 2004-04-14 devnull
457 4314729d 2004-04-14 devnull struct z
458 4314729d 2004-04-14 devnull setlinlim(int lbf, int ubf, float xlb, float xub){
459 4314729d 2004-04-14 devnull struct z z;
460 4314729d 2004-04-14 devnull float r,s,delta;
461 4314729d 2004-04-14 devnull float ub,lb;
462 4314729d 2004-04-14 devnull
463 4314729d 2004-04-14 devnull loop:
464 4314729d 2004-04-14 devnull ub = xub;
465 4314729d 2004-04-14 devnull lb = xlb;
466 4314729d 2004-04-14 devnull delta = ub - lb;
467 4314729d 2004-04-14 devnull /*scale up by s, a power of 10, so range (delta) exceeds 1*/
468 4314729d 2004-04-14 devnull /*find power of 10 quantum, r, such that delta/10<=r<delta*/
469 4314729d 2004-04-14 devnull r = s = 1;
470 4314729d 2004-04-14 devnull while(delta*s < 10)
471 4314729d 2004-04-14 devnull s *= 10;
472 4314729d 2004-04-14 devnull delta *= s;
473 4314729d 2004-04-14 devnull while(10*r < delta)
474 4314729d 2004-04-14 devnull r *= 10;
475 4314729d 2004-04-14 devnull lb *= s;
476 4314729d 2004-04-14 devnull ub *= s;
477 4314729d 2004-04-14 devnull /*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/
478 4314729d 2004-04-14 devnull if(r>=delta/2)
479 4314729d 2004-04-14 devnull r /= 2;
480 4314729d 2004-04-14 devnull else if(r<delta/5)
481 4314729d 2004-04-14 devnull r *= 2;
482 4314729d 2004-04-14 devnull z.ub = ubf? ub: modceil(ub,r);
483 4314729d 2004-04-14 devnull z.lb = lbf? lb: modfloor(lb,r);
484 4314729d 2004-04-14 devnull if(!lbf && z.lb<=r && z.lb>0) {
485 4314729d 2004-04-14 devnull xlb = 0;
486 4314729d 2004-04-14 devnull goto loop;
487 4314729d 2004-04-14 devnull }
488 4314729d 2004-04-14 devnull else if(!ubf && z.ub>=-r && z.ub<0) {
489 4314729d 2004-04-14 devnull xub = 0;
490 4314729d 2004-04-14 devnull goto loop;
491 4314729d 2004-04-14 devnull }
492 4314729d 2004-04-14 devnull z.quant = r;
493 4314729d 2004-04-14 devnull z.mult = s;
494 4314729d 2004-04-14 devnull return(z);
495 4314729d 2004-04-14 devnull }
496 4314729d 2004-04-14 devnull
497 4314729d 2004-04-14 devnull void scale(struct xy *p){
498 4314729d 2004-04-14 devnull float edge;
499 4314729d 2004-04-14 devnull
500 4314729d 2004-04-14 devnull setlim(p);
501 4314729d 2004-04-14 devnull edge = top-bot;
502 4314729d 2004-04-14 devnull p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb));
503 4314729d 2004-04-14 devnull p->xbot = bot + edge*p->xoff;
504 4314729d 2004-04-14 devnull p->xtop = p->xbot + (top-bot)*p->xsize;
505 4314729d 2004-04-14 devnull p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5;
506 4314729d 2004-04-14 devnull }
507 4314729d 2004-04-14 devnull
508 4314729d 2004-04-14 devnull void equilibrate(struct xy *p, struct xy *q){
509 4314729d 2004-04-14 devnull if(p->xlbf|| /* needn't test xubf; it implies xlbf*/
510 4314729d 2004-04-14 devnull q->xubf&&q->xlb>q->xub)
511 4314729d 2004-04-14 devnull return;
512 4314729d 2004-04-14 devnull if(p->xlb>q->xlb) {
513 4314729d 2004-04-14 devnull p->xlb = q->xlb;
514 4314729d 2004-04-14 devnull p->xlbf = q->xlbf;
515 4314729d 2004-04-14 devnull }
516 4314729d 2004-04-14 devnull if(p->xub<q->xub) {
517 4314729d 2004-04-14 devnull p->xub = q->xub;
518 4314729d 2004-04-14 devnull p->xubf = q->xubf;
519 4314729d 2004-04-14 devnull }
520 4314729d 2004-04-14 devnull }
521 4314729d 2004-04-14 devnull
522 4314729d 2004-04-14 devnull void axes(void){
523 4314729d 2004-04-14 devnull int i;
524 4314729d 2004-04-14 devnull int mark[50];
525 4314729d 2004-04-14 devnull int xn, yn;
526 4314729d 2004-04-14 devnull if(gridf==0)
527 4314729d 2004-04-14 devnull return;
528 4314729d 2004-04-14 devnull
529 4314729d 2004-04-14 devnull line(xd.xbot,yd.xbot,xd.xtop,yd.xbot);
530 4314729d 2004-04-14 devnull vec(xd.xtop,yd.xtop);
531 4314729d 2004-04-14 devnull vec(xd.xbot,yd.xtop);
532 4314729d 2004-04-14 devnull vec(xd.xbot,yd.xbot);
533 4314729d 2004-04-14 devnull
534 4314729d 2004-04-14 devnull xn = setmark(mark,&xd);
535 4314729d 2004-04-14 devnull for(i=0; i<xn; i++) {
536 4314729d 2004-04-14 devnull if(gridf==2)
537 4314729d 2004-04-14 devnull line(mark[i],yd.xbot,mark[i],yd.xtop);
538 4314729d 2004-04-14 devnull if(gridf==1) {
539 4314729d 2004-04-14 devnull line(mark[i],yd.xbot,mark[i],yd.xbot+tick);
540 4314729d 2004-04-14 devnull line(mark[i],yd.xtop-tick,mark[i],yd.xtop);
541 4314729d 2004-04-14 devnull }
542 4314729d 2004-04-14 devnull }
543 4314729d 2004-04-14 devnull yn = setmark(mark,&yd);
544 4314729d 2004-04-14 devnull for(i=0; i<yn; i++) {
545 4314729d 2004-04-14 devnull if(gridf==2)
546 4314729d 2004-04-14 devnull line(xd.xbot,mark[i],xd.xtop,mark[i]);
547 4314729d 2004-04-14 devnull if(gridf==1) {
548 4314729d 2004-04-14 devnull line(xd.xbot,mark[i],xd.xbot+tick,mark[i]);
549 4314729d 2004-04-14 devnull line(xd.xtop-tick,mark[i],xd.xtop,mark[i]);
550 4314729d 2004-04-14 devnull }
551 4314729d 2004-04-14 devnull }
552 4314729d 2004-04-14 devnull }
553 4314729d 2004-04-14 devnull
554 4314729d 2004-04-14 devnull int
555 4314729d 2004-04-14 devnull setmark(int *xmark, struct xy *p){
556 4314729d 2004-04-14 devnull int xn = 0;
557 4314729d 2004-04-14 devnull float x,xl,xu;
558 4314729d 2004-04-14 devnull float q;
559 4314729d 2004-04-14 devnull if(p->xf==log10&&!p->xqf) {
560 4314729d 2004-04-14 devnull for(x=p->xquant; x<p->xub; x*=10) {
561 4314729d 2004-04-14 devnull submark(xmark,&xn,x,p);
562 4314729d 2004-04-14 devnull if(p->xub/p->xlb<=100) {
563 4314729d 2004-04-14 devnull submark(xmark,&xn,2*x,p);
564 4314729d 2004-04-14 devnull submark(xmark,&xn,5*x,p);
565 4314729d 2004-04-14 devnull }
566 4314729d 2004-04-14 devnull }
567 4314729d 2004-04-14 devnull } else {
568 4314729d 2004-04-14 devnull xn = 0;
569 4314729d 2004-04-14 devnull q = p->xquant;
570 4314729d 2004-04-14 devnull if(q>0) {
571 4314729d 2004-04-14 devnull xl = modceil(p->xlb+q/6,q);
572 4314729d 2004-04-14 devnull xu = modfloor(p->xub-q/6,q)+q/2;
573 4314729d 2004-04-14 devnull } else {
574 4314729d 2004-04-14 devnull xl = modceil(p->xub-q/6,q);
575 4314729d 2004-04-14 devnull xu = modfloor(p->xlb+q/6,q)-q/2;
576 4314729d 2004-04-14 devnull }
577 4314729d 2004-04-14 devnull for(x=xl; x<=xu; x+=fabs(p->xquant))
578 4314729d 2004-04-14 devnull xmark[xn++] = (*p->xf)(x)*p->xa + p->xb;
579 4314729d 2004-04-14 devnull }
580 4314729d 2004-04-14 devnull return(xn);
581 4314729d 2004-04-14 devnull }
582 4314729d 2004-04-14 devnull void submark(int *xmark, int *pxn, float x, struct xy *p){
583 4314729d 2004-04-14 devnull if(1.001*p->xlb < x && .999*p->xub > x)
584 4314729d 2004-04-14 devnull xmark[(*pxn)++] = log10(x)*p->xa + p->xb;
585 4314729d 2004-04-14 devnull }
586 4314729d 2004-04-14 devnull
587 4314729d 2004-04-14 devnull void plot(void){
588 4314729d 2004-04-14 devnull int ix,iy;
589 4314729d 2004-04-14 devnull int i,j;
590 4314729d 2004-04-14 devnull int conn;
591 4314729d 2004-04-14 devnull
592 4314729d 2004-04-14 devnull for(j=0;j<ovlay;j++) {
593 4314729d 2004-04-14 devnull switch(mode) {
594 4314729d 2004-04-14 devnull case -1:
595 4314729d 2004-04-14 devnull pen(modes[j%(sizeof modes/sizeof *modes-1)+1]);
596 4314729d 2004-04-14 devnull break;
597 4314729d 2004-04-14 devnull case 0:
598 4314729d 2004-04-14 devnull break;
599 4314729d 2004-04-14 devnull default:
600 4314729d 2004-04-14 devnull pen(modes[mode]);
601 4314729d 2004-04-14 devnull }
602 4314729d 2004-04-14 devnull conn = 0;
603 4314729d 2004-04-14 devnull for(i=j; i<n; i+=ovlay) {
604 4314729d 2004-04-14 devnull if(!conv(xx[i].xv,&xd,&ix) ||
605 4314729d 2004-04-14 devnull !conv(xx[i].yv,&yd,&iy)) {
606 4314729d 2004-04-14 devnull conn = 0;
607 4314729d 2004-04-14 devnull continue;
608 4314729d 2004-04-14 devnull }
609 4314729d 2004-04-14 devnull if(mode!=0) {
610 4314729d 2004-04-14 devnull if(conn != 0)
611 4314729d 2004-04-14 devnull vec(ix,iy);
612 4314729d 2004-04-14 devnull else
613 4314729d 2004-04-14 devnull move(ix,iy);
614 4314729d 2004-04-14 devnull conn = 1;
615 4314729d 2004-04-14 devnull }
616 4314729d 2004-04-14 devnull conn &= symbol(ix,iy,xx[i].lblptr);
617 4314729d 2004-04-14 devnull }
618 4314729d 2004-04-14 devnull }
619 4314729d 2004-04-14 devnull pen(modes[1]);
620 4314729d 2004-04-14 devnull }
621 4314729d 2004-04-14 devnull
622 4314729d 2004-04-14 devnull int
623 4314729d 2004-04-14 devnull conv(float xv, struct xy *p, int *ip){
624 4314729d 2004-04-14 devnull long ix;
625 4314729d 2004-04-14 devnull ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb;
626 4314729d 2004-04-14 devnull if(ix<p->xbot || ix>p->xtop)
627 4314729d 2004-04-14 devnull return(0);
628 4314729d 2004-04-14 devnull *ip = ix;
629 4314729d 2004-04-14 devnull return(1);
630 4314729d 2004-04-14 devnull }
631 4314729d 2004-04-14 devnull
632 4314729d 2004-04-14 devnull int
633 4314729d 2004-04-14 devnull getfloat(float *p){
634 4314729d 2004-04-14 devnull int i;
635 4314729d 2004-04-14 devnull
636 4314729d 2004-04-14 devnull i = scanf("%f",p);
637 4314729d 2004-04-14 devnull return(i==1);
638 4314729d 2004-04-14 devnull }
639 b237df90 2004-05-16 devnull
640 4314729d 2004-04-14 devnull int
641 4314729d 2004-04-14 devnull getstring(void){
642 4314729d 2004-04-14 devnull int i;
643 4314729d 2004-04-14 devnull char junk[20];
644 4314729d 2004-04-14 devnull i = scanf("%1s",labbuf);
645 4314729d 2004-04-14 devnull if(i==-1)
646 4314729d 2004-04-14 devnull return(-1);
647 4314729d 2004-04-14 devnull switch(*labbuf) {
648 4314729d 2004-04-14 devnull default:
649 4314729d 2004-04-14 devnull if(!isdigit(*labbuf)) {
650 4314729d 2004-04-14 devnull ungetc(*labbuf,stdin);
651 4314729d 2004-04-14 devnull i = scanf("%s",labbuf);
652 4314729d 2004-04-14 devnull break;
653 4314729d 2004-04-14 devnull }
654 4314729d 2004-04-14 devnull case '.':
655 4314729d 2004-04-14 devnull case '+':
656 4314729d 2004-04-14 devnull case '-':
657 4314729d 2004-04-14 devnull ungetc(*labbuf,stdin);
658 4314729d 2004-04-14 devnull return(0);
659 4314729d 2004-04-14 devnull case '"':
660 4314729d 2004-04-14 devnull i = scanf("%[^\"\n]",labbuf);
661 4314729d 2004-04-14 devnull scanf("%[\"]",junk);
662 4314729d 2004-04-14 devnull break;
663 4314729d 2004-04-14 devnull }
664 4314729d 2004-04-14 devnull if(i==-1)
665 4314729d 2004-04-14 devnull return(-1);
666 4314729d 2004-04-14 devnull return(strlen(labbuf));
667 4314729d 2004-04-14 devnull }
668 4314729d 2004-04-14 devnull
669 4314729d 2004-04-14 devnull int
670 4314729d 2004-04-14 devnull symbol(int ix, int iy, int k){
671 4314729d 2004-04-14 devnull
672 4314729d 2004-04-14 devnull if(symbf==0&&k<0) {
673 4314729d 2004-04-14 devnull if(mode==0)
674 4314729d 2004-04-14 devnull point(ix,iy);
675 4314729d 2004-04-14 devnull return(1);
676 4314729d 2004-04-14 devnull }
677 4314729d 2004-04-14 devnull else {
678 4314729d 2004-04-14 devnull move(ix,iy);
679 4314729d 2004-04-14 devnull text(k>=0?labels+k:plotsymb);
680 4314729d 2004-04-14 devnull move(ix,iy);
681 4314729d 2004-04-14 devnull return(!brkf|k<0);
682 4314729d 2004-04-14 devnull }
683 4314729d 2004-04-14 devnull }
684 4314729d 2004-04-14 devnull
685 4314729d 2004-04-14 devnull void title(void){
686 4314729d 2004-04-14 devnull char buf[BSIZ+100];
687 4314729d 2004-04-14 devnull buf[0] = ' ';
688 4314729d 2004-04-14 devnull buf[1] = ' ';
689 4314729d 2004-04-14 devnull buf[2] = ' ';
690 4314729d 2004-04-14 devnull strcpy(buf+3,titlebuf);
691 4314729d 2004-04-14 devnull if(erasf&&gridf) {
692 4314729d 2004-04-14 devnull axlab('x',&xd,buf);
693 4314729d 2004-04-14 devnull strcat(buf,",");
694 4314729d 2004-04-14 devnull axlab('y',&yd,buf);
695 4314729d 2004-04-14 devnull }
696 4314729d 2004-04-14 devnull move(xd.xbot,yd.xbot-60);
697 4314729d 2004-04-14 devnull text(buf);
698 4314729d 2004-04-14 devnull }
699 4314729d 2004-04-14 devnull
700 4314729d 2004-04-14 devnull void axlab(char c, struct xy *p, char *b){
701 4314729d 2004-04-14 devnull char *dir;
702 4314729d 2004-04-14 devnull dir = p->xlb<p->xub? "<=": ">=";
703 4314729d 2004-04-14 devnull sprintf(b+strlen(b), " %g %s %c%s %s %g", p->xlb/p->xmult,
704 4314729d 2004-04-14 devnull dir, c, p->xf==log10?" (log)":"", dir, p->xub/p->xmult);
705 4314729d 2004-04-14 devnull }
706 4314729d 2004-04-14 devnull
707 4314729d 2004-04-14 devnull void badarg(void){
708 4314729d 2004-04-14 devnull fprintf(stderr,"graph: error in arguments\n");
709 4314729d 2004-04-14 devnull closepl();
710 4314729d 2004-04-14 devnull exits("bad arg");
711 4314729d 2004-04-14 devnull }