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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 1.2 static const char RCSid[] = "$Id: tgraph.c,v 1.1 2003/02/22 02:07:26 greg 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     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 schorsch 1.2 if ((cp = strchr(s, ',')) != NULL)
545 greg 1.1 *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     }