Annotation of researchv10no/cmd/dimpress/draw.c, revision 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.