|
|
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 lsegment(l, p, q, f) segment(l, p, q, f)
6: #endif
7:
8: #include <jerq.h>
9: #define DB ((Word *)0x700000)
10: #define ONSCREEN(b) (b->base>=DB && b->base<DB+XMAX/WORDSIZE*YMAX)
11: #define labs(x,y) if((x=y)<0) x= -x
12: #define samesign(x,y) (((int)(x)^(int)(y)) > 0)
13:
14: #define BIG 077777
15: #define HUGE 07777777777L
16:
17: /* draw an ellipse centered at x0,y0 with half-axes a,b */
18: #ifdef MUX
19: #define POINT Tvoid(26)
20: #else
21: extern void point();
22: #define POINT point
23: #endif
24: ellipse(bp, p, a, b, f)
25: Bitmap *bp;
26: Point p;
27: long a, b;
28: Code f;
29: {
30: short inhibited;
31: inhibited=0;
32: if(f!=F_XOR && ONSCREEN(bp)){
33: Jcursinhibit();
34: inhibited=1;
35: }
36: if(a==0 || b==0)
37: lsegment(bp, Pt(p.x-a, p.y-b), Pt(p.x+a, p.y+b), f);
38: else
39: ellip1(bp, p, a, b, POINT, Pt(0, b), Pt(0, b), f);
40: if(inhibited)
41: Jcursallow();
42: }
43:
44: /* calculate b*b*x*x + a*a*y*y - a*a*b*b avoiding ovfl */
45:
46: static long
47: resid(a,b,x,y)
48: register long a,b;
49: long x,y;
50: {
51: long e = 0;
52: long u = b*(a*a - x*x);
53: long v = a*y*y;
54: register q = u>BIG? HUGE/u: BIG;
55: register r = v>BIG? HUGE/v: BIG;
56: while(a || b) {
57: if(e>=0 && b) {
58: if(q>b) q = b;
59: e -= q*u;
60: b -= q;
61: } else {
62: if(r>a) r = a;
63: e += r*v;
64: a -= r;
65: }
66: }
67: return(e);
68: }
69:
70: /* service routine used for both elliptic arcs and ellipses
71: * traces clockwise an ellipse centered at x0,y0 with half-axes
72: * a,b starting from the point x1,y1 and ending at x2,y2
73: * performing an action at each point
74: * x1,y1,x2,y2 are measured relative to center
75: * when x1,y1 = x2,y2 the whole ellipse is traced
76: * e is the error b^2 x^2 + a^2 y^2 - a^2 b^2
77: */
78:
79: ellip1(bp, p0, a, b, action, p1, p2, f)
80: Point p0, p1, p2;
81: long a, b;
82: register void (*action)();
83: register Bitmap *bp;
84: Code f;
85: {
86: int dx = p1.y>0? 1: p1.y<0? -1: p1.x>0? -1: 1;
87: int dy = p1.x>0? -1: p1.x<0? 1: p1.y>0? -1: 1;
88: long a2 = a*a;
89: long b2 = b*b;
90: register long dex = b2*(2*dx*p1.x+1);
91: register long e;
92: register long dey = a2*(2*dy*p1.y+1);
93: register long ex, ey, exy;
94: int partial = !eqpt(p1, p2);
95:
96: if(partial &&
97: (p1.x==0 && p2.x==0 && samesign(p1.y, p2.y) ||
98: p1.y==0 && p2.y==0 && samesign(p1.x, p2.x))) {
99: lsegment(bp, add(p0, p1), add(p0,p2), f);
100: return;
101: }
102: e = resid(a, b, p1.x, p1.y);
103: a2 *= 2;
104: b2 *= 2;
105: do {
106: labs(ex, e+dex);
107: labs(ey, e+dey);
108: labs(exy, e+dex+dey);
109: if(exy<=ex || ey<ex) {
110: p1.y += dy;
111: e += dey;
112: dey += a2;
113: }
114: if(exy<=ey || ex<ey) {
115: p1.x += dx;
116: e += dex;
117: dex += b2;
118: }
119: if(p1.x == 0) {
120: if(abs(p1.y) == b) {
121: dy = -dy;
122: dey = -dey + a2;
123: partial = 0;
124: } else if(!samesign(p1.y, dy) && !partial)
125: continue; /* don't double-draw skinny ends */
126: } else if(p1.y == 0) {
127: if(abs(p1.x) == a) {
128: dx = -dx;
129: dex = -dex + b2;
130: partial = 0;
131: } else if(!samesign(p1.x, dx) && !partial)
132: continue;
133: }
134: (*action)(bp, add(p0, p1), f);
135: } while(! eqpt(p1, p2));
136: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.