ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/tgraph.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (22 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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