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