ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.4
Committed: Fri Aug 1 14:14:24 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -15 lines
Log Message:
Eliminated CPM, MAC, and UNIX conditional compiles.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tgraph.c,v 1.3 2003/07/21 22:30:18 schorsch Exp $";
3 #endif
4 /*
5 * Routines for tel-a-graph file plotting
6 *
7 * 1/20/85
8 */
9
10 #include <ctype.h>
11 #include <string.h>
12
13 #include "tgraph.h"
14
15
16 #define isfloat(a) (isdigit(a) || (a) == '-' || (a) == '.' || \
17 (a) == 'E' || (a) == '+' || (a) == 'e')
18
19
20 extern double log10();
21
22
23
24
25
26 initialize()
27
28 {
29 int i;
30
31 for (i = 0; i < NCUR; i++)
32 usecurve[i] = 1;
33
34 }
35
36
37
38
39
40
41 option(s) /* record option */
42
43 char *s;
44
45 {
46 double atof();
47 char *sp;
48 short userror = 0;
49 int i;
50
51 if (s[0] == '-') {
52
53 switch(s[1]) {
54
55 case 'x':
56 xmnset = atof(s+2);
57 break;
58
59 case 'y':
60 ymnset = atof(s+2);
61 break;
62
63 case 's': /* set symbol size */
64 symrad = atoi(s+2);
65 break;
66
67 case 'l': /* log plot */
68 if (s[2] == 'x')
69 logx++;
70 else if (s[2] == 'y')
71 logy++;
72 else
73 userror++;
74 break;
75
76 case 'g': /* grid on */
77 grid = TRUE;
78 break;
79
80 case 'p': /* polar coordinates */
81 if (s[2] == 'd')
82 polar = DEGREES;
83 else if (s[2] == 'r')
84 polar = RADIANS;
85 else
86 userror++;
87 break;
88
89 default:
90 for (sp = s+1; *sp && *sp > '@' && *sp < '@'+NCUR; sp++)
91 usecurve[*sp-'@'] = 0;
92 userror = *sp;
93 break;
94 }
95 } else {
96
97 switch (s[1]) {
98
99 case 'x':
100 xmxset = atof(s+2);
101 break;
102
103 case 'y':
104 ymxset = atof(s+2);
105 break;
106
107 default:
108 for (i = 0; i < 27; i++)
109 usecurve[i] = 0;
110 for (sp = s+1; *sp && *sp > '@' && *sp < '@'+NCUR; sp++)
111 usecurve[*sp-'@'] = 1;
112 userror = *sp;
113 }
114 }
115
116 if (userror)
117 error(USER, "options are [-sSYMRAD][-g][-lx][-ly][-p{dr}][-xXMIN][+xXMAX][-yYMIN][+yYMAX][-C..|+C..]");
118
119 }
120
121
122
123
124 normalize(fp, fout) /* get extrema from file */
125
126 FILE *fp, *fout;
127
128 {
129 char line[255];
130 double x, y;
131 long npoints = 0;
132
133 ncurves = 0;
134 xmin = ymin = FHUGE;
135 xmax = ymax = -FHUGE;
136
137 while (fgets(line, sizeof line, fp) != NULL) {
138
139 if (fout != NULL)
140 fputs(line, fout);
141
142 if (islabel(line))
143
144 ncurves++;
145
146 else if (ncurves < NCUR && usecurve[ncurves] && isdata(line)) {
147
148 if (getdata(line, &x, &y) < 0)
149 continue;
150
151 if (x < xmin)
152 xmin = x;
153 if (x > xmax)
154 xmax = x;
155 if (y < ymin)
156 ymin = y;
157 if (y > ymax)
158 ymax = y;
159
160 npoints++;
161
162 }
163
164 }
165
166 if (npoints <= 1)
167 error(USER, "insufficient data in file");
168
169 }
170
171
172
173
174
175 makeaxis(flag) /* make and print x and y axis */
176
177 int flag;
178
179 {
180 double xstep, ystep, step(), pos;
181 int xorg, yorg;
182 char *format, stemp[32];
183
184 /* set limits */
185 if (polar) {
186 if (xmax-xmin < ymax-ymin) /* null aspect for polar */
187 xmax = xmin + ymax-ymin;
188 else
189 ymax = ymin + xmax-xmin;
190 } else {
191 if (xmnset > -FHUGE) {
192 if (logx) {
193 if (xmnset > FTINY)
194 xmin = log10(xmnset);
195 } else
196 xmin = xmnset;
197 }
198 if (xmxset < FHUGE) {
199 if (logx) {
200 if (xmxset > FTINY)
201 xmax = log10(xmxset);
202 } else
203 xmax = xmxset;
204 }
205 if (ymnset > -FHUGE) {
206 if (logy) {
207 if (ymnset > FTINY)
208 ymin = log10(ymnset);
209 } else
210 ymin = ymnset;
211 }
212 if (ymxset < FHUGE) {
213 if (logy) {
214 if (ymxset > FTINY)
215 ymax = log10(ymxset);
216 } else
217 ymax = ymxset;
218 }
219 }
220 /* set step */
221 if (logx) {
222 xmin = floor(xmin);
223 xmax = ceil(xmax);
224 xstep = 1.0;
225 } else
226 xstep = step(&xmin, &xmax);
227
228 if (logy) {
229 ymin = floor(ymin);
230 ymax = ceil(ymax);
231 ystep = 1.0;
232 } else
233 ystep = step(&ymin, &ymax);
234
235 xsize = xmax - xmin;
236 ysize = ymax - ymin;
237
238 if (polar) { /* null aspect again */
239 if (xsize < ysize)
240 xmax = xmin + (xsize = ysize);
241 else
242 ymax = ymin + (ysize = xsize);
243 }
244
245 if (xmin > 0.0)
246 xorg = XBEG;
247 else if (xmax < 0.0)
248 xorg = XBEG+XSIZ-1;
249 else
250 xorg = XCONV(0.0);
251 if (ymin > 0.0)
252 yorg = YBEG;
253 else if (ymax < 0.0)
254 yorg = YBEG+YSIZ-1;
255 else
256 yorg = YCONV(0.0);
257 /* make x-axis */
258 if (flag & BOX) {
259 plseg(010, XBEG, YBEG, XBEG+XSIZ-1, YBEG);
260 plseg(010, XBEG, YBEG+YSIZ-1, XBEG+XSIZ-1, YBEG+YSIZ-1);
261 }
262 if (flag & ORIGIN)
263 plseg(010, XBEG, yorg, XBEG+XSIZ-1, yorg);
264
265 format = "%5g";
266 if (logx)
267 format = "1e%-3.0f";
268
269 for (pos = xmin; pos < xmax+xstep/2; pos += xstep) {
270 if (flag & XTICS) {
271 if (polar)
272 plseg(010, XCONV(pos), yorg-TSIZ/2, XCONV(pos), yorg+TSIZ/2);
273 else {
274 plseg(010, XCONV(pos), YBEG, XCONV(pos), YBEG-TSIZ);
275 plseg(010, XCONV(pos), YBEG+YSIZ-1, XCONV(pos), YBEG+YSIZ-1+TSIZ);
276 }
277 }
278 if (flag & XNUMS) {
279 sprintf(stemp, format, pos);
280 if (polar)
281 pprim(PMSTR, 020, XCONV(pos)-600, yorg-TSIZ-150,
282 XCONV(pos)-600, yorg-TSIZ-150, stemp);
283 else
284 pprim(PMSTR, 020, XCONV(pos)-600, YBEG-2*TSIZ-150,
285 XCONV(pos)-600, YBEG-2*TSIZ-150, stemp);
286 }
287 if (flag & XGRID)
288 plseg(040, XCONV(pos), YBEG, XCONV(pos), YBEG+YSIZ-1);
289 }
290 /* make y-axis */
291 if (flag & BOX) {
292 plseg(010, XBEG, YBEG, XBEG, YBEG+YSIZ-1);
293 plseg(010, XBEG+XSIZ-1, YBEG, XBEG+XSIZ-1, YBEG+YSIZ-1);
294 }
295 if (flag & ORIGIN)
296 plseg(010, xorg, YBEG, xorg, YBEG+YSIZ-1);
297
298 format = "%5g";
299 if (logy)
300 format = "1e%-3.0f";
301
302 for (pos = ymin; pos < ymax+ystep/2; pos += ystep) {
303 if (flag & YTICS) {
304 if (polar)
305 plseg(010, xorg-TSIZ/2, YCONV(pos), xorg+TSIZ/2, YCONV(pos));
306 else {
307 plseg(010, XBEG, YCONV(pos), XBEG-TSIZ, YCONV(pos));
308 plseg(010, XBEG+XSIZ-1, YCONV(pos), XBEG+XSIZ-1+TSIZ, YCONV(pos));
309 }
310 }
311 if (flag & YNUMS) {
312 sprintf(stemp, format, pos);
313 if (polar)
314 pprim(PMSTR, 020, xorg-TSIZ-900, YCONV(pos)+32,
315 xorg-TSIZ-900, YCONV(pos)+32, stemp);
316 else
317 pprim(PMSTR, 020, XBEG-2*TSIZ-900, YCONV(pos)+32,
318 XBEG-2*TSIZ-900, YCONV(pos)+32, stemp);
319 }
320 if (flag & YGRID)
321 plseg(040, XBEG, YCONV(pos), XBEG+XSIZ-1, YCONV(pos));
322 }
323
324 }
325
326
327
328 isdata(s)
329
330 register char *s;
331
332 {
333 int commas = 0;
334
335 while (*s)
336 if (isfloat(*s) || isspace(*s))
337 s++;
338 else if (*s == ',') {
339 commas++;
340 s++;
341 }
342 else
343 return 0;
344
345 return commas <= 1;
346 }
347
348
349
350
351 islabel(s)
352
353 char s[];
354
355 {
356 int i;
357
358 i = strlen(s) - 2;
359
360 return(i > 0 && s[0] == '"' && s[i] == '"');
361 }
362
363
364
365
366 double
367 step(mn, mx) /* compute step size for axis */
368
369 double *mn, *mx;
370
371 {
372 static int steps[] = {100, 50, 20, 10, 5, 2, 1};
373 int i;
374 double fact, stp;
375 double pown(), floor(), ceil();
376
377 if (*mx-*mn <= FTINY) {
378 stp = 1.0;
379 }
380 else {
381 fact = pown(10.0, (int)log10(*mx-*mn)-2);
382 stp = (*mx-*mn)/fact/MINDIVS;
383
384 for (i = 0; stp < steps[i]; i++);
385 stp = steps[i]*fact;
386 }
387
388 *mn = floor(*mn/stp) * stp;
389 *mx = ceil(*mx/stp) * stp;
390
391 return(stp);
392 }
393
394
395
396 double
397 pown(x, n) /* raise x to an integer power */
398
399 double x;
400 int n;
401
402 {
403 register int i;
404 double p = 1.0;
405
406 if (n > 0)
407 for (i = 0; i < n; i++)
408 p *= x;
409 else
410 for (i = 0; i > n; i--)
411 p /= x;
412
413 return(p);
414 }
415
416
417
418
419 istitle(s)
420
421 char *s;
422
423 {
424 char word[32];
425
426 if (sscanf(s, "%10s", word) == 1)
427 return strcmp(word, "title") == 0;
428 else
429 return 0;
430 }
431
432
433
434
435 isdivlab(s) /* return TRUE if division label(s) */
436
437 register char *s;
438
439 {
440
441 return(instr(s, "division") != NULL);
442 }
443
444
445
446
447 isxlabel(s)
448
449 register char *s;
450
451 {
452 register char *xindex = instr(s, "x ");
453
454 return(xindex != NULL && instr(xindex, "label ") != NULL);
455 }
456
457
458
459
460 isylabel(s)
461
462 register char *s;
463
464 {
465 register char *yindex = instr(s, "y ");
466
467 return(yindex != NULL && instr(yindex, "label ") != NULL);
468 }
469
470
471
472 char *
473 instr(s, t) /* return pointer to first occurrence of t in s */
474
475 char *s,
476 *t;
477
478 {
479 register char *pt, *ps;
480
481 do {
482
483 ps = s;
484 pt = t;
485
486 while (*pt && *pt == *ps++)
487 pt++;
488
489 if (*pt == '\0')
490 return(s);
491
492 } while (*s++);
493
494 return(NULL);
495 }
496
497
498
499
500 char *
501 snagquo(s) /* find and return quoted string within s */
502
503 register char *s;
504
505 {
506 register char *rval = NULL;
507
508 for ( ; *s; s++)
509 if (*s == '"') {
510 if (rval == NULL)
511 rval = s+1;
512 else {
513 *s = '\0';
514 return(rval);
515 }
516 }
517
518 return(NULL);
519 }
520
521
522
523
524 getdata(s, xp, yp) /* get data from line */
525
526 char *s;
527 double *xp, *yp;
528
529 {
530 double sin(), cos();
531 int oobounds = 0;
532 double a;
533 register char *cp;
534
535 if ((cp = strchr(s, ',')) != NULL)
536 *cp = ' ';
537
538 if (sscanf(s, "%lf %lf", xp, yp) != 2)
539 return(-1);
540
541 if (*xp < xmnset || *xp > xmxset)
542 oobounds++;
543 if (*yp < ymnset || *yp > ymxset)
544 oobounds++;
545
546 if (logx) {
547 if (*xp < FTINY)
548 oobounds++;
549 else
550 *xp = log10(*xp);
551 }
552
553 if (logy) {
554 if (*yp < FTINY)
555 oobounds++;
556 else
557 *yp = log10(*yp);
558 }
559
560 if (polar) {
561 a = *xp;
562 if (polar == DEGREES)
563 a *= PI/180.0;
564 *xp = *yp * cos(a);
565 *yp *= sin(a);
566 }
567
568 return(oobounds ? -1 : 0);
569 }
570
571
572
573
574 symout(a0, x, y, sname) /* output a symbol */
575
576 int a0;
577 int x, y;
578 char *sname;
579
580 {
581
582 pprim(PSEG, a0, x-symrad, y-symrad, x+symrad, y+symrad, sname);
583
584 }
585
586
587
588 boxstring(a0, xmn, ymn, xmx, ymx, s) /* output a string within a box */
589
590 int a0;
591 int xmn, ymn, xmx, ymx;
592 char *s;
593
594 {
595 int start;
596 long size;
597
598 if (a0 & 020) { /* up or down */
599
600 size = (long)strlen(s)*(xmx-xmn)*2/3; /* aspect ratio is 1.5 */
601
602 if (size > ymx-ymn) {
603 size = ymx-ymn; /* squash it */
604 start = ymn;
605 } else
606 start = (ymx-ymn-(int)size)/2 + ymn; /* center it */
607
608 pprim(PVSTR, a0, xmn, start, xmx, start+(int)size, s);
609
610 } else { /* right or left */
611
612 size = (long)strlen(s)*(ymx-ymn)*2/3; /* aspect ratio is 1.5 */
613
614 if (size > xmx-xmn) {
615 size = xmx-xmn; /* squash it */
616 start = xmn;
617 } else
618 start = (xmx-xmn-(int)size)/2 + xmn; /* center it */
619
620 pprim(PVSTR, a0, start, ymn, start+(int)size, ymx, s);
621
622 }
623
624 }