Annotation of researchv10no/cmd/dimpress/draw.c, revision 1.1.1.1

1.1       root        1: /*      @(#)draw.c     1.1     */
                      2: #include       <stdio.h>
                      3: #include       <math.h>
                      4: #define        PI      3.141592654
                      5: #define        hmot(n)         hpos += n
                      6: #define        hgoto(n)        hpos = n
                      7: #define        vmot(n)         vgoto(vpos + n)
                      8: 
                      9: extern int     hpos;
                     10: extern int     vpos;
                     11: extern int     size;
                     12: extern short   *pstab;
                     13: extern int     DX;     /* step size in x */
                     14: extern int     DY;     /* step size in y */
                     15: extern int     drawdot;        /* character to use when drawing */
                     16: extern int     drawsize;       /* shrink point size by this facter */
                     17: 
                     18: int    maxdots = 32000;        /* maximum number of dots in an object */
                     19: 
                     20: #define        sgn(n)  ((n > 0) ? 1 : ((n < 0) ? -1 : 0))
                     21: #define        abs(n)  ((n) >= 0 ? (n) : -(n))
                     22: #define        max(x,y)        ((x) > (y) ? (x) : (y))
                     23: #define        min(x,y)        ((x) < (y) ? (x) : (y))
                     24: #define        arcmove(x,y)    { hgoto(x); vmot(-vpos-(y)); }
                     25: 
                     26: drawline(dx, dy, s)    /* draw line from here to dx, dy using s */
                     27: int dx, dy;
                     28: char *s;
                     29: {
                     30:        int xd, yd;
                     31:        float val, slope;
                     32:        int i, numdots;
                     33:        int dirmot, perp;
                     34:        int motincr, perpincr;
                     35:        int ohpos, ovpos, osize, ofont;
                     36:        float incrway;
                     37: 
                     38:        osize = size;
                     39:        setsize(t_size(pstab[osize-1] / drawsize));
                     40:        ohpos = hpos;
                     41:        ovpos = vpos;
                     42:        xd = dx / DX;
                     43:        yd = dy / DX;
                     44:        if (xd == 0) {
                     45:                numdots = abs (yd);
                     46:                numdots = min(numdots, maxdots);
                     47:                motincr = DX * sgn (yd);
                     48:                for (i = 0; i < numdots; i++) {
                     49:                        vmot(motincr);
                     50:                        put1(drawdot);
                     51:                }
                     52:                vgoto(ovpos + dy);
                     53:                setsize(osize);
                     54:                return;
                     55:        }
                     56:        if (yd == 0) {
                     57:                numdots = abs (xd);
                     58:                motincr = DX * sgn (xd);
                     59:                for (i = 0; i < numdots; i++) {
                     60:                        hmot(motincr);
                     61:                        put1(drawdot);
                     62:                }
                     63:                hgoto(ohpos + dx);
                     64:                setsize(osize);
                     65:                return;
                     66:        }
                     67:        if (abs (xd) > abs (yd)) {
                     68:                val = slope = (float) xd/yd;
                     69:                numdots = abs (xd);
                     70:                numdots = min(numdots, maxdots);
                     71:                dirmot = 'h';
                     72:                perp = 'v';
                     73:                motincr = DX * sgn (xd);
                     74:                perpincr = DX * sgn (yd);
                     75:        }
                     76:        else {
                     77:                val = slope = (float) yd/xd;
                     78:                numdots = abs (yd);
                     79:                numdots = min(numdots, maxdots);
                     80:                dirmot = 'v';
                     81:                perp = 'h';
                     82:                motincr = DX * sgn (yd);
                     83:                perpincr = DX * sgn (xd);
                     84:        }
                     85:        incrway = sgn ((int) slope);
                     86:        for (i = 0; i < numdots; i++) {
                     87:                val -= incrway;
                     88:                if (dirmot == 'h')
                     89:                        hmot(motincr);
                     90:                else
                     91:                        vmot(motincr);
                     92:                if (val * slope < 0) {
                     93:                        if (perp == 'h')
                     94:                                hmot(perpincr);
                     95:                        else
                     96:                                vmot(perpincr);
                     97:                        val += slope;
                     98:                }
                     99:                put1(drawdot);
                    100:        }
                    101:        hgoto(ohpos + dx);
                    102:        vgoto(ovpos + dy);
                    103:        setsize(osize);
                    104: }
                    105: 
                    106: drawwig(s)     /* draw wiggly line */
                    107:        char *s;
                    108: {
                    109:        int x[50], y[50], xp, yp, pxp, pyp;
                    110:        float t1, t2, t3, w;
                    111:        int i, j, numdots, N;
                    112:        int osize, ofont;
                    113:        char temp[50], *p, *getstr();
                    114: 
                    115:        osize = size;
                    116:        setsize(t_size(pstab[osize-1] / drawsize));
                    117:        p = s;
                    118:        for (N = 2; (p=getstr(p,temp)) != NULL && N < sizeof(x)/sizeof(x[0]); N++) {
                    119:                x[N] = atoi(temp);
                    120:                p = getstr(p, temp);
                    121:                y[N] = atoi(temp);
                    122:        }
                    123:        x[0] = x[1] = hpos;
                    124:        y[0] = y[1] = vpos;
                    125:        for (i = 1; i < N; i++) {
                    126:                x[i+1] += x[i];
                    127:                y[i+1] += y[i];
                    128:        }
                    129:        x[N] = x[N-1];
                    130:        y[N] = y[N-1];
                    131:        pxp = pyp = -9999;
                    132:        for (i = 0; i < N-1; i++) {     /* interval */
                    133:                numdots = (dist(x[i],y[i], x[i+1],y[i+1]) + dist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2;
                    134:                numdots /= DX;
                    135:                numdots = min(numdots, maxdots);
                    136:                for (j = 0; j < numdots; j++) { /* points within */
                    137:                        w = (float) j / numdots;
                    138:                        t1 = 0.5 * w * w;
                    139:                        w = w - 0.5;
                    140:                        t2 = 0.75 - w * w;
                    141:                        w = w - 0.5;
                    142:                        t3 = 0.5 * w * w;
                    143:                        xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5;
                    144:                        yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5;
                    145:                        if (xp != pxp || yp != pyp) {
                    146:                                hgoto(xp);
                    147:                                vgoto(yp);
                    148:                                put1(drawdot);
                    149:                                pxp = xp;
                    150:                                pyp = yp;
                    151:                        }
                    152:                }
                    153:        }
                    154:        setsize(osize);
                    155: }
                    156: 
                    157: char *getstr(p, temp)  /* copy next non-blank string from p to temp, update p */
                    158: char *p, *temp;
                    159: {
                    160:        while (*p == ' ' || *p == '\t' || *p == '\n')
                    161:                p++;
                    162:        if (*p == '\0') {
                    163:                temp[0] = 0;
                    164:                return(NULL);
                    165:        }
                    166:        while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
                    167:                *temp++ = *p++;
                    168:        *temp = '\0';
                    169:        return(p);
                    170: }
                    171: 
                    172: drawcirc(d)
                    173: {
                    174:        int xc, yc;
                    175: 
                    176:        xc = hpos;
                    177:        yc = vpos;
                    178:        conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2);
                    179:        hgoto(xc + d);  /* circle goes to right side */
                    180:        vgoto(yc);
                    181: }
                    182: 
                    183: dist(x1, y1, x2, y2)   /* integer distance from x1,y1 to x2,y2 */
                    184: {
                    185:        float dx, dy;
                    186: 
                    187:        dx = x2 - x1;
                    188:        dy = y2 - y1;
                    189:        return sqrt(dx*dx + dy*dy) + 0.5;
                    190: }
                    191: 
                    192: drawarc(dx1, dy1, dx2, dy2)
                    193: {
                    194:        int x0, y0, x2, y2, r;
                    195: 
                    196:        x0 = hpos + dx1;        /* center */
                    197:        y0 = vpos + dy1;
                    198:        x2 = x0 + dx2;  /* "to" */
                    199:        y2 = y0 + dy2;
                    200:        r = sqrt((float) dx1 * dx1 + (float) dy1 * dy1) + 0.5;
                    201:        conicarc(x0, -y0, hpos, -vpos, x2, -y2, r, r);
                    202: }
                    203: 
                    204: drawellip(a, b)
                    205: {
                    206:        int xc, yc;
                    207: 
                    208:        xc = hpos;
                    209:        yc = vpos;
                    210:        conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2);
                    211:        hgoto(xc + a);
                    212:        vgoto(yc);
                    213: }
                    214: 
                    215: #define sqr(x) (long int)(x)*(x)
                    216: 
                    217: conicarc(x, y, x0, y0, x1, y1, a, b)
                    218: {
                    219:        /* based on Bresenham, CACM, Feb 77, pp 102-3 */
                    220:        /* by Chris Van Wyk */
                    221:        /* capitalized vars are an internal reference frame */
                    222:        long dotcount = 0;
                    223:        int osize, ofont;
                    224:        int     xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt,
                    225:                M1x, M1y, M2x, M2y, M3x, M3y,
                    226:                Q, move, Xc, Yc;
                    227:        int ox1, oy1;
                    228:        long    delta;
                    229:        float   xc, yc;
                    230:        float   radius, slope;
                    231:        float   xstep, ystep;
                    232: 
                    233:        osize = size;
                    234:        setsize(t_size(pstab[osize-1] / drawsize));
                    235:        ox1 = x1;
                    236:        oy1 = y1;
                    237:        if (a != b)     /* an arc of an ellipse; internally, will still think of circle */
                    238:                if (a > b) {
                    239:                        xstep = (float)a / b;
                    240:                        ystep = 1;
                    241:                        radius = b;
                    242:                } else {
                    243:                        xstep = 1;
                    244:                        ystep = (float)b / a;
                    245:                        radius = a;
                    246:                } 
                    247:        else {  /* a circular arc; radius is computed from center and first point */    
                    248:                xstep = ystep = 1;
                    249:                radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y)));
                    250:        }
                    251: 
                    252: 
                    253:        xc = x0;
                    254:        yc = y0;
                    255:        /* now, use start and end point locations to figure out
                    256:        the angle at which start and end happen; use these
                    257:        angles with known radius to figure out where start
                    258:        and end should be
                    259:        */
                    260:        slope = atan2((double)(y0 - y), (double)(x0 - x) );
                    261:        if (slope == 0.0 && x0 < x)
                    262:                slope = 3.14159265;
                    263:        x0 = x + radius * cos(slope) + 0.5;
                    264:        y0 = y + radius * sin(slope) + 0.5;
                    265:        slope = atan2((double)(y1 - y), (double)(x1 - x));
                    266:        if (slope == 0.0 && x1 < x)
                    267:                slope = 3.14159265;
                    268:        x1 = x + radius * cos(slope) + 0.5;
                    269:        y1 = y + radius * sin(slope) + 0.5;
                    270:        /* step 2: translate to zero-centered circle */
                    271:        xs = x0 - x;
                    272:        ys = y0 - y;
                    273:        xt = x1 - x;
                    274:        yt = y1 - y;
                    275:        /* step 3: normalize to first quadrant */
                    276:        if (xs < 0)
                    277:                if (ys < 0) {
                    278:                        Xs = abs(ys);
                    279:                        Ys = abs(xs);
                    280:                        qs = 3;
                    281:                        M1x = 0;
                    282:                        M1y = -1;
                    283:                        M2x = 1;
                    284:                        M2y = -1;
                    285:                        M3x = 1;
                    286:                        M3y = 0;
                    287:                } else {
                    288:                        Xs = abs(xs);
                    289:                        Ys = abs(ys);
                    290:                        qs = 2;
                    291:                        M1x = -1;
                    292:                        M1y = 0;
                    293:                        M2x = -1;
                    294:                        M2y = -1;
                    295:                        M3x = 0;
                    296:                        M3y = -1;
                    297:                } 
                    298:        else if (ys < 0) {
                    299:                Xs = abs(xs);
                    300:                Ys = abs(ys);
                    301:                qs = 0;
                    302:                M1x = 1;
                    303:                M1y = 0;
                    304:                M2x = 1;
                    305:                M2y = 1;
                    306:                M3x = 0;
                    307:                M3y = 1;
                    308:        } else {
                    309:                Xs = abs(ys);
                    310:                Ys = abs(xs);
                    311:                qs = 1;
                    312:                M1x = 0;
                    313:                M1y = 1;
                    314:                M2x = -1;
                    315:                M2y = 1;
                    316:                M3x = -1;
                    317:                M3y = 0;
                    318:        }
                    319: 
                    320: 
                    321:        Xc = Xs;
                    322:        Yc = Ys;
                    323:        if (xt < 0)
                    324:                if (yt < 0) {
                    325:                        Xt = abs(yt);
                    326:                        Yt = abs(xt);
                    327:                        qt = 3;
                    328:                } else {
                    329:                        Xt = abs(xt);
                    330:                        Yt = abs(yt);
                    331:                        qt = 2;
                    332:                } 
                    333:        else if (yt < 0) {
                    334:                Xt = abs(xt);
                    335:                Yt = abs(yt);
                    336:                qt = 0;
                    337:        } else {
                    338:                Xt = abs(yt);
                    339:                Yt = abs(xt);
                    340:                qt = 1;
                    341:        }
                    342: 
                    343: 
                    344:        /* step 4: calculate number of quadrant crossings */
                    345:        if (((4 + qt - qs)
                    346:             % 4 == 0)
                    347:             && (Xt <= Xs)
                    348:             && (Yt >= Ys)
                    349:            )
                    350:                Q = 3;
                    351:        else
                    352:                Q = (4 + qt - qs) % 4 - 1;
                    353:        /* step 5: calculate initial decision difference */
                    354:        delta = sqr(Xs + 1)
                    355:         + sqr(Ys - 1)
                    356:        -sqr(xs)
                    357:        -sqr(ys);
                    358:        /* here begins the work of drawing
                    359:    we hope it ends here too */
                    360:        while ((Q >= 0)
                    361:             || ((Q > -2)
                    362:             && ((Xt > Xc)
                    363:             && (Yt < Yc)
                    364:            )
                    365:            )
                    366:            ) {
                    367:                if (dotcount++ % DX == 0)
                    368:                        putdot((int)xc, (int)yc);
                    369:                if (Yc < 0.5) {
                    370:                        /* reinitialize */
                    371:                        Xs = Xc = 0;
                    372:                        Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys)));
                    373:                        delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys);
                    374:                        Q--;
                    375:                        M1x = M3x;
                    376:                        M1y = M3y;
                    377:                         {
                    378:                                int     T;
                    379:                                T = M2y;
                    380:                                M2y = M2x;
                    381:                                M2x = -T;
                    382:                                T = M3y;
                    383:                                M3y = M3x;
                    384:                                M3x = -T;
                    385:                        }
                    386:                } else {
                    387:                        if (delta <= 0)
                    388:                                if (2 * delta + 2 * Yc - 1 <= 0)
                    389:                                        move = 1;
                    390:                                else
                    391:                                        move = 2;
                    392:                        else if (2 * delta - 2 * Xc - 1 <= 0)
                    393:                                move = 2;
                    394:                        else
                    395:                                move = 3;
                    396:                        switch (move) {
                    397:                        case 1:
                    398:                                Xc++;
                    399:                                delta += 2 * Xc + 1;
                    400:                                xc += M1x * xstep;
                    401:                                yc += M1y * ystep;
                    402:                                break;
                    403:                        case 2:
                    404:                                Xc++;
                    405:                                Yc--;
                    406:                                delta += 2 * Xc - 2 * Yc + 2;
                    407:                                xc += M2x * xstep;
                    408:                                yc += M2y * ystep;
                    409:                                break;
                    410:                        case 3:
                    411:                                Yc--;
                    412:                                delta -= 2 * Yc + 1;
                    413:                                xc += M3x * xstep;
                    414:                                yc += M3y * ystep;
                    415:                                break;
                    416:                        }
                    417:                }
                    418:        }
                    419: 
                    420: 
                    421:        setsize(osize);
                    422:        drawline((int)xc-ox1,(int)yc-oy1,".");
                    423: }
                    424: 
                    425: putdot(x, y)
                    426: {
                    427:        arcmove(x, y);
                    428:        put1(drawdot);
                    429: }

unix.superglobalmegacorp.com

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