ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.4
Committed: Fri Aug 1 14:14:24 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -15 lines
Log Message:
Eliminated CPM, MAC, and UNIX conditional compiles.

File Contents

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