|
|
1.1 root 1: #ifndef MUX
2: #define Jcursinhibit() cursinhibit()
3: #define Jcursallow() cursallow()
4: #define lrectf(l, r, f) rectf(l, r, f)
5: #define lpoint(l, p, f) point(l, p, f)
6: #endif
7:
8: #include <jerq.h>
9: static Point nearby();
10: #define sq(x) ((long)(x)*(x))
11: #define sgn(x) ((x)<0? -1 : (x)==0? 0 : 1)
12: #define labs(x) (x<0? -x : x)
13: #define DB ((Word *)0x700000)
14: #define ONSCREEN(b) (b->base>=DB && b->base<DB+XMAX/WORDSIZE*YMAX)
15:
16: /* Draw an approximate arc centered at x0,y0 of an
17: * integer grid and running anti-clockwise from
18: * x1,y1 to the vicinity of x2,y2.
19: * If the endpoints coincide, draw a complete circle.
20: *
21: * The "arc" is a sequence of vertically, horizontally,
22: * or diagonally adjacent points that minimize
23: * abs(x^2+y^2-r^2).
24: *
25: * The circle is guaranteed to be symmetric about
26: * the horizontal, vertical, and diagonal axes
27: */
28: arc(bp, p0, p2, p1, f)
29: register Bitmap *bp;
30: Point p0, p1, p2;
31: {
32: short inhibited;
33: register dx, dy;
34: register eps; /* x^2 + y^2 - r^2 */
35: int dxsq, dysq; /* (x+dx)^2-x^2, ...*/
36: int ex, ey, exy;
37: p1=sub(p1, p0);
38: p2=sub(p2, p0);
39: p2=nearby(p1, p2);
40: dx = -sgn(p1.y); /* y1==0 is soon fixed */
41: dy = sgn(p1.x);
42: dxsq = (2*p1.x + dx)*dx;
43: dysq = (2*p1.y + dy)*dy;
44: eps = 0;
45: inhibited=0;
46: if(f!=F_XOR && ONSCREEN(bp)){
47: Jcursinhibit();
48: inhibited=1;
49: }
50: do {
51: if(p1.x == 0) {
52: dy = -sgn(p1.y);
53: dysq = (2*p1.y + dy)*dy;
54: } else if(p1.y == 0) {
55: dx = -sgn(p1.x);
56: dxsq = (2*p1.x + dx)*dx;
57: }
58: ex = abs(eps + dxsq);
59: ey = abs(eps + dysq);
60: exy = abs(eps + dxsq + dysq);
61: if(ex<ey || exy<=ey) {
62: p1.x += dx;
63: eps += dxsq;
64: dxsq += 2;
65: }
66: if(ey<ex || exy<=ex) {
67: p1.y += dy;
68: eps += dysq;
69: dysq += 2;
70: }
71: lpoint(bp, Pt(p0.x+p1.x, p0.y+p1.y), f);
72: } while(!(p1.x==p2.x && p1.y==p2.y)); /* Note1 */
73: if(inhibited)
74: Jcursallow();
75: }
76: /* Note1: the equality end test is justified
77: * because it is impossible that
78: * abs(x^2+y^2-r^2)==abs((x++-1)^2+y^2-r^2) or
79: * abs(x^2+y^2-r^2)==abs(x^2+(y++-1)-r^2),
80: * and no values of x or y are skipped.
81: *
82: */
83: static Point nearby(p1, p2)
84: Point p1, p2;
85: {
86: long eps, exy; /*integers but many bits*/
87: int d;
88: register dy;
89: register dx;
90: register x1 = p1.x;
91: register y1 = p1.y;
92: register x2 = p2.x;
93: register y2 = p2.y;
94: eps = sq(x2) + sq(y2) - sq(x1) - sq(y1);
95: d = eps>0? -1: 1;
96: for( ; ; eps=exy, x2+=dx, y2+=dy) {
97: if(abs(y2) > abs(x2)) {
98: dy = d*sgn(y2);
99: dx = 0;
100: } else {
101: dy = 0;
102: dx = d*sgn(x2);
103: if(dx==0)
104: dx = 1;
105: }
106: exy = eps + (2*x2+dx)*dx + (2*y2+dy)*dy;
107: if(labs(eps) <= labs(exy))
108: break;
109: }
110: p2.x = x2;
111: p2.y = y2;
112: return(p2);
113: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.