Annotation of researchv9/jerq/src/lib/mj/ellipse.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.