ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.2
Committed: Mon Jun 30 14:59:12 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.1: +5 -5 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: tgraph.c,v 1.1 2003/02/22 02:07:26 greg 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 if (userror)
116 error(USER, "options are [-sSYMRAD][-g][-lx][-ly][-p{dr}][-xXMIN][+xXMAX][-yYMIN][+yYMAX][-C..|+C..]");
117
118 }
119
120
121
122
123 normalize(fp, fout) /* get extrema from file */
124
125 FILE *fp, *fout;
126
127 {
128 char line[255];
129 double x, y;
130 long npoints = 0;
131
132 ncurves = 0;
133 xmin = ymin = FHUGE;
134 xmax = ymax = -FHUGE;
135
136 while (fgets(line, sizeof line, fp) != NULL) {
137
138 if (fout != NULL)
139 fputs(line, fout);
140
141 if (islabel(line))
142
143 ncurves++;
144
145 else if (ncurves < NCUR && usecurve[ncurves] && isdata(line)) {
146
147 if (getdata(line, &x, &y) < 0)
148 continue;
149
150 if (x < xmin)
151 xmin = x;
152 if (x > xmax)
153 xmax = x;
154 if (y < ymin)
155 ymin = y;
156 if (y > ymax)
157 ymax = y;
158
159 npoints++;
160
161 }
162
163 }
164
165 if (npoints <= 1)
166 error(USER, "insufficient data in file");
167
168 }
169
170
171
172
173
174 makeaxis(flag) /* make and print x and y axis */
175
176 int flag;
177
178 {
179 double xstep, ystep, step(), pos;
180 int xorg, yorg;
181 char *format, stemp[32];
182
183 /* set limits */
184 if (polar)
185 if (xmax-xmin < ymax-ymin) /* null aspect for polar */
186 xmax = xmin + ymax-ymin;
187 else
188 ymax = ymin + xmax-xmin;
189 else {
190 if (xmnset > -FHUGE)
191 if (logx) {
192 if (xmnset > FTINY)
193 xmin = log10(xmnset);
194 }
195 else
196 xmin = xmnset;
197 if (xmxset < FHUGE)
198 if (logx) {
199 if (xmxset > FTINY)
200 xmax = log10(xmxset);
201 }
202 else
203 xmax = xmxset;
204 if (ymnset > -FHUGE)
205 if (logy) {
206 if (ymnset > FTINY)
207 ymin = log10(ymnset);
208 }
209 else
210 ymin = ymnset;
211 if (ymxset < FHUGE)
212 if (logy) {
213 if (ymxset > FTINY)
214 ymax = log10(ymxset);
215 }
216 else
217 ymax = ymxset;
218 }
219 /* set step */
220 if (logx) {
221 xmin = floor(xmin);
222 xmax = ceil(xmax);
223 xstep = 1.0;
224 } else
225 xstep = step(&xmin, &xmax);
226
227 if (logy) {
228 ymin = floor(ymin);
229 ymax = ceil(ymax);
230 ystep = 1.0;
231 } else
232 ystep = step(&ymin, &ymax);
233
234 xsize = xmax - xmin;
235 ysize = ymax - ymin;
236
237 if (polar) /* null aspect again */
238 if (xsize < ysize)
239 xmax = xmin + (xsize = ysize);
240 else
241 ymax = ymin + (ysize = xsize);
242
243 if (xmin > 0.0)
244 xorg = XBEG;
245 else if (xmax < 0.0)
246 xorg = XBEG+XSIZ-1;
247 else
248 xorg = XCONV(0.0);
249 if (ymin > 0.0)
250 yorg = YBEG;
251 else if (ymax < 0.0)
252 yorg = YBEG+YSIZ-1;
253 else
254 yorg = YCONV(0.0);
255 /* make x-axis */
256 if (flag & BOX) {
257 plseg(010, XBEG, YBEG, XBEG+XSIZ-1, YBEG);
258 plseg(010, XBEG, YBEG+YSIZ-1, XBEG+XSIZ-1, YBEG+YSIZ-1);
259 }
260 if (flag & ORIGIN)
261 plseg(010, XBEG, yorg, XBEG+XSIZ-1, yorg);
262
263 #if CPM || MAC
264 if (xstep > 1.0)
265 format = "%5.0f";
266 else
267 format = "%5.3f";
268 #else
269 format = "%5g";
270 #endif
271 if (logx)
272 format = "1e%-3.0f";
273
274 for (pos = xmin; pos < xmax+xstep/2; pos += xstep) {
275 if (flag & XTICS)
276 if (polar)
277 plseg(010, XCONV(pos), yorg-TSIZ/2, XCONV(pos), yorg+TSIZ/2);
278 else {
279 plseg(010, XCONV(pos), YBEG, XCONV(pos), YBEG-TSIZ);
280 plseg(010, XCONV(pos), YBEG+YSIZ-1, XCONV(pos), YBEG+YSIZ-1+TSIZ);
281 }
282 if (flag & XNUMS) {
283 sprintf(stemp, format, pos);
284 if (polar)
285 pprim(PMSTR, 020, XCONV(pos)-600, yorg-TSIZ-150,
286 XCONV(pos)-600, yorg-TSIZ-150, stemp);
287 else
288 pprim(PMSTR, 020, XCONV(pos)-600, YBEG-2*TSIZ-150,
289 XCONV(pos)-600, YBEG-2*TSIZ-150, stemp);
290 }
291 if (flag & XGRID)
292 plseg(040, XCONV(pos), YBEG, XCONV(pos), YBEG+YSIZ-1);
293 }
294 /* make y-axis */
295 if (flag & BOX) {
296 plseg(010, XBEG, YBEG, XBEG, YBEG+YSIZ-1);
297 plseg(010, XBEG+XSIZ-1, YBEG, XBEG+XSIZ-1, YBEG+YSIZ-1);
298 }
299 if (flag & ORIGIN)
300 plseg(010, xorg, YBEG, xorg, YBEG+YSIZ-1);
301
302 #if CPM || MAC
303 if (ystep > 1.0)
304 format = "%5.0f";
305 else
306 format = "%5.3f";
307 #else
308 format = "%5g";
309 #endif
310 if (logy)
311 format = "1e%-3.0f";
312
313 for (pos = ymin; pos < ymax+ystep/2; pos += ystep) {
314 if (flag & YTICS)
315 if (polar)
316 plseg(010, xorg-TSIZ/2, YCONV(pos), xorg+TSIZ/2, YCONV(pos));
317 else {
318 plseg(010, XBEG, YCONV(pos), XBEG-TSIZ, YCONV(pos));
319 plseg(010, XBEG+XSIZ-1, YCONV(pos), XBEG+XSIZ-1+TSIZ, YCONV(pos));
320 }
321 if (flag & YNUMS) {
322 sprintf(stemp, format, pos);
323 if (polar)
324 pprim(PMSTR, 020, xorg-TSIZ-900, YCONV(pos)+32,
325 xorg-TSIZ-900, YCONV(pos)+32, stemp);
326 else
327 pprim(PMSTR, 020, XBEG-2*TSIZ-900, YCONV(pos)+32,
328 XBEG-2*TSIZ-900, YCONV(pos)+32, stemp);
329 }
330 if (flag & YGRID)
331 plseg(040, XBEG, YCONV(pos), XBEG+XSIZ-1, YCONV(pos));
332 }
333
334 }
335
336
337
338 isdata(s)
339
340 register char *s;
341
342 {
343 int commas = 0;
344
345 while (*s)
346 if (isfloat(*s) || isspace(*s))
347 s++;
348 else if (*s == ',') {
349 commas++;
350 s++;
351 }
352 else
353 return 0;
354
355 return commas <= 1;
356 }
357
358
359
360
361 islabel(s)
362
363 char s[];
364
365 {
366 int i;
367
368 i = strlen(s) - 2;
369
370 return(i > 0 && s[0] == '"' && s[i] == '"');
371 }
372
373
374
375
376 double
377 step(mn, mx) /* compute step size for axis */
378
379 double *mn, *mx;
380
381 {
382 static int steps[] = {100, 50, 20, 10, 5, 2, 1};
383 int i;
384 double fact, stp;
385 double pown(), floor(), ceil();
386
387 if (*mx-*mn <= FTINY) {
388 stp = 1.0;
389 }
390 else {
391 fact = pown(10.0, (int)log10(*mx-*mn)-2);
392 stp = (*mx-*mn)/fact/MINDIVS;
393
394 for (i = 0; stp < steps[i]; i++);
395 stp = steps[i]*fact;
396 }
397
398 *mn = floor(*mn/stp) * stp;
399 *mx = ceil(*mx/stp) * stp;
400
401 return(stp);
402 }
403
404
405
406 double
407 pown(x, n) /* raise x to an integer power */
408
409 double x;
410 int n;
411
412 {
413 register int i;
414 double p = 1.0;
415
416 if (n > 0)
417 for (i = 0; i < n; i++)
418 p *= x;
419 else
420 for (i = 0; i > n; i--)
421 p /= x;
422
423 return(p);
424 }
425
426
427
428
429 istitle(s)
430
431 char *s;
432
433 {
434 char word[32];
435
436 if (sscanf(s, "%10s", word) == 1)
437 return strcmp(word, "title") == 0;
438 else
439 return 0;
440 }
441
442
443
444
445 isdivlab(s) /* return TRUE if division label(s) */
446
447 register char *s;
448
449 {
450
451 return(instr(s, "division") != NULL);
452 }
453
454
455
456
457 isxlabel(s)
458
459 register char *s;
460
461 {
462 register char *xindex = instr(s, "x ");
463
464 return(xindex != NULL && instr(xindex, "label ") != NULL);
465 }
466
467
468
469
470 isylabel(s)
471
472 register char *s;
473
474 {
475 register char *yindex = instr(s, "y ");
476
477 return(yindex != NULL && instr(yindex, "label ") != NULL);
478 }
479
480
481
482 char *
483 instr(s, t) /* return pointer to first occurrence of t in s */
484
485 char *s,
486 *t;
487
488 {
489 register char *pt, *ps;
490
491 do {
492
493 ps = s;
494 pt = t;
495
496 while (*pt && *pt == *ps++)
497 pt++;
498
499 if (*pt == '\0')
500 return(s);
501
502 } while (*s++);
503
504 return(NULL);
505 }
506
507
508
509
510 char *
511 snagquo(s) /* find and return quoted string within s */
512
513 register char *s;
514
515 {
516 register char *rval = NULL;
517
518 for ( ; *s; s++)
519 if (*s == '"')
520 if (rval == NULL)
521 rval = s+1;
522 else {
523 *s = '\0';
524 return(rval);
525 }
526
527 return(NULL);
528 }
529
530
531
532
533 getdata(s, xp, yp) /* get data from line */
534
535 char *s;
536 double *xp, *yp;
537
538 {
539 double sin(), cos();
540 int oobounds = 0;
541 double a;
542 register char *cp;
543
544 if ((cp = strchr(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 }