ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/mgraph.c
Revision: 1.2
Committed: Sat Nov 15 02:13:37 2003 UTC (20 years, 4 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1, rad5R3, HEAD
Changes since 1.1: +130 -57 lines
Log Message:
Continued ANSIfication, and reduced other compile warnings.

File Contents

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