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