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