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