aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/grap/plot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/grap/plot.c')
-rw-r--r--src/cmd/grap/plot.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/cmd/grap/plot.c b/src/cmd/grap/plot.c
new file mode 100644
index 00000000..ab375953
--- /dev/null
+++ b/src/cmd/grap/plot.c
@@ -0,0 +1,132 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "grap.h"
+#include "y.tab.h"
+
+void line(int type, Point p1, Point p2, Attr *desc) /* draw a line segment */
+{
+ fprintf(tfd, "%s %s from %s",
+ type==LINE ? "line" : "arrow", desc_str(desc), xyname(p1));
+ fprintf(tfd, " to %s", xyname(p2)); /* 'cause xyname is botched */
+ fprintf(tfd, "\n");
+ range(p1);
+ range(p2);
+}
+
+void circle(double r, Point pt) /* draw a circle */
+{
+ if (r > 0.0)
+ fprintf(tfd, "circle rad %g at %s\n", r, xyname(pt));
+ else
+ fprintf(tfd, "\"\\s-3\\(ob\\s0\" at %s\n", xyname(pt));
+ range(pt);
+}
+
+char *xyname(Point pt) /* generate xy name macro for point p */
+{
+ static char buf[200];
+ Obj *p;
+
+ p = pt.obj;
+ if (p->log & XFLAG) {
+ if (pt.x <= 0.0)
+ ERROR "can't take log of x coord %g", pt.x FATAL;
+ logit(pt.x);
+ }
+ if (p->log & YFLAG) {
+ if (pt.y <= 0.0)
+ ERROR "can't take log of y coord %g", pt.y FATAL;
+ logit(pt.y);
+ }
+ sprintf(buf, "xy_%s(%g,%g)", p->name, pt.x, pt.y);
+ return buf; /* WATCH IT: static */
+}
+
+void pic(char *s) /* fire out pic stuff directly */
+{
+ while (*s == ' ')
+ s++;
+ fprintf(tfd, "%s\n", s);
+}
+
+int auto_x = 0; /* counts abscissa if none provided */
+
+void numlist(void) /* print numbers in default way */
+{
+ Obj *p;
+ Point pt;
+ int i;
+ static char *spot = "\\(bu";
+ Attr *ap;
+
+ p = pt.obj = lookup(curr_coord, 1);
+ if (nnum == 1) {
+ nnum = 2;
+ num[1] = num[0];
+ num[0] = ++auto_x;
+ }
+ pt.x = num[0];
+ if (p->attr && p->attr->sval)
+ spot = p->attr->sval;
+ for (i = 1; i < nnum; i++) {
+ pt.y = num[i];
+ if (p->attr == 0 || p->attr->type == 0) {
+ ap = makesattr(tostring(spot));
+ plot(ap, pt);
+ } else
+ next(p, pt, p->attr);
+ }
+ nnum = 0;
+}
+
+void plot(Attr *sl, Point pt) /* put stringlist sl at point pt */
+{
+ fprintf(tfd, "%s at %s\n", slprint(sl), xyname(pt));
+ range(pt);
+ freeattr(sl);
+}
+
+void plotnum(double f, char *fmt, Point pt) /* plot value f at point */
+{
+ char buf[100];
+
+ if (fmt) {
+ sprintf(buf, fmt, f);
+ free(fmt);
+ } else if (f >= 0.0)
+ sprintf(buf, "%g", f);
+ else
+ sprintf(buf, "\\-%g", -f);
+ fprintf(tfd, "\"%s\" at %s\n", buf, xyname(pt));
+ range(pt);
+}
+
+void drawdesc(int type, Obj *p, Attr *desc, char *s) /* set line description for p */
+{
+ p->attr = desc;
+ p->attr->sval = s;
+ if (type == NEW) {
+ p->first = 0; /* so it really looks new */
+ auto_x = 0;
+ }
+}
+
+void next(Obj *p, Point pt, Attr *desc) /* add component to a path */
+{
+ char *s;
+
+ if (p->first == 0) {
+ p->first++;
+ fprintf(tfd, "L%s: %s\n", p->name, xyname(pt));
+ } else {
+ fprintf(tfd, "line %s from L%s to %s; L%s: Here\n",
+ desc_str(desc->type ? desc : p->attr),
+ p->name, xyname(pt), p->name);
+ }
+ if (p->attr && (s=p->attr->sval)) {
+ /* BUG: should fix size here */
+ fprintf(tfd, "\"%s\" at %s\n", s, xyname(pt));
+ }
+ range(pt);
+}