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, 5 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.5 static const char RCSid[] = "$Id: tgraph.c,v 1.4 2003/08/01 14:14:24 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 schorsch 1.5 #include <math.h>
13 schorsch 1.2
14 greg 1.1 #include "tgraph.h"
15 schorsch 1.5 #include "plot.h"
16 greg 1.1
17     #define isfloat(a) (isdigit(a) || (a) == '-' || (a) == '.' || \
18     (a) == 'E' || (a) == '+' || (a) == 'e')
19    
20    
21    
22 schorsch 1.5 extern void
23     initialize(void)
24 greg 1.1 {
25     int i;
26    
27     for (i = 0; i < NCUR; i++)
28     usecurve[i] = 1;
29 schorsch 1.5 }
30 greg 1.1
31    
32 schorsch 1.5 extern void
33     option( /* record option */
34     char *s
35     )
36 greg 1.1 {
37     double atof();
38     char *sp;
39     short userror = 0;
40     int i;
41    
42 schorsch 1.3 if (s[0] == '-') {
43 greg 1.1
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 schorsch 1.3 } else {
87 greg 1.1
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 schorsch 1.3 }
106 greg 1.1
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 schorsch 1.5 extern void
114     normalize( /* get extrema from file */
115     FILE *fp,
116     FILE *fout
117     )
118 greg 1.1 {
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 schorsch 1.5 extern void
164     makeaxis( /* make and print x and y axis */
165     int flag
166     )
167 greg 1.1 {
168     double xstep, ystep, step(), pos;
169     int xorg, yorg;
170     char *format, stemp[32];
171    
172     /* set limits */
173 schorsch 1.3 if (polar) {
174 greg 1.1 if (xmax-xmin < ymax-ymin) /* null aspect for polar */
175     xmax = xmin + ymax-ymin;
176     else
177     ymax = ymin + xmax-xmin;
178 schorsch 1.3 } else {
179     if (xmnset > -FHUGE) {
180 greg 1.1 if (logx) {
181     if (xmnset > FTINY)
182     xmin = log10(xmnset);
183 schorsch 1.3 } else
184 greg 1.1 xmin = xmnset;
185 schorsch 1.3 }
186     if (xmxset < FHUGE) {
187 greg 1.1 if (logx) {
188     if (xmxset > FTINY)
189     xmax = log10(xmxset);
190 schorsch 1.3 } else
191 greg 1.1 xmax = xmxset;
192 schorsch 1.3 }
193     if (ymnset > -FHUGE) {
194 greg 1.1 if (logy) {
195     if (ymnset > FTINY)
196     ymin = log10(ymnset);
197 schorsch 1.3 } else
198 greg 1.1 ymin = ymnset;
199 schorsch 1.3 }
200     if (ymxset < FHUGE) {
201 greg 1.1 if (logy) {
202     if (ymxset > FTINY)
203     ymax = log10(ymxset);
204 schorsch 1.3 } else
205 greg 1.1 ymax = ymxset;
206 schorsch 1.3 }
207 greg 1.1 }
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 schorsch 1.3 if (polar) { /* null aspect again */
227 greg 1.1 if (xsize < ysize)
228     xmax = xmin + (xsize = ysize);
229     else
230     ymax = ymin + (ysize = xsize);
231 schorsch 1.3 }
232 greg 1.1
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 schorsch 1.3 if (flag & XTICS) {
259 greg 1.1 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 schorsch 1.3 }
266 greg 1.1 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 schorsch 1.3 if (flag & YTICS) {
292 greg 1.1 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 schorsch 1.3 }
299 greg 1.1 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 schorsch 1.5 extern int
316     isdata(
317     register char *s
318     )
319 greg 1.1 {
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 schorsch 1.5 extern int
337     islabel(
338     char *s
339     )
340 greg 1.1 {
341     int i;
342    
343     i = strlen(s) - 2;
344    
345     return(i > 0 && s[0] == '"' && s[i] == '"');
346 schorsch 1.5 }
347 greg 1.1
348    
349     double
350 schorsch 1.5 step( /* compute step size for axis */
351     double *mn,
352     double *mx
353     )
354 greg 1.1 {
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 schorsch 1.5 pown( /* raise x to an integer power */
381     double x,
382     int n
383     )
384 greg 1.1 {
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 schorsch 1.5 extern int
400     istitle(
401     char *s
402     )
403 greg 1.1 {
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 schorsch 1.5 extern int
415     isdivlab( /* return TRUE if division label(s) */
416     register char *s
417     )
418 greg 1.1 {
419    
420     return(instr(s, "division") != NULL);
421     }
422    
423    
424    
425 schorsch 1.5 extern int
426     isxlabel(
427     register char *s
428     )
429 greg 1.1 {
430     register char *xindex = instr(s, "x ");
431    
432     return(xindex != NULL && instr(xindex, "label ") != NULL);
433     }
434    
435    
436 schorsch 1.5 extern int
437     isylabel(
438     register char *s
439     )
440 greg 1.1 {
441     register char *yindex = instr(s, "y ");
442    
443     return(yindex != NULL && instr(yindex, "label ") != NULL);
444     }
445    
446    
447    
448 schorsch 1.5 extern char *
449     instr( /* return pointer to first occurrence of t in s */
450     char *s,
451     char *t
452     )
453 greg 1.1 {
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 schorsch 1.5 extern char *
475     snagquo( /* find and return quoted string within s */
476     register char *s
477     )
478 greg 1.1 {
479     register char *rval = NULL;
480    
481     for ( ; *s; s++)
482 schorsch 1.3 if (*s == '"') {
483 greg 1.1 if (rval == NULL)
484     rval = s+1;
485     else {
486     *s = '\0';
487     return(rval);
488     }
489 schorsch 1.3 }
490 greg 1.1
491     return(NULL);
492     }
493    
494    
495    
496 schorsch 1.5 extern int
497     getdata( /* get data from line */
498     char *s,
499     double *xp,
500     double *yp
501     )
502 greg 1.1 {
503     double sin(), cos();
504     int oobounds = 0;
505     double a;
506     register char *cp;
507    
508 schorsch 1.2 if ((cp = strchr(s, ',')) != NULL)
509 greg 1.1 *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 schorsch 1.3 if (logx) {
520 greg 1.1 if (*xp < FTINY)
521     oobounds++;
522     else
523     *xp = log10(*xp);
524 schorsch 1.3 }
525 greg 1.1
526 schorsch 1.3 if (logy) {
527 greg 1.1 if (*yp < FTINY)
528     oobounds++;
529     else
530     *yp = log10(*yp);
531 schorsch 1.3 }
532 greg 1.1
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 schorsch 1.5 extern void
547     symout( /* output a symbol */
548     int a0,
549     int x,
550     int y,
551     char *sname
552     )
553 greg 1.1 {
554    
555     pprim(PSEG, a0, x-symrad, y-symrad, x+symrad, y+symrad, sname);
556    
557     }
558    
559    
560 schorsch 1.5 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 greg 1.1 {
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     }