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