|
|
1.1 ! root 1: /* @(#)draw.c 1.1 */ ! 2: #include <stdio.h> ! 3: #include <math.h> ! 4: #define PI 3.141592654 ! 5: #define hmot(n) hpos += n ! 6: #define hgoto(n) hpos = n ! 7: #define vmot(n) vgoto(vpos + n) ! 8: ! 9: extern int hpos; ! 10: extern int vpos; ! 11: extern int size; ! 12: extern short *pstab; ! 13: extern int DX; /* step size in x */ ! 14: extern int DY; /* step size in y */ ! 15: extern int drawdot; /* character to use when drawing */ ! 16: extern int drawsize; /* shrink point size by this facter */ ! 17: ! 18: int maxdots = 32000; /* maximum number of dots in an object */ ! 19: ! 20: #define sgn(n) ((n > 0) ? 1 : ((n < 0) ? -1 : 0)) ! 21: #define abs(n) ((n) >= 0 ? (n) : -(n)) ! 22: #define max(x,y) ((x) > (y) ? (x) : (y)) ! 23: #define min(x,y) ((x) < (y) ? (x) : (y)) ! 24: #define arcmove(x,y) { hgoto(x); vmot(-vpos-(y)); } ! 25: ! 26: drawline(dx, dy, s) /* draw line from here to dx, dy using s */ ! 27: int dx, dy; ! 28: char *s; ! 29: { ! 30: int xd, yd; ! 31: float val, slope; ! 32: int i, numdots; ! 33: int dirmot, perp; ! 34: int motincr, perpincr; ! 35: int ohpos, ovpos, osize, ofont; ! 36: float incrway; ! 37: ! 38: osize = size; ! 39: setsize(t_size(pstab[osize-1] / drawsize)); ! 40: ohpos = hpos; ! 41: ovpos = vpos; ! 42: xd = dx / DX; ! 43: yd = dy / DX; ! 44: if (xd == 0) { ! 45: numdots = abs (yd); ! 46: numdots = min(numdots, maxdots); ! 47: motincr = DX * sgn (yd); ! 48: for (i = 0; i < numdots; i++) { ! 49: vmot(motincr); ! 50: put1(drawdot); ! 51: } ! 52: vgoto(ovpos + dy); ! 53: setsize(osize); ! 54: return; ! 55: } ! 56: if (yd == 0) { ! 57: numdots = abs (xd); ! 58: motincr = DX * sgn (xd); ! 59: for (i = 0; i < numdots; i++) { ! 60: hmot(motincr); ! 61: put1(drawdot); ! 62: } ! 63: hgoto(ohpos + dx); ! 64: setsize(osize); ! 65: return; ! 66: } ! 67: if (abs (xd) > abs (yd)) { ! 68: val = slope = (float) xd/yd; ! 69: numdots = abs (xd); ! 70: numdots = min(numdots, maxdots); ! 71: dirmot = 'h'; ! 72: perp = 'v'; ! 73: motincr = DX * sgn (xd); ! 74: perpincr = DX * sgn (yd); ! 75: } ! 76: else { ! 77: val = slope = (float) yd/xd; ! 78: numdots = abs (yd); ! 79: numdots = min(numdots, maxdots); ! 80: dirmot = 'v'; ! 81: perp = 'h'; ! 82: motincr = DX * sgn (yd); ! 83: perpincr = DX * sgn (xd); ! 84: } ! 85: incrway = sgn ((int) slope); ! 86: for (i = 0; i < numdots; i++) { ! 87: val -= incrway; ! 88: if (dirmot == 'h') ! 89: hmot(motincr); ! 90: else ! 91: vmot(motincr); ! 92: if (val * slope < 0) { ! 93: if (perp == 'h') ! 94: hmot(perpincr); ! 95: else ! 96: vmot(perpincr); ! 97: val += slope; ! 98: } ! 99: put1(drawdot); ! 100: } ! 101: hgoto(ohpos + dx); ! 102: vgoto(ovpos + dy); ! 103: setsize(osize); ! 104: } ! 105: ! 106: drawwig(s) /* draw wiggly line */ ! 107: char *s; ! 108: { ! 109: int x[50], y[50], xp, yp, pxp, pyp; ! 110: float t1, t2, t3, w; ! 111: int i, j, numdots, N; ! 112: int osize, ofont; ! 113: char temp[50], *p, *getstr(); ! 114: ! 115: osize = size; ! 116: setsize(t_size(pstab[osize-1] / drawsize)); ! 117: p = s; ! 118: for (N = 2; (p=getstr(p,temp)) != NULL && N < sizeof(x)/sizeof(x[0]); N++) { ! 119: x[N] = atoi(temp); ! 120: p = getstr(p, temp); ! 121: y[N] = atoi(temp); ! 122: } ! 123: x[0] = x[1] = hpos; ! 124: y[0] = y[1] = vpos; ! 125: for (i = 1; i < N; i++) { ! 126: x[i+1] += x[i]; ! 127: y[i+1] += y[i]; ! 128: } ! 129: x[N] = x[N-1]; ! 130: y[N] = y[N-1]; ! 131: pxp = pyp = -9999; ! 132: for (i = 0; i < N-1; i++) { /* interval */ ! 133: numdots = (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; ! 134: numdots /= DX; ! 135: numdots = min(numdots, maxdots); ! 136: for (j = 0; j < numdots; j++) { /* points within */ ! 137: w = (float) j / numdots; ! 138: t1 = 0.5 * w * w; ! 139: w = w - 0.5; ! 140: t2 = 0.75 - w * w; ! 141: w = w - 0.5; ! 142: t3 = 0.5 * w * w; ! 143: xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5; ! 144: yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5; ! 145: if (xp != pxp || yp != pyp) { ! 146: hgoto(xp); ! 147: vgoto(yp); ! 148: put1(drawdot); ! 149: pxp = xp; ! 150: pyp = yp; ! 151: } ! 152: } ! 153: } ! 154: setsize(osize); ! 155: } ! 156: ! 157: char *getstr(p, temp) /* copy next non-blank string from p to temp, update p */ ! 158: char *p, *temp; ! 159: { ! 160: while (*p == ' ' || *p == '\t' || *p == '\n') ! 161: p++; ! 162: if (*p == '\0') { ! 163: temp[0] = 0; ! 164: return(NULL); ! 165: } ! 166: while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') ! 167: *temp++ = *p++; ! 168: *temp = '\0'; ! 169: return(p); ! 170: } ! 171: ! 172: drawcirc(d) ! 173: { ! 174: int xc, yc; ! 175: ! 176: xc = hpos; ! 177: yc = vpos; ! 178: conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2); ! 179: hgoto(xc + d); /* circle goes to right side */ ! 180: vgoto(yc); ! 181: } ! 182: ! 183: dist(x1, y1, x2, y2) /* integer distance from x1,y1 to x2,y2 */ ! 184: { ! 185: float dx, dy; ! 186: ! 187: dx = x2 - x1; ! 188: dy = y2 - y1; ! 189: return sqrt(dx*dx + dy*dy) + 0.5; ! 190: } ! 191: ! 192: drawarc(dx1, dy1, dx2, dy2) ! 193: { ! 194: int x0, y0, x2, y2, r; ! 195: ! 196: x0 = hpos + dx1; /* center */ ! 197: y0 = vpos + dy1; ! 198: x2 = x0 + dx2; /* "to" */ ! 199: y2 = y0 + dy2; ! 200: r = sqrt((float) dx1 * dx1 + (float) dy1 * dy1) + 0.5; ! 201: conicarc(x0, -y0, hpos, -vpos, x2, -y2, r, r); ! 202: } ! 203: ! 204: drawellip(a, b) ! 205: { ! 206: int xc, yc; ! 207: ! 208: xc = hpos; ! 209: yc = vpos; ! 210: conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2); ! 211: hgoto(xc + a); ! 212: vgoto(yc); ! 213: } ! 214: ! 215: #define sqr(x) (long int)(x)*(x) ! 216: ! 217: conicarc(x, y, x0, y0, x1, y1, a, b) ! 218: { ! 219: /* based on Bresenham, CACM, Feb 77, pp 102-3 */ ! 220: /* by Chris Van Wyk */ ! 221: /* capitalized vars are an internal reference frame */ ! 222: long dotcount = 0; ! 223: int osize, ofont; ! 224: int xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt, ! 225: M1x, M1y, M2x, M2y, M3x, M3y, ! 226: Q, move, Xc, Yc; ! 227: int ox1, oy1; ! 228: long delta; ! 229: float xc, yc; ! 230: float radius, slope; ! 231: float xstep, ystep; ! 232: ! 233: osize = size; ! 234: setsize(t_size(pstab[osize-1] / drawsize)); ! 235: ox1 = x1; ! 236: oy1 = y1; ! 237: if (a != b) /* an arc of an ellipse; internally, will still think of circle */ ! 238: if (a > b) { ! 239: xstep = (float)a / b; ! 240: ystep = 1; ! 241: radius = b; ! 242: } else { ! 243: xstep = 1; ! 244: ystep = (float)b / a; ! 245: radius = a; ! 246: } ! 247: else { /* a circular arc; radius is computed from center and first point */ ! 248: xstep = ystep = 1; ! 249: radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y))); ! 250: } ! 251: ! 252: ! 253: xc = x0; ! 254: yc = y0; ! 255: /* now, use start and end point locations to figure out ! 256: the angle at which start and end happen; use these ! 257: angles with known radius to figure out where start ! 258: and end should be ! 259: */ ! 260: slope = atan2((double)(y0 - y), (double)(x0 - x) ); ! 261: if (slope == 0.0 && x0 < x) ! 262: slope = 3.14159265; ! 263: x0 = x + radius * cos(slope) + 0.5; ! 264: y0 = y + radius * sin(slope) + 0.5; ! 265: slope = atan2((double)(y1 - y), (double)(x1 - x)); ! 266: if (slope == 0.0 && x1 < x) ! 267: slope = 3.14159265; ! 268: x1 = x + radius * cos(slope) + 0.5; ! 269: y1 = y + radius * sin(slope) + 0.5; ! 270: /* step 2: translate to zero-centered circle */ ! 271: xs = x0 - x; ! 272: ys = y0 - y; ! 273: xt = x1 - x; ! 274: yt = y1 - y; ! 275: /* step 3: normalize to first quadrant */ ! 276: if (xs < 0) ! 277: if (ys < 0) { ! 278: Xs = abs(ys); ! 279: Ys = abs(xs); ! 280: qs = 3; ! 281: M1x = 0; ! 282: M1y = -1; ! 283: M2x = 1; ! 284: M2y = -1; ! 285: M3x = 1; ! 286: M3y = 0; ! 287: } else { ! 288: Xs = abs(xs); ! 289: Ys = abs(ys); ! 290: qs = 2; ! 291: M1x = -1; ! 292: M1y = 0; ! 293: M2x = -1; ! 294: M2y = -1; ! 295: M3x = 0; ! 296: M3y = -1; ! 297: } ! 298: else if (ys < 0) { ! 299: Xs = abs(xs); ! 300: Ys = abs(ys); ! 301: qs = 0; ! 302: M1x = 1; ! 303: M1y = 0; ! 304: M2x = 1; ! 305: M2y = 1; ! 306: M3x = 0; ! 307: M3y = 1; ! 308: } else { ! 309: Xs = abs(ys); ! 310: Ys = abs(xs); ! 311: qs = 1; ! 312: M1x = 0; ! 313: M1y = 1; ! 314: M2x = -1; ! 315: M2y = 1; ! 316: M3x = -1; ! 317: M3y = 0; ! 318: } ! 319: ! 320: ! 321: Xc = Xs; ! 322: Yc = Ys; ! 323: if (xt < 0) ! 324: if (yt < 0) { ! 325: Xt = abs(yt); ! 326: Yt = abs(xt); ! 327: qt = 3; ! 328: } else { ! 329: Xt = abs(xt); ! 330: Yt = abs(yt); ! 331: qt = 2; ! 332: } ! 333: else if (yt < 0) { ! 334: Xt = abs(xt); ! 335: Yt = abs(yt); ! 336: qt = 0; ! 337: } else { ! 338: Xt = abs(yt); ! 339: Yt = abs(xt); ! 340: qt = 1; ! 341: } ! 342: ! 343: ! 344: /* step 4: calculate number of quadrant crossings */ ! 345: if (((4 + qt - qs) ! 346: % 4 == 0) ! 347: && (Xt <= Xs) ! 348: && (Yt >= Ys) ! 349: ) ! 350: Q = 3; ! 351: else ! 352: Q = (4 + qt - qs) % 4 - 1; ! 353: /* step 5: calculate initial decision difference */ ! 354: delta = sqr(Xs + 1) ! 355: + sqr(Ys - 1) ! 356: -sqr(xs) ! 357: -sqr(ys); ! 358: /* here begins the work of drawing ! 359: we hope it ends here too */ ! 360: while ((Q >= 0) ! 361: || ((Q > -2) ! 362: && ((Xt > Xc) ! 363: && (Yt < Yc) ! 364: ) ! 365: ) ! 366: ) { ! 367: if (dotcount++ % DX == 0) ! 368: putdot((int)xc, (int)yc); ! 369: if (Yc < 0.5) { ! 370: /* reinitialize */ ! 371: Xs = Xc = 0; ! 372: Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys))); ! 373: delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys); ! 374: Q--; ! 375: M1x = M3x; ! 376: M1y = M3y; ! 377: { ! 378: int T; ! 379: T = M2y; ! 380: M2y = M2x; ! 381: M2x = -T; ! 382: T = M3y; ! 383: M3y = M3x; ! 384: M3x = -T; ! 385: } ! 386: } else { ! 387: if (delta <= 0) ! 388: if (2 * delta + 2 * Yc - 1 <= 0) ! 389: move = 1; ! 390: else ! 391: move = 2; ! 392: else if (2 * delta - 2 * Xc - 1 <= 0) ! 393: move = 2; ! 394: else ! 395: move = 3; ! 396: switch (move) { ! 397: case 1: ! 398: Xc++; ! 399: delta += 2 * Xc + 1; ! 400: xc += M1x * xstep; ! 401: yc += M1y * ystep; ! 402: break; ! 403: case 2: ! 404: Xc++; ! 405: Yc--; ! 406: delta += 2 * Xc - 2 * Yc + 2; ! 407: xc += M2x * xstep; ! 408: yc += M2y * ystep; ! 409: break; ! 410: case 3: ! 411: Yc--; ! 412: delta -= 2 * Yc + 1; ! 413: xc += M3x * xstep; ! 414: yc += M3y * ystep; ! 415: break; ! 416: } ! 417: } ! 418: } ! 419: ! 420: ! 421: setsize(osize); ! 422: drawline((int)xc-ox1,(int)yc-oy1,"."); ! 423: } ! 424: ! 425: putdot(x, y) ! 426: { ! 427: arcmove(x, y); ! 428: put1(drawdot); ! 429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.