ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mgraph.c
Revision: 1.1
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 9 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     * mgraph.c - routines for plotting graphs from variables.
6     *
7     * 6/23/86
8     *
9     * Greg Ward Larson
10     */
11    
12     #include <stdio.h>
13    
14     #include "mgvars.h"
15    
16     #include "mgraph.h"
17    
18     extern char *progname; /* argv[0] */
19    
20     extern double goodstep(), floor(), ceil(), sin(), cos();
21    
22     static BOUNDS xbounds, ybounds; /* the boundaries for the graph */
23    
24     static double period = DEFPERIOD; /* period for polar plot */
25    
26     static double axbegin, axsize; /* the mapped x axis boundaries */
27     static double aybegin, aysize; /* the mapped y axis boundaries */
28    
29     static int npltbl[MAXCUR]; /* plottable points per curve */
30    
31     static double lastx, lasty; /* last curve postion */
32     static int nplottable; /* number of plottable points */
33     static int nplotted; /* number of plotted points */
34    
35    
36     mgraph() /* plot the current graph */
37     {
38     /* load the symbol file */
39     if (gparam[SYMFILE].flags & DEFINED)
40     minclude(gparam[SYMFILE].v.s);
41     /* check for polar plot */
42     if (gparam[PERIOD].flags & DEFINED)
43     period = varvalue(gparam[PERIOD].name);
44    
45     getbounds(); /* get the boundaries */
46     makeaxis(); /* draw the coordinate axis */
47     plotcurves(); /* plot the curves */
48    
49     mendpage(); /* advance page */
50     }
51    
52    
53     getbounds() /* compute the boundaries */
54     {
55     int i, stretchbounds();
56    
57     xbounds.min = gparam[XMIN].flags & DEFINED ?
58     varvalue(gparam[XMIN].name) - FTINY :
59     FHUGE ;
60     xbounds.max = gparam[XMAX].flags & DEFINED ?
61     varvalue(gparam[XMAX].name) + FTINY :
62     -FHUGE ;
63     ybounds.min = gparam[YMIN].flags & DEFINED ?
64     varvalue(gparam[YMIN].name) - FTINY :
65     FHUGE ;
66     ybounds.max = gparam[YMAX].flags & DEFINED ?
67     varvalue(gparam[YMAX].name) + FTINY :
68     -FHUGE ;
69    
70     nplottable = 0;
71     for (i = 0; i < MAXCUR; i++) {
72     npltbl[i] = 0;
73     mgcurve(i, stretchbounds);
74     nplottable += npltbl[i];
75     }
76     if (nplottable == 0) {
77     fprintf(stderr, "%s: no plottable data\n", progname);
78     quit(1);
79     }
80    
81     xbounds.step = gparam[XSTEP].flags & DEFINED ?
82     varvalue(gparam[XSTEP].name) :
83     period > FTINY ?
84     DEFPLSTEP*period :
85     goodstep(xbounds.max - xbounds.min) ;
86     if (!(gparam[XMIN].flags & DEFINED))
87     xbounds.min = floor(xbounds.min/xbounds.step) *
88     xbounds.step;
89     if (!(gparam[XMAX].flags & DEFINED))
90     xbounds.max = ceil(xbounds.max/xbounds.step) *
91     xbounds.step;
92     ybounds.step = gparam[YSTEP].flags & DEFINED ?
93     varvalue(gparam[YSTEP].name) :
94     period > FTINY ?
95     goodstep((ybounds.max - ybounds.min)*1.75) :
96     goodstep(ybounds.max - ybounds.min) ;
97     if (!(gparam[YMIN].flags & DEFINED))
98     ybounds.min = floor(ybounds.min/ybounds.step) *
99     ybounds.step;
100     if (!(gparam[YMAX].flags & DEFINED))
101     ybounds.max = ceil(ybounds.max/ybounds.step) *
102     ybounds.step;
103     if (gparam[XMAP].flags & DEFINED) {
104     axbegin = funvalue(gparam[XMAP].name, 1, &xbounds.min);
105     axsize = funvalue(gparam[XMAP].name, 1, &xbounds.max);
106     axsize -= axbegin;
107     } else {
108     axbegin = xbounds.min;
109     axsize = xbounds.max;
110     axsize -= axbegin;
111     }
112     if (gparam[YMAP].flags & DEFINED) {
113     aybegin = funvalue(gparam[YMAP].name, 1, &ybounds.min);
114     aysize = funvalue(gparam[YMAP].name, 1, &ybounds.max);
115     aysize -= aybegin;
116     } else {
117     aybegin = ybounds.min;
118     aysize = ybounds.max;
119     aysize -= aybegin;
120     }
121     }
122    
123    
124     makeaxis() /* draw the coordinate axis */
125     {
126     char stmp[64];
127    
128     if (period > FTINY)
129     polaraxis();
130     else
131     cartaxis();
132     /* x axis label */
133     if (gparam[XLABEL].flags & DEFINED)
134     boxstring(XL_L,XL_D,XL_R,XL_U,gparam[XLABEL].v.s,'r',0,0);
135     /* x mapping */
136     if (gparam[XMAP].flags & DEFINED) {
137     mgtoa(stmp, &gparam[XMAP]);
138     boxstring(XM_L,XM_D,XM_R,XM_U,stmp,'r',0,0);
139     }
140     /* y axis label */
141     if (gparam[YLABEL].flags & DEFINED)
142     boxstring(YL_L,YL_D,YL_R,YL_U,gparam[YLABEL].v.s,'u',0,0);
143     /* y mapping */
144     if (gparam[YMAP].flags & DEFINED) {
145     mgtoa(stmp, &gparam[YMAP]);
146     boxstring(YM_L,YM_D,YM_R,YM_U,stmp,'u',0,0);
147     }
148     /* title */
149     if (gparam[TITLE].flags & DEFINED)
150     boxstring(TI_L,TI_D,TI_R,TI_U,gparam[TITLE].v.s,'r',2,0);
151     /* subtitle */
152     if (gparam[SUBTITLE].flags & DEFINED)
153     boxstring(ST_L,ST_D,ST_R,ST_U,gparam[SUBTITLE].v.s,'r',1,0);
154     /* legend */
155     if (gparam[LEGEND].flags & DEFINED)
156     mtext(LT_X, LT_Y, gparam[LEGEND].v.s, CPI, 0);
157     }
158    
159    
160     polaraxis() /* print polar coordinate axis */
161     {
162     int lw, tstyle, t0, t1;
163     double d, d1, ybeg, xstep;
164     char stmp[64], *fmt, *goodformat();
165     /* get tick style */
166     if (gparam[TSTYLE].flags & DEFINED)
167     tstyle = varvalue(gparam[TSTYLE].name) + 0.5;
168     else
169     tstyle = DEFTSTYLE;
170     /* start of numbering */
171     ybeg = ceil(ybounds.min/ybounds.step)*ybounds.step;
172     /* theta (x) numbering */
173     fmt = goodformat(xbounds.step);
174     for (d = 0.0; d < period-FTINY; d += xbounds.step) {
175     sprintf(stmp, fmt, d);
176     d1 = d*(2*PI)/period;
177     t0 = TN_X + TN_R*cos(d1) + .5;
178     if (t0 < TN_X)
179     t0 -= strlen(stmp)*CWID;
180     mtext(t0,(int)(TN_Y+TN_R*sin(d1)+.5),stmp,CPI,0);
181     }
182     /* radius (y) numbering */
183     fmt = goodformat(ybounds.step);
184     lw = PL_R+RN_S;
185     for (d = ybeg; d <= ybounds.max+FTINY; d += ybounds.step) {
186     t0 = rconv(d);
187     if (t0 >= lw+RN_S || t0 <= lw-RN_S) {
188     sprintf(stmp, fmt, d);
189     mtext(RN_X+t0-strlen(stmp)*(CWID/2),RN_Y,stmp,CPI,0);
190     lw = t0;
191     }
192     }
193     /* frame */
194     if (gparam[FTHICK].flags & DEFINED)
195     lw = varvalue(gparam[FTHICK].name) + 0.5;
196     else
197     lw = DEFFTHICK;
198     if (lw-- > 0) {
199     drawcircle(PL_X,PL_Y,PL_R,0,lw,0);
200     switch (tstyle) {
201     case 1: /* outside */
202     t0 = 0; t1 = TLEN; break;
203     case 2: /* inside */
204     t0 = TLEN; t1 = 0; break;
205     case 3: /* accross */
206     t0 = TLEN/2; t1 = TLEN/2; break;
207     default: /* none */
208     t0 = t1 = 0; break;
209     }
210     if (t0 + t1) {
211     for (d = 0.0; d < 2*PI-FTINY;
212     d += xbounds.step*(2*PI)/period) {
213     mline((int)(PL_X+(PL_R-t0)*cos(d)+.5),
214     (int)(PL_Y+(PL_R-t0)*sin(d)+.5),
215     0, lw, 0);
216     mdraw((int)(PL_X+(PL_R+t1)*cos(d)+.5),
217     (int)(PL_Y+(PL_R+t1)*sin(d)+.5));
218     }
219     }
220     }
221     /* origin */
222     if (gparam[OTHICK].flags & DEFINED)
223     lw = varvalue(gparam[OTHICK].name) + 0.5;
224     else
225     lw = DEFOTHICK;
226     if (lw-- > 0) {
227     mline(PL_X-PL_R,PL_Y,0,lw,0);
228     mdraw(PL_X+PL_R,PL_Y);
229     mline(PL_X,PL_Y-PL_R,0,lw,0);
230     mdraw(PL_X,PL_Y+PL_R);
231     if (tstyle > 0)
232     for (d = ybeg; d <= ybounds.max+FTINY;
233     d += ybounds.step) {
234     t0 = rconv(d);
235     mline(PL_X+t0,PL_Y-TLEN/2,0,lw,0);
236     mdraw(PL_X+t0,PL_Y+TLEN/2);
237     mline(PL_X-TLEN/2,PL_Y+t0,0,lw,0);
238     mdraw(PL_X+TLEN/2,PL_Y+t0);
239     mline(PL_X-t0,PL_Y-TLEN/2,0,lw,0);
240     mdraw(PL_X-t0,PL_Y+TLEN/2);
241     mline(PL_X-TLEN/2,PL_Y-t0,0,lw,0);
242     mdraw(PL_X+TLEN/2,PL_Y-t0);
243     }
244     }
245     /* grid */
246     if (gparam[GRID].flags & DEFINED)
247     lw = varvalue(gparam[GRID].name);
248     else
249     lw = DEFGRID;
250     if (lw-- > 0) {
251     for (d = 0.0; d < PI-FTINY; d += xbounds.step*(2*PI)/period) {
252     mline((int)(PL_X+PL_R*cos(d)+.5),
253     (int)(PL_Y+PL_R*sin(d)+.5),2,0,0);
254     mdraw((int)(PL_X-PL_R*cos(d)+.5),
255     (int)(PL_Y-PL_R*sin(d)+.5));
256     }
257     for (d = ybeg; d <= ybounds.max + FTINY; d += ybounds.step)
258     drawcircle(PL_X,PL_Y,rconv(d),2,0,0);
259     }
260     }
261    
262    
263     cartaxis() /* print Cartesian coordinate axis */
264     {
265     int lw, t0, t1, tstyle;
266     double d, xbeg, ybeg;
267     char stmp[64], *fmt, *goodformat();
268     register int i;
269     /* get tick style */
270     if (gparam[TSTYLE].flags & DEFINED)
271     tstyle = varvalue(gparam[TSTYLE].name) + 0.5;
272     else
273     tstyle = DEFTSTYLE;
274     /* start of numbering */
275     xbeg = ceil(xbounds.min/xbounds.step)*xbounds.step;
276     ybeg = ceil(ybounds.min/ybounds.step)*ybounds.step;
277    
278     /* x numbering */
279     fmt = goodformat(xbounds.step);
280     lw = 2*AX_L-AX_R;
281     for (d = xbeg;
282     d <= xbounds.max + FTINY;
283     d += xbounds.step)
284     if ((i = xconv(d)) >= lw+XN_S || i <= lw-XN_S) {
285     sprintf(stmp, fmt, d);
286     mtext(i-strlen(stmp)*(CWID/2)+XN_X,XN_Y,stmp,CPI,0);
287     lw = i;
288     }
289     /* y numbering */
290     fmt = goodformat(ybounds.step);
291     lw = 2*AX_D-AX_U;
292     for (d = ybeg;
293     d <= ybounds.max + FTINY;
294     d += ybounds.step)
295     if ((i = yconv(d)) >= lw+YN_S || i <= lw-YN_S) {
296     sprintf(stmp, fmt, d);
297     mtext(YN_X-strlen(stmp)*CWID,i+YN_Y,stmp,CPI,0);
298     lw = i;
299     }
300     /* frame */
301     if (gparam[FTHICK].flags & DEFINED)
302     lw = varvalue(gparam[FTHICK].name) + 0.5;
303     else
304     lw = DEFFTHICK;
305     if (lw-- > 0) {
306     mline(AX_L,AX_D,0,lw,0);
307     mdraw(AX_R,AX_D);
308     mdraw(AX_R,AX_U);
309     mdraw(AX_L,AX_U);
310     mdraw(AX_L,AX_D);
311     switch (tstyle) {
312     case 1: /* outside */
313     t0 = 0; t1 = TLEN; break;
314     case 2: /* inside */
315     t0 = TLEN; t1 = 0; break;
316     case 3: /* accross */
317     t0 = TLEN/2; t1 = TLEN/2; break;
318     default: /* none */
319     t0 = t1 = 0; break;
320     }
321     if (t0 + t1) {
322     for (d = xbeg;
323     d <= xbounds.max + FTINY;
324     d += xbounds.step) {
325     i = xconv(d);
326     mline(i,AX_D+t0,0,lw,0);
327     mdraw(i,AX_D-t1);
328     mline(i,AX_U-t0,0,lw,0);
329     mdraw(i,AX_U+t1);
330     }
331     for (d = ybeg;
332     d <= ybounds.max + FTINY;
333     d += ybounds.step) {
334     i = yconv(d);
335     mline(AX_L+t0,i,0,lw,0);
336     mdraw(AX_L-t1,i);
337     mline(AX_R-t0,i,0,lw,0);
338     mdraw(AX_R+t1,i);
339     }
340     }
341     }
342     /* origin */
343     if (gparam[OTHICK].flags & DEFINED)
344     lw = varvalue(gparam[OTHICK].name) + 0.5;
345     else
346     lw = DEFOTHICK;
347     if (lw-- > 0) {
348     i = yconv(0.0);
349     if (i >= AX_D && i <= AX_U) {
350     mline(AX_L,i,0,lw,0);
351     mdraw(AX_R,i);
352     if (tstyle > 0)
353     for (d = xbeg; d <= xbounds.max+FTINY;
354     d += xbounds.step) {
355     mline(xconv(d),i+TLEN/2,0,lw,0);
356     mdraw(xconv(d),i-TLEN/2);
357     }
358     }
359     i = xconv(0.0);
360     if (i >= AX_L && i <= AX_R) {
361     mline(i,AX_D,0,lw,0);
362     mdraw(i,AX_U);
363     if (tstyle > 0)
364     for (d = ybeg; d <= ybounds.max+FTINY;
365     d += ybounds.step) {
366     mline(i+TLEN/2,yconv(d),0,lw,0);
367     mdraw(i-TLEN/2,yconv(d));
368     }
369     }
370     }
371     /* grid */
372     if (gparam[GRID].flags & DEFINED)
373     lw = varvalue(gparam[GRID].name);
374     else
375     lw = DEFGRID;
376     if (lw-- > 0) {
377     for (d = xbeg;
378     d <= xbounds.max + FTINY;
379     d += xbounds.step) {
380     i = xconv(d);
381     mline(i,AX_D,2,0,0);
382     mdraw(i,AX_U);
383     }
384     for (d = ybeg;
385     d <= ybounds.max + FTINY;
386     d += ybounds.step) {
387     i = yconv(d);
388     mline(AX_L,i,2,0,0);
389     mdraw(AX_R,i);
390     }
391     }
392     }
393    
394    
395     plotcurves() /* plot the curves */
396     {
397     int i, j, k, nextpoint();
398    
399     for (i = 0; i < MAXCUR; i++) {
400     nplottable = nplotted = 0;
401     lastx = FHUGE;
402     if (mgcurve(i, nextpoint) > 0 &&
403     cparam[i][CLABEL].flags & DEFINED) {
404     j = (LE_U-LE_D)/MAXCUR;
405     k = LE_U - i*j;
406     mtext(LE_L+(LE_R-LE_L)/8,k+j/3,
407     cparam[i][CLABEL].v.s,CPI,0);
408     cmsymbol(i,LE_L,k);
409     if (cmline(i,LE_L,k) == 0)
410     mdraw(LE_R-(LE_R-LE_L)/4,k);
411     }
412     }
413     }
414    
415    
416     nextpoint(c, x, y) /* plot the next point for c */
417     register int c;
418     double x, y;
419     {
420     if (inbounds(x, y)) {
421    
422     if (!(cparam[c][CNPOINTS].flags & DEFINED) ||
423     nplotted * npltbl[c] <= nplottable *
424     (int)varvalue(cparam[c][CNPOINTS].name) ) {
425     csymbol(c, x, y);
426     nplotted++;
427     }
428     nplottable++;
429     if (lastx != FHUGE)
430     climline(c, x, y, lastx, lasty);
431    
432     } else if (inbounds(lastx, lasty)) {
433    
434     climline(c, lastx, lasty, x, y);
435    
436     }
437     lastx = x;
438     lasty = y;
439     }
440    
441    
442     stretchbounds(c, x, y) /* stretch our boundaries */
443     int c;
444     double x, y;
445     {
446     if (gparam[XMIN].flags & DEFINED &&
447     x < xbounds.min)
448     return;
449     if (gparam[XMAX].flags & DEFINED &&
450     x > xbounds.max)
451     return;
452     if (gparam[YMIN].flags & DEFINED &&
453     y < ybounds.min)
454     return;
455     if (gparam[YMAX].flags & DEFINED &&
456     y > ybounds.max)
457     return;
458    
459     if (x < xbounds.min)
460     xbounds.min = x;
461     if (x > xbounds.max)
462     xbounds.max = x;
463     if (y < ybounds.min)
464     ybounds.min = y;
465     if (y > ybounds.max)
466     ybounds.max = y;
467    
468     npltbl[c]++;
469     }
470    
471    
472     #define exp10(x) exp((x)*2.3025850929940456)
473    
474     double
475     goodstep(interval) /* determine a good step for the interval */
476     double interval;
477     {
478     static int steps[] = {50, 20, 10, 5, 2, 1};
479     double fact, exp(), log10(), floor();
480     int i;
481    
482     if (interval <= FTINY)
483     return(1.0);
484     fact = exp10(floor(log10(interval)))/10;
485     interval /= fact * MINDIVS;
486     for (i = 0; interval < steps[i]; i++)
487     ;
488     return(steps[i] * fact);
489     }
490    
491     #undef exp10
492    
493    
494     int
495     xconv(x) /* convert x to meta coords */
496     double x;
497     {
498     if (gparam[XMAP].flags & DEFINED)
499     x = funvalue(gparam[XMAP].name, 1, &x);
500     x = (x - axbegin)/axsize;
501     return( AX_L + (int)(x*(AX_R-AX_L)) );
502     }
503    
504    
505     int
506     yconv(y) /* convert y to meta coords */
507     double y;
508     {
509     if (gparam[YMAP].flags & DEFINED)
510     y = funvalue(gparam[YMAP].name, 1, &y);
511     y = (y - aybegin)/aysize;
512     return( AX_D + (int)(y*(AX_U-AX_D)) );
513     }
514    
515    
516     pconv(xp, yp, t, r) /* convert theta and radius to meta coords */
517     int *xp, *yp;
518     double t, r;
519     {
520     t *= (2.*PI)/period;
521     r = rconv(r);
522     *xp = r*cos(t) + (PL_X+.5);
523     *yp = r*sin(t) + (PL_Y+.5);
524     }
525    
526    
527     int
528     rconv(r) /* convert radius to meta coords */
529     double r;
530     {
531     if (gparam[YMAP].flags & DEFINED)
532     r = funvalue(gparam[YMAP].name, 1, &r);
533    
534     return((r - aybegin)*PL_R/aysize + .5);
535     }
536    
537    
538     boxstring(xmin, ymin, xmax, ymax, s, d, width, color) /* put string in box */
539     int xmin, ymin, xmax, ymax;
540     char *s;
541     int d, width, color;
542     {
543     register long size;
544    
545     if (d == 'u' || d == 'd') { /* up or down */
546     size = strlen(s)*(xmax-xmin)/ASPECT;
547     size -= ymax-ymin;
548     size /= 2;
549     if (size < 0) { /* center */
550     ymin -= size;
551     ymax += size;
552     }
553     } else { /* left or right */
554     size = strlen(s)*(ymax-ymin)/ASPECT;
555     size -= xmax-xmin;
556     size /= 2;
557     if (size < 0) { /* center */
558     xmin -= size;
559     xmax += size;
560     }
561     }
562     mvstr(xmin, ymin, xmax, ymax, s, d, width, color); /* print */
563     }
564    
565    
566     char *
567     goodformat(d) /* return a suitable format string for d */
568     double d;
569     {
570     static char *f[5] = {"%.0f", "%.1f", "%.2f", "%.3f", "%.4f"};
571     double floor();
572     register int i;
573    
574     if (d < 0.0)
575     d = -d;
576     if (d > 1e-4 && d < 1e6)
577     for (i = 0; i < 5; i++) {
578     if (d - floor(d+FTINY) <= FTINY)
579     return(f[i]);
580     d *= 10.0;
581     }
582     return("%.1e");
583     }
584    
585    
586     drawcircle(x, y, r, typ, wid, col) /* draw a circle */
587     int x, y, r;
588     int typ, wid, col;
589     {
590     double d;
591    
592     if (r <= 0)
593     return;
594     mline(x+r, y, typ, wid, col);
595     for (d = 2*PI*PL_F; d <= 2*PI+FTINY; d += 2*PI*PL_F)
596     mdraw((int)(x+r*cos(d)+.5), (int)(y+r*sin(d)+.5));
597     }
598    
599    
600     climline(c, x, y, xout, yout) /* print line from/to out of bounds */
601     int c;
602     double x, y, xout, yout;
603     {
604     for ( ; ; )
605     if (xout < xbounds.min) {
606     yout = y + (yout - y)*(xbounds.min - x)/(xout - x);
607     xout = xbounds.min;
608     } else if (yout < ybounds.min) {
609     xout = x + (xout - x)*(ybounds.min - y)/(yout - y);
610     yout = ybounds.min;
611     } else if (xout > xbounds.max) {
612     yout = y + (yout - y)*(xbounds.max - x)/(xout - x);
613     xout = xbounds.max;
614     } else if (yout > ybounds.max) {
615     xout = x + (xout - x)*(ybounds.max - y)/(yout - y);
616     yout = ybounds.max;
617     } else {
618     cline(c, x, y, xout, yout);
619     break;
620     }
621     }
622    
623    
624     cline(c, u1, v1, u2, v2) /* print a curve line */
625     int c;
626     double u1, v1, u2, v2;
627     {
628     int x, y;
629     double ustep, vstep;
630    
631     if (period > FTINY) { /* polar */
632     if (u1 > u2) {
633     ustep = u1; u1 = u2; u2 = ustep;
634     vstep = v1; v1 = v2; v2 = vstep;
635     }
636     pconv(&x, &y, u1, v1);
637     if (cmline(c, x, y) < 0)
638     return;
639     ustep = period*PL_F;
640     if (u2-u1 > ustep) {
641     vstep = ustep*(v2-v1)/(u2-u1);
642     while ((u1 += ustep) < u2) {
643     v1 += vstep;
644     pconv(&x, &y, u1, v1);
645     mdraw(x, y);
646     }
647     }
648     pconv(&x, &y, u2, v2);
649     mdraw(x, y);
650     } else if (cmline(c, xconv(u1), yconv(v1)) == 0)
651     mdraw(xconv(u2), yconv(v2));
652     }
653    
654    
655     int
656     cmline(c, x, y) /* start curve line in meta coords */
657     int c;
658     int x, y;
659     {
660     int lw, lt, col;
661     register VARIABLE *cv;
662    
663     cv = cparam[c];
664     if (cv[CLINTYPE].flags & DEFINED)
665     lt = varvalue(cv[CLINTYPE].name);
666     else
667     lt = DEFLINTYPE;
668     if (lt-- <= 0)
669     return(-1);
670     if (cv[CTHICK].flags & DEFINED)
671     lw = varvalue(cv[CTHICK].name);
672     else
673     lw = DEFTHICK;
674     if (lw-- <= 0)
675     return(-1);
676     if (cv[CCOLOR].flags & DEFINED)
677     col = varvalue(cv[CCOLOR].name);
678     else
679     col = DEFCOLOR;
680     if (col-- <= 0)
681     return(-1);
682     mline(x, y, lt, lw, col);
683     return(0);
684     }
685    
686    
687     csymbol(c, u, v) /* plot curve symbol */
688     int c;
689     double u, v;
690     {
691     int x, y;
692    
693     if (period > FTINY) {
694     pconv(&x, &y, u, v);
695     cmsymbol(c, x, y);
696     } else
697     cmsymbol(c, xconv(u), yconv(v));
698     }
699    
700    
701     cmsymbol(c, x, y) /* print curve symbol in meta coords */
702     int c;
703     int x, y;
704     {
705     int col, ss;
706     register VARIABLE *cv;
707    
708     cv = cparam[c];
709     if (!(cv[CSYMTYPE].flags & DEFINED))
710     return;
711     if (cv[CSYMSIZE].flags & DEFINED)
712     ss = varvalue(cv[CSYMSIZE].name);
713     else
714     ss = DEFSYMSIZE;
715     if (ss <= 0)
716     return;
717     if (cv[CCOLOR].flags & DEFINED)
718     col = varvalue(cv[CCOLOR].name);
719     else
720     col = DEFCOLOR;
721     if (col-- <= 0)
722     return;
723     msegment(x-ss,y-ss,x+ss,y+ss,
724     cv[CSYMTYPE].v.s,'r',0,col);
725     }
726    
727    
728     inbounds(x, y) /* determine if x and y are within gbounds */
729     double x, y;
730     {
731     if (x < xbounds.min || x > xbounds.max)
732     return(0);
733     if (y < ybounds.min || y > ybounds.max)
734     return(0);
735     return(1);
736     }