|
|
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.