ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.5
Committed: Sat Nov 15 02:13:37 2003 UTC (20 years, 4 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 1.4: +83 -108 lines
Log Message:
Continued ANSIfication, and reduced other compile warnings.

File Contents

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