ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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