Annotation of researchv9/jerq/src/lib/jj/op, revision 1.1

1.1     ! root        1: #include       <jerq.h>
        !             2: 
        !             3: static emax(a,b) { return((a<b)? b:a); }
        !             4: static emin(a,b) { return((a>b)? b:a); }
        !             5: static ycmp(), xcmp(), xcut();
        !             6: 
        !             7: typedef struct Edge
        !             8: {
        !             9:        Point p1, p2;
        !            10:        short dolow;
        !            11: } Edge;
        !            12: static Edge edges[300];
        !            13: static Edge *canon();
        !            14: 
        !            15: polyture(bp, pts, n, t, mode)
        !            16:        Bitmap *bp;
        !            17:        Point *pts;
        !            18:        Texture *t;
        !            19: {
        !            20:        register Edge *eend, *e, *estart;
        !            21:        register y;
        !            22:        int ymin, ymax, flag;
        !            23:        Point p;
        !            24:        int xcuts[64], *xp, *x;
        !            25: 
        !            26:        eend = canon(pts, n, &ymax);
        !            27:        qsort(edges, eend-edges, sizeof(edges[0]), ycmp);
        !            28:        ymin = edges->p1.y;
        !            29:        eend->p1.y = eend->p2.y = ymax+1;
        !            30:        /*
        !            31:                traditional scanline
        !            32:        */
        !            33:        for(estart = eend = edges, y = ymin; y <= ymax; y++)
        !            34:        {
        !            35:                while(estart->p2.y < y) estart++;
        !            36:                while(eend->p1.y <= y) eend++;
        !            37:                for(e = estart, xp = xcuts; e < eend; e++)
        !            38:                        if((y < e->p2.y) || (e->dolow && (y == e->p2.y)))
        !            39:                                *xp++ = xcut(y, e);
        !            40:                qsort(xcuts, xp-xcuts, sizeof(*xp), xcmp);
        !            41:                for(x = xcuts; x < xp; x += 2)
        !            42:                        texture(bp, Rect(*x, y, x[1]+1, y+1), t, mode);
        !            43:        }
        !            44: }
        !            45: 
        !            46: static Edge *
        !            47: canon(pts, n, ymax)
        !            48:        register Point *pts;
        !            49:        register *ymax;
        !            50: {
        !            51:        register Edge *le, *e;
        !            52:        register Point *p, *lp, pt;
        !            53:        int vert;
        !            54: 
        !            55:        /*
        !            56:                delete horizontal edges; compact vertical edges into one
        !            57:        */
        !            58:        p = pts;
        !            59:        lp = p+n;
        !            60:        e = edges;
        !            61:        *ymax = p->y;
        !            62:        e->p1 = *p++;
        !            63:        for(vert = 0; p < lp; p++)
        !            64:        {
        !            65:                if(*ymax < p->y) *ymax = p->y;
        !            66:                if(p->y == p[-1].y)
        !            67:                {
        !            68:                        vert = 0;
        !            69:                        e->p1 = *p;
        !            70:                        continue;
        !            71:                }
        !            72:                if(vert && (p->x == p[-1].x))
        !            73:                        e->p2.y = p->y;
        !            74:                else
        !            75:                {
        !            76:                        if(vert)
        !            77:                                e[1].p1 = e->p2, e++;
        !            78:                        e++->p2 = *p;
        !            79:                        e->p1 = *p;
        !            80:                        if(vert = p->x == p[-1].x) e--;
        !            81:                }
        !            82:        }
        !            83:        if(vert) e++;
        !            84:        le = e;
        !            85:        *le = edges[0];
        !            86:        le[1] = edges[1];
        !            87:        for(e = edges+1; e <= le; e++)
        !            88:        {
        !            89:                if(e->p1.y < e->p2.y)   /* going down */
        !            90:                        e->dolow = (e[1].p1.y-e[1].p2.y) > 0;
        !            91:                else
        !            92:                        e->dolow = (e[-1].p1.y-e[-1].p2.y) < 0;
        !            93:        }
        !            94:        edges[0] = *le;
        !            95:        /*
        !            96:                canonise the edges so that p1.y < p2.y
        !            97:                or if p1.y == p2.y then p1.x < p2.x.
        !            98:        */
        !            99:        for(e = edges; e < le; e++)
        !           100:        {
        !           101:                if((e->p1.y > e->p2.y) || ((e->p1.y == e->p2.y)&&(e->p1.x > e->p2.x)))
        !           102:                        pt = e->p1, e->p1 = e->p2, e->p2 = pt;
        !           103:        }
        !           104:        return(le);
        !           105: }
        !           106: 
        !           107: static
        !           108: ycmp(a, b)
        !           109:        register Edge *a, *b;
        !           110: {
        !           111:        register k;
        !           112: 
        !           113:        if(k = a->p1.y - b->p1.y)
        !           114:                return(k);
        !           115:        return(a->p2.y - b->p2.y);
        !           116: }
        !           117: 
        !           118: static
        !           119: xcmp(a, b)
        !           120:        register int *a, *b;
        !           121: {
        !           122:        return(*a - *b);
        !           123: }
        !           124: 
        !           125: static
        !           126: xcut(y, e)
        !           127:        register Edge *e;
        !           128: {
        !           129:        return(e->p1.x + muldiv(e->p2.x-e->p1.x, y-e->p1.y, e->p2.y-e->p1.y));
        !           130: }
        !           131: 

unix.superglobalmegacorp.com

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