-downsize() /* set size lower to make it lighter */
-{
- if (drawsize != 1) {
- printf(".nr .. \\n(.s/%d\n", drawsize);
- printf(".ps \\n(..\n");
- }
-}
-
-upsize() /* undo downsize */
-{
- printf(".ps\n"); /* God help anyone who fiddles .ps */
-}
-
-drawline(dx, dy) /* draw line from here to dx, dy */
-int dx, dy;
-{
- int xd, yd;
- float val, slope;
- int i, numdots;
- int dirmot, perp;
- int motincr, perpincr;
- int ohpos, ovpos, osize;
- float incrway;
-
- ohpos = hpos;
- ovpos = vpos;
- xd = dx / DX;
- yd = dy / DX;
- printf("\\\&");
- put1(drawdot);
- if (xd == 0) {
- numdots = abs (yd);
- motincr = DX * sgn (yd);
- for (i = 0; i < numdots; i++) {
- vmot(motincr);
- put1(drawdot);
- }
- vgoto(ovpos + dy);
- printf("\n");
- return;
- }
- if (yd == 0) {
- numdots = abs (xd);
- motincr = DX * sgn (xd);
- for (i = 0; i < numdots; i++) {
- hmot(motincr);
- put1(drawdot);
- }
- hgoto(ohpos + dx);
- printf("\n");
- return;
- }
- if (abs (xd) > abs (yd)) {
- val = slope = (float) xd/yd;
- numdots = abs (xd);
- dirmot = 'h';
- perp = 'v';
- motincr = DX * sgn (xd);
- perpincr = DX * sgn (yd);
- }
- else {
- val = slope = (float) yd/xd;
- numdots = abs (yd);
- dirmot = 'v';
- perp = 'h';
- motincr = DX * sgn (yd);
- perpincr = DX * sgn (xd);
- }
- incrway = sgn ((int) slope);
- for (i = 0; i < numdots; i++) {
- val -= incrway;
- if (dirmot == 'h')
- hmot(motincr);
- else
- vmot(motincr);
- if (val * slope < 0) {
- if (perp == 'h')
- hmot(perpincr);
- else
- vmot(perpincr);
- val += slope;
- }
- put1(drawdot);
- }
- hgoto(ohpos + dx);
- vgoto(ovpos + dy);
- printf("\n");
-}
-
-drawspline(s) /* draw spline curve */
- char *s;
-{
- int x[50], y[50], xp, yp, pxp, pyp;
- float t1, t2, t3, w;
- int i, j, steps, N, prevsteps;
- register char *p;
-
- N = 0;
-
-/* Weird...
- N = sscanf(s, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ",
- &x[2], &y[2], &x[3], &y[3], &x[4], &y[4], &x[5], &y[5], &x[6], &y[6], &x[7], &y[7], &x[8], &y[8], &x[9], &y[9], &x[10], &y[10], &x[11], &y[11], &x[12], &y[12],
-&x[13], &y[13], &x[14], &y[14], &x[15], &y[15], &x[16], &y[16], &x[17], &y[17], &x[18], &y[18], &x[19], &y[19], &x[20], &y[20], &x[21], &y[21], &x[22], &y[22], &x[23], &y[23], &x[24], &y[24],
-&x[25], &y[25], &x[26], &y[26], &x[27], &y[27], &x[28], &y[28], &x[29], &y[29], &x[30], &y[30], &x[31], &y[31], &x[32], &y[32], &x[33], &y[33], &x[34], &y[34], &x[35], &y[35], &x[36], &y[36],
-&x[37], &y[37]);
-*/
- p = s;
- for( i = 2; i <= 37; i++) {
- j = sscanf(p, "%d%d", &x[i], &y[i]);
- if( j == -1)
- break;
- while( isspace(*p))
- p++;
- while( isdigit(*p) || *p == '-')
- p++;
- while( isspace(*p))
- p++;
- while( isdigit(*p) || *p == '-')
- p++;
- N += 2;
- }
-
- N = N/2 + 2;
- x[0] = x[1] = hpos;
- y[0] = y[1] = vpos;
- for (i = 1; i < N; i++) {
- x[i+1] += x[i];
- y[i+1] += y[i];
- }
- x[N] = x[N-1];
- y[N] = y[N-1];
- prevsteps = 0;
- pxp = pyp = -9999;
- printf("\\\&");
- for (i = 0; i < N-1; i++) { /* interval */
- steps = (dist(x[i],y[i], x[i+1],y[i+1]) + dist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2;
- steps /= DX;
- for (j = 0; j < steps; j++) { /* points within */
- w = (float) j / steps;
- t1 = 0.5 * w * w;
- w = w - 0.5;
- t2 = 0.75 - w * w;
- w = w - 0.5;
- t3 = 0.5 * w * w;
- xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5;
- yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5;
- xp = round(xp, DX);
- yp = round(yp, DY);
- if (xp != pxp || yp != pyp) {
- hgoto(xp);
- vgoto(yp);
- put1(drawdot);
- pxp = xp;
- pyp = yp;
- }
- }
- }
- printf("\n");
-}
-
-drawcircle(d)
-{
- int xc, yc;
-
- xc = hpos;
- yc = vpos;
- printf("\\\&");
- conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2);
- hgoto(xc + d); /* circle goes to right side */
- vgoto(yc);
- printf("\n");
-}
-
-dist(x1, y1, x2, y2) /* integer distance from x1,y1 to x2,y2 */
-{
- float dx, dy;
-
- dx = x2 - x1;
- dy = y2 - y1;
- return sqrt(dx*dx + dy*dy) + 0.5;
-}
-
-drawarc(x, y, r)
-{
- int x0, y0;
- float dx, dy, phi, d, ht, ang;
-
- if (r == 0)
- r = 1;
- if (r < 0)
- ang = PI / 2;
- else
- ang = -(PI / 2);
- dx = x / 2;
- dy = y / 2;
- phi = atan2(dy, dx) + ang;
- while ((d = (float)r * r - (dx*dx + dy*dy)) < 0.0)
- r *= 2;
- ht = sqrt(d);
- x0 = hpos + dx + ht * cos(phi) + 0.5;
- y0 = vpos + dy + ht * sin(phi) + 0.5;
- printf("\\\&");
- conicarc(x0, -y0, hpos, -vpos, hpos+x, -vpos-y, r, r);
- printf("\n");
-}
-
-drawellipse(a, b)
-{
- int xc, yc;
-
- xc = hpos;
- yc = vpos;
- printf("\\\&");
- conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2);
- hgoto(xc + a);
- vgoto(yc);
- printf("\n");
-}
-
-#define sqr(x) (long int)(x)*(x)
-
-conicarc(x, y, x0, y0, x1, y1, a, b)
-{
- /* based on Bresenham, CACM, Feb 77, pp 102-3 */
- /* by Chris Van Wyk */
- /* capitalized vars are an internal reference frame */
- long dotcount = 0;
- int xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt,
- M1x, M1y, M2x, M2y, M3x, M3y,
- Q, move, Xc, Yc;
- int delta;
- float xc, yc;
- float radius, slope;
- float xstep, ystep;
- if (a != b) /* an arc of an ellipse; internally, will still think of circle */
- if (a > b) {
- xstep = (float)a / b;
- ystep = 1;
- radius = b;
- }
- else
- {
- xstep = 1;
- ystep = (float)b / a;
- radius = a;
- }
- else /* a circular arc; radius is computed from center and first point */ {
- xstep = ystep = 1;
- radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y)));
- }
-
-
- xc = x0;
- yc = y0;
- /* now, use start and end point locations to figure out
- the angle at which start and end happen; use these
- angles with known radius to figure out where start
- and end should be */
- slope = atan2((double)(y0 - y), (double)(x0 - x)
- );
- if ((slope == 0.0)
- && (x0 < x)
- )
- slope = 3.14159265;
- x0 = x + radius * cos(slope)
- + 0.5;
- y0 = y + radius * sin(slope)
- + 0.5;
- slope = atan2((double)(y1 - y), (double)(x1 - x)
- );
- if ((slope == 0.0)
- && (x1 < x)
- )
- slope = 3.14159265;
- x1 = x + radius * cos(slope)
- + 0.5;
- y1 = y + radius * sin(slope)
- + 0.5;
- /* step 2: translate to zero-centered circle */
- xs = x0 - x;
- ys = y0 - y;
- xt = x1 - x;
- yt = y1 - y;
- /* step 3: normalize to first quadrant */
- if (xs < 0)
- if (ys < 0) {
- Xs = abs(ys);
- Ys = abs(xs);
- qs = 3;
- M1x = 0;
- M1y = -1;
- M2x = 1;
- M2y = -1;
- M3x = 1;
- M3y = 0;
- }
- else {
- Xs = abs(xs);
- Ys = abs(ys);
- qs = 2;
- M1x = -1;
- M1y = 0;
- M2x = -1;
- M2y = -1;
- M3x = 0;
- M3y = -1;
- }
- else if (ys < 0) {
- Xs = abs(xs);
- Ys = abs(ys);
- qs = 0;
- M1x = 1;
- M1y = 0;
- M2x = 1;
- M2y = 1;
- M3x = 0;
- M3y = 1;
- } else {
- Xs = abs(ys);
- Ys = abs(xs);
- qs = 1;
- M1x = 0;
- M1y = 1;
- M2x = -1;
- M2y = 1;
- M3x = -1;
- M3y = 0;
- }
-
-
- Xc = Xs;
- Yc = Ys;
- if (xt < 0)
- if (yt < 0) {
- Xt = abs(yt);
- Yt = abs(xt);
- qt = 3;
- }
- else {
- Xt = abs(xt);
- Yt = abs(yt);
- qt = 2;
- }
- else if (yt < 0) {
- Xt = abs(xt);
- Yt = abs(yt);
- qt = 0;
- } else {
- Xt = abs(yt);
- Yt = abs(xt);
- qt = 1;
- }
-
-
- /* step 4: calculate number of quadrant crossings */
- if (((4 + qt - qs)
- % 4 == 0)
- && (Xt <= Xs)
- && (Yt >= Ys)
- )
- Q = 3;
- else
- Q = (4 + qt - qs) % 4 - 1;
- /* step 5: calculate initial decision difference */
- delta = sqr(Xs + 1)
- + sqr(Ys - 1)
- -sqr(xs)
- -sqr(ys);
- /* here begins the work of drawing
- we hope it ends here too */
- while ((Q >= 0)
- || ((Q > -2)
- && ((Xt > Xc)
- || (Yt < Yc)
- )
- )
- ) {
- if (dotcount++ % DX == 0)
- putdot(round((int) xc, DX), round((int) yc, DY));
- if (Yc < 0.5) {
- /* reinitialize */
- Xs = Xc = 0;
- Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys)));
- delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys);
- Q--;
- M1x = M3x;
- M1y = M3y;
- {
- int T;
- T = M2y;
- M2y = M2x;
- M2x = -T;
- T = M3y;
- M3y = M3x;
- M3x = -T;
- }
- } else {
- if (delta <= 0)
- if (2 * delta + 2 * Yc - 1 <= 0)
- move = 1;
- else
- move = 2;
- else if (2 * delta - 2 * Xc - 1 <= 0)
- move = 2;
- else
- move = 3;
- switch (move) {
- case 1:
- Xc++;
- delta += 2 * Xc + 1;
- xc += M1x * xstep;
- yc += M1y * ystep;
- break;
- case 2:
- Xc++;
- Yc--;
- delta += 2 * Xc - 2 * Yc + 2;
- xc += M2x * xstep;
- yc += M2y * ystep;
- break;
- case 3:
- Yc--;
- delta -= 2 * Yc + 1;
- xc += M3x * xstep;
- yc += M3y * ystep;
- break;
- }
- }
- }
-
-
-}
-
-putdot(x, y)
-{
- arcmove(x, y);
- put1(drawdot);
-}
-
-round(x, dx) /* round x relative to dx */
-{
- x = (x + dx - 1) / dx;
- return x * dx;