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