Annotation of researchv9/jerq/src/lib/j/ellipse.c, revision 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.