xref: /plan9/sys/src/cmd/grap/plot.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include "grap.h"
5 #include "y.tab.h"
6 
line(int type,Point p1,Point p2,Attr * desc)7 void line(int type, Point p1, Point p2, Attr *desc)	/* draw a line segment */
8 {
9 	fprintf(tfd, "%s %s from %s",
10 		type==LINE ? "line" : "arrow",  desc_str(desc), xyname(p1));
11 	fprintf(tfd, " to %s", xyname(p2));	/* 'cause xyname is botched */
12 	fprintf(tfd, "\n");
13 	range(p1);
14 	range(p2);
15 }
16 
circle(double r,Point pt)17 void circle(double r, Point pt)		/* draw a circle */
18 {
19 	if (r > 0.0)
20 		fprintf(tfd, "circle rad %g at %s\n", r, xyname(pt));
21 	else
22 		fprintf(tfd, "\"\\s-3\\(ob\\s0\" at %s\n", xyname(pt));
23 	range(pt);
24 }
25 
xyname(Point pt)26 char *xyname(Point pt)	/* generate xy name macro for point p */
27 {
28 	static char buf[200];
29 	Obj *p;
30 
31 	p = pt.obj;
32 	if (p->log & XFLAG) {
33 		if (pt.x <= 0.0)
34 			ERROR "can't take log of x coord %g", pt.x FATAL;
35 		logit(pt.x);
36 	}
37 	if (p->log & YFLAG) {
38 		if (pt.y <= 0.0)
39 			ERROR "can't take log of y coord %g", pt.y FATAL;
40 		logit(pt.y);
41 	}
42 	sprintf(buf, "xy_%s(%g,%g)", p->name, pt.x, pt.y);
43 	return buf;	/* WATCH IT:  static */
44 }
45 
pic(char * s)46 void pic(char *s)	/* fire out pic stuff directly */
47 {
48 	while (*s == ' ')
49 		s++;
50 	fprintf(tfd, "%s\n", s);
51 }
52 
53 int	auto_x	= 0;	/* counts abscissa if none provided */
54 
numlist(void)55 void numlist(void)	/* print numbers in default way */
56 {
57 	Obj *p;
58 	Point pt;
59 	int i;
60 	static char *spot = "\\(bu";
61 	Attr *ap;
62 
63 	p = pt.obj = lookup(curr_coord, 1);
64 	if (nnum == 1) {
65 		nnum = 2;
66 		num[1] = num[0];
67 		num[0] = ++auto_x;
68 	}
69 	pt.x = num[0];
70 	if (p->attr && p->attr->sval)
71 		spot = p->attr->sval;
72 	for (i = 1; i < nnum; i++) {
73 		pt.y = num[i];
74 		if (p->attr == 0 || p->attr->type == 0) {
75 			ap = makesattr(tostring(spot));
76 			plot(ap, pt);
77 		} else
78 			next(p, pt, p->attr);
79 	}
80 	nnum = 0;
81 }
82 
plot(Attr * sl,Point pt)83 void plot(Attr *sl, Point pt)	/* put stringlist sl at point pt */
84 {
85 	fprintf(tfd, "%s at %s\n", slprint(sl), xyname(pt));
86 	range(pt);
87 	freeattr(sl);
88 }
89 
plotnum(double f,char * fmt,Point pt)90 void plotnum(double f, char *fmt, Point pt)	/* plot value f at point */
91 {
92 	char buf[100];
93 
94 	if (fmt) {
95 		sprintf(buf, fmt, f);
96 		free(fmt);
97 	} else if (f >= 0.0)
98 		sprintf(buf, "%g", f);
99 	else
100 		sprintf(buf, "\\-%g", -f);
101 	fprintf(tfd, "\"%s\" at %s\n", buf, xyname(pt));
102 	range(pt);
103 }
104 
drawdesc(int type,Obj * p,Attr * desc,char * s)105 void drawdesc(int type, Obj *p, Attr *desc, char *s)	/* set line description for p */
106 {
107 	p->attr = desc;
108 	p->attr->sval = s;
109 	if (type == NEW) {
110 		p->first = 0;	/* so it really looks new */
111 		auto_x = 0;
112 	}
113 }
114 
next(Obj * p,Point pt,Attr * desc)115 void next(Obj *p, Point pt, Attr *desc)	/* add component to a path */
116 {
117 	char *s;
118 
119 	if (p->first == 0) {
120 		p->first++;
121 		fprintf(tfd, "L%s: %s\n", p->name, xyname(pt));
122 	} else {
123 		fprintf(tfd, "line %s from L%s to %s; L%s: Here\n",
124 			desc_str(desc->type ? desc : p->attr),
125 			p->name, xyname(pt), p->name);
126 	}
127 	if (p->attr && (s=p->attr->sval)) {
128 		/* BUG: should fix size here */
129 		fprintf(tfd, "\"%s\" at %s\n", s, xyname(pt));
130 	}
131 	range(pt);
132 }
133