ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.3
Committed: Mon Jul 21 22:30:18 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.2: +30 -23 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.3 static const char RCSid[] = "$Id: tgraph.c,v 1.2 2003/06/30 14:59:12 schorsch Exp $";
3 greg 1.1 #endif
4     /*
5     * Routines for tel-a-graph file plotting
6     *
7     * 1/20/85
8     */
9    
10 schorsch 1.2 #include <ctype.h>
11     #include <string.h>
12    
13 greg 1.1 #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 schorsch 1.3 if (s[0] == '-') {
52 greg 1.1
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 schorsch 1.3 } else {
96 greg 1.1
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 schorsch 1.3 }
115 greg 1.1
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 schorsch 1.3 if (polar) {
186 greg 1.1 if (xmax-xmin < ymax-ymin) /* null aspect for polar */
187     xmax = xmin + ymax-ymin;
188     else
189     ymax = ymin + xmax-xmin;
190 schorsch 1.3 } else {
191     if (xmnset > -FHUGE) {
192 greg 1.1 if (logx) {
193     if (xmnset > FTINY)
194     xmin = log10(xmnset);
195 schorsch 1.3 } else
196 greg 1.1 xmin = xmnset;
197 schorsch 1.3 }
198     if (xmxset < FHUGE) {
199 greg 1.1 if (logx) {
200     if (xmxset > FTINY)
201     xmax = log10(xmxset);
202 schorsch 1.3 } else
203 greg 1.1 xmax = xmxset;
204 schorsch 1.3 }
205     if (ymnset > -FHUGE) {
206 greg 1.1 if (logy) {
207     if (ymnset > FTINY)
208     ymin = log10(ymnset);
209 schorsch 1.3 } else
210 greg 1.1 ymin = ymnset;
211 schorsch 1.3 }
212     if (ymxset < FHUGE) {
213 greg 1.1 if (logy) {
214     if (ymxset > FTINY)
215     ymax = log10(ymxset);
216 schorsch 1.3 } else
217 greg 1.1 ymax = ymxset;
218 schorsch 1.3 }
219 greg 1.1 }
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 schorsch 1.3 if (polar) { /* null aspect again */
239 greg 1.1 if (xsize < ysize)
240     xmax = xmin + (xsize = ysize);
241     else
242     ymax = ymin + (ysize = xsize);
243 schorsch 1.3 }
244 greg 1.1
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     #if CPM || MAC
266     if (xstep > 1.0)
267     format = "%5.0f";
268     else
269     format = "%5.3f";
270     #else
271     format = "%5g";
272     #endif
273     if (logx)
274     format = "1e%-3.0f";
275    
276     for (pos = xmin; pos < xmax+xstep/2; pos += xstep) {
277 schorsch 1.3 if (flag & XTICS) {
278 greg 1.1 if (polar)
279     plseg(010, XCONV(pos), yorg-TSIZ/2, XCONV(pos), yorg+TSIZ/2);
280     else {
281     plseg(010, XCONV(pos), YBEG, XCONV(pos), YBEG-TSIZ);
282     plseg(010, XCONV(pos), YBEG+YSIZ-1, XCONV(pos), YBEG+YSIZ-1+TSIZ);
283     }
284 schorsch 1.3 }
285 greg 1.1 if (flag & XNUMS) {
286     sprintf(stemp, format, pos);
287     if (polar)
288     pprim(PMSTR, 020, XCONV(pos)-600, yorg-TSIZ-150,
289     XCONV(pos)-600, yorg-TSIZ-150, stemp);
290     else
291     pprim(PMSTR, 020, XCONV(pos)-600, YBEG-2*TSIZ-150,
292     XCONV(pos)-600, YBEG-2*TSIZ-150, stemp);
293     }
294     if (flag & XGRID)
295     plseg(040, XCONV(pos), YBEG, XCONV(pos), YBEG+YSIZ-1);
296     }
297     /* make y-axis */
298     if (flag & BOX) {
299     plseg(010, XBEG, YBEG, XBEG, YBEG+YSIZ-1);
300     plseg(010, XBEG+XSIZ-1, YBEG, XBEG+XSIZ-1, YBEG+YSIZ-1);
301     }
302     if (flag & ORIGIN)
303     plseg(010, xorg, YBEG, xorg, YBEG+YSIZ-1);
304    
305     #if CPM || MAC
306     if (ystep > 1.0)
307     format = "%5.0f";
308     else
309     format = "%5.3f";
310     #else
311     format = "%5g";
312     #endif
313     if (logy)
314     format = "1e%-3.0f";
315    
316     for (pos = ymin; pos < ymax+ystep/2; pos += ystep) {
317 schorsch 1.3 if (flag & YTICS) {
318 greg 1.1 if (polar)
319     plseg(010, xorg-TSIZ/2, YCONV(pos), xorg+TSIZ/2, YCONV(pos));
320     else {
321     plseg(010, XBEG, YCONV(pos), XBEG-TSIZ, YCONV(pos));
322     plseg(010, XBEG+XSIZ-1, YCONV(pos), XBEG+XSIZ-1+TSIZ, YCONV(pos));
323     }
324 schorsch 1.3 }
325 greg 1.1 if (flag & YNUMS) {
326     sprintf(stemp, format, pos);
327     if (polar)
328     pprim(PMSTR, 020, xorg-TSIZ-900, YCONV(pos)+32,
329     xorg-TSIZ-900, YCONV(pos)+32, stemp);
330     else
331     pprim(PMSTR, 020, XBEG-2*TSIZ-900, YCONV(pos)+32,
332     XBEG-2*TSIZ-900, YCONV(pos)+32, stemp);
333     }
334     if (flag & YGRID)
335     plseg(040, XBEG, YCONV(pos), XBEG+XSIZ-1, YCONV(pos));
336     }
337    
338     }
339    
340    
341    
342     isdata(s)
343    
344     register char *s;
345    
346     {
347     int commas = 0;
348    
349     while (*s)
350     if (isfloat(*s) || isspace(*s))
351     s++;
352     else if (*s == ',') {
353     commas++;
354     s++;
355     }
356     else
357     return 0;
358    
359     return commas <= 1;
360     }
361    
362    
363    
364    
365     islabel(s)
366    
367     char s[];
368    
369     {
370     int i;
371    
372     i = strlen(s) - 2;
373    
374     return(i > 0 && s[0] == '"' && s[i] == '"');
375     }
376    
377    
378    
379    
380     double
381     step(mn, mx) /* compute step size for axis */
382    
383     double *mn, *mx;
384    
385     {
386     static int steps[] = {100, 50, 20, 10, 5, 2, 1};
387     int i;
388     double fact, stp;
389     double pown(), floor(), ceil();
390    
391     if (*mx-*mn <= FTINY) {
392     stp = 1.0;
393     }
394     else {
395     fact = pown(10.0, (int)log10(*mx-*mn)-2);
396     stp = (*mx-*mn)/fact/MINDIVS;
397    
398     for (i = 0; stp < steps[i]; i++);
399     stp = steps[i]*fact;
400     }
401    
402     *mn = floor(*mn/stp) * stp;
403     *mx = ceil(*mx/stp) * stp;
404    
405     return(stp);
406     }
407    
408    
409    
410     double
411     pown(x, n) /* raise x to an integer power */
412    
413     double x;
414     int n;
415    
416     {
417     register int i;
418     double p = 1.0;
419    
420     if (n > 0)
421     for (i = 0; i < n; i++)
422     p *= x;
423     else
424     for (i = 0; i > n; i--)
425     p /= x;
426    
427     return(p);
428     }
429    
430    
431    
432    
433     istitle(s)
434    
435     char *s;
436    
437     {
438     char word[32];
439    
440     if (sscanf(s, "%10s", word) == 1)
441     return strcmp(word, "title") == 0;
442     else
443     return 0;
444     }
445    
446    
447    
448    
449     isdivlab(s) /* return TRUE if division label(s) */
450    
451     register char *s;
452    
453     {
454    
455     return(instr(s, "division") != NULL);
456     }
457    
458    
459    
460    
461     isxlabel(s)
462    
463     register char *s;
464    
465     {
466     register char *xindex = instr(s, "x ");
467    
468     return(xindex != NULL && instr(xindex, "label ") != NULL);
469     }
470    
471    
472    
473    
474     isylabel(s)
475    
476     register char *s;
477    
478     {
479     register char *yindex = instr(s, "y ");
480    
481     return(yindex != NULL && instr(yindex, "label ") != NULL);
482     }
483    
484    
485    
486     char *
487     instr(s, t) /* return pointer to first occurrence of t in s */
488    
489     char *s,
490     *t;
491    
492     {
493     register char *pt, *ps;
494    
495     do {
496    
497     ps = s;
498     pt = t;
499    
500     while (*pt && *pt == *ps++)
501     pt++;
502    
503     if (*pt == '\0')
504     return(s);
505    
506     } while (*s++);
507    
508     return(NULL);
509     }
510    
511    
512    
513    
514     char *
515     snagquo(s) /* find and return quoted string within s */
516    
517     register char *s;
518    
519     {
520     register char *rval = NULL;
521    
522     for ( ; *s; s++)
523 schorsch 1.3 if (*s == '"') {
524 greg 1.1 if (rval == NULL)
525     rval = s+1;
526     else {
527     *s = '\0';
528     return(rval);
529     }
530 schorsch 1.3 }
531 greg 1.1
532     return(NULL);
533     }
534    
535    
536    
537    
538     getdata(s, xp, yp) /* get data from line */
539    
540     char *s;
541     double *xp, *yp;
542    
543     {
544     double sin(), cos();
545     int oobounds = 0;
546     double a;
547     register char *cp;
548    
549 schorsch 1.2 if ((cp = strchr(s, ',')) != NULL)
550 greg 1.1 *cp = ' ';
551    
552     if (sscanf(s, "%lf %lf", xp, yp) != 2)
553     return(-1);
554    
555     if (*xp < xmnset || *xp > xmxset)
556     oobounds++;
557     if (*yp < ymnset || *yp > ymxset)
558     oobounds++;
559    
560 schorsch 1.3 if (logx) {
561 greg 1.1 if (*xp < FTINY)
562     oobounds++;
563     else
564     *xp = log10(*xp);
565 schorsch 1.3 }
566 greg 1.1
567 schorsch 1.3 if (logy) {
568 greg 1.1 if (*yp < FTINY)
569     oobounds++;
570     else
571     *yp = log10(*yp);
572 schorsch 1.3 }
573 greg 1.1
574     if (polar) {
575     a = *xp;
576     if (polar == DEGREES)
577     a *= PI/180.0;
578     *xp = *yp * cos(a);
579     *yp *= sin(a);
580     }
581    
582     return(oobounds ? -1 : 0);
583     }
584    
585    
586    
587    
588     symout(a0, x, y, sname) /* output a symbol */
589    
590     int a0;
591     int x, y;
592     char *sname;
593    
594     {
595    
596     pprim(PSEG, a0, x-symrad, y-symrad, x+symrad, y+symrad, sname);
597    
598     }
599    
600    
601    
602     boxstring(a0, xmn, ymn, xmx, ymx, s) /* output a string within a box */
603    
604     int a0;
605     int xmn, ymn, xmx, ymx;
606     char *s;
607    
608     {
609     int start;
610     long size;
611    
612     if (a0 & 020) { /* up or down */
613    
614     size = (long)strlen(s)*(xmx-xmn)*2/3; /* aspect ratio is 1.5 */
615    
616     if (size > ymx-ymn) {
617     size = ymx-ymn; /* squash it */
618     start = ymn;
619     } else
620     start = (ymx-ymn-(int)size)/2 + ymn; /* center it */
621    
622     pprim(PVSTR, a0, xmn, start, xmx, start+(int)size, s);
623    
624     } else { /* right or left */
625    
626     size = (long)strlen(s)*(ymx-ymn)*2/3; /* aspect ratio is 1.5 */
627    
628     if (size > xmx-xmn) {
629     size = xmx-xmn; /* squash it */
630     start = xmn;
631     } else
632     start = (xmx-xmn-(int)size)/2 + xmn; /* center it */
633    
634     pprim(PVSTR, a0, start, ymn, start+(int)size, ymx, s);
635    
636     }
637    
638     }