Annotation of 43BSDTahoe/usr.lib/libplot/bitgraph/arc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)arc.c      5.2 (Berkeley) 4/30/85";
        !             9: #endif not lint
        !            10: 
        !            11: 
        !            12: #include "bg.h"
        !            13: 
        !            14: /* should include test for equality? */
        !            15: #define side(x,y)      (a*(x)+b*(y)+c > 0.0 ? 1 : -1)
        !            16: 
        !            17: /* The beginning and ending points must be distinct. */
        !            18: arc(xc,yc,xbeg,ybeg,xend,yend)
        !            19: int xc,yc,xbeg,ybeg,xend,yend;
        !            20: {
        !            21:        double r, radius, costheta, sintheta;
        !            22:        double a, b, c, x, y, tempX;
        !            23:        int right_side;
        !            24: 
        !            25:        int screen_xc = scaleX(xc);
        !            26:        int screen_yc = scaleY(yc);
        !            27: 
        !            28:        /* It is more convienient to beg and end relative to center. */
        !            29:        int screen_xbeg = scaleX(xbeg) - screen_xc;
        !            30:        int screen_ybeg = scaleY(ybeg) - screen_yc;
        !            31: 
        !            32:        int screen_xend = scaleX(xend) - screen_xc;
        !            33:        int screen_yend = scaleY(yend) - screen_yc;
        !            34: 
        !            35:        /* probably should check that arc is truely circular */
        !            36:        r = sqrt( (double) (screen_xbeg*screen_xbeg + screen_ybeg*screen_ybeg) );
        !            37: 
        !            38:        /*
        !            39:        This method is reasonably efficient, clean, and clever.
        !            40:        The easy part is generating the next point on the arc.  This is
        !            41:        done by rotating the points by the angle theta.  Theta is chosen
        !            42:        so that no rotation will cause more than one pixel of a move.
        !            43:        This corresponds to a triangle having x side of r and y side of 1.
        !            44:        The rotation is done (way) below inside the loop.
        !            45: 
        !            46:        Note:  all calculations are done in screen coordinates.
        !            47:        */
        !            48:        if (r <= 1.0) {
        !            49:                /* radius is mapped to length < 1*/
        !            50:                point(xc,yc);
        !            51:                return;
        !            52:                }
        !            53: 
        !            54:        radius = sqrt(r*r + 1.0);
        !            55:        sintheta = 1.0/radius;
        !            56:        costheta = r/radius;
        !            57: 
        !            58:        /*
        !            59:        The hard part of drawing an arc is figuring out when to stop.
        !            60:        This method works by drawing the line from the beginning point
        !            61:        to the ending point.  This splits the plane in half, with the
        !            62:        arc that we wish to draw on one side of the line.  If we evaluate
        !            63:        side(x,y) = a*x + b*y + c, then all of the points on one side of the
        !            64:        line will result in side being positive, and all the points on the
        !            65:        other side of the line will result in side being negative.
        !            66: 
        !            67:        We want to draw the arc in a counter-clockwise direction, so we
        !            68:        must find out what the sign of "side" is for a point which is to the 
        !            69:        "right" of a line drawn from "beg" to "end".  A point which must lie 
        !            70:        on the right is [xbeg + (yend-ybeg), ybeg - (xend-xbeg)].  (This
        !            71:        point is perpendicular to the line at "beg").
        !            72: 
        !            73:        Thus, we compute side of the above point, and then compare the
        !            74:        sign of side for each new point with the sign of the above point.
        !            75:        When they are different, we terminate the loop.
        !            76:        */
        !            77: 
        !            78:        a = (double) (screen_yend - screen_ybeg);
        !            79:        b = (double) (screen_xend - screen_xbeg);
        !            80:        c = (double) (screen_yend*screen_xbeg - screen_xend*screen_ybeg);
        !            81:        right_side = side(screen_xbeg + (screen_yend-screen_ybeg),
        !            82:                          screen_ybeg - (screen_xend-screen_xbeg) );
        !            83: 
        !            84:        x = screen_xbeg;
        !            85:        y = screen_ybeg;
        !            86:        move(xbeg, ybeg);
        !            87:        do {
        !            88:                currentx = screen_xc + (int) (x + 0.5);
        !            89:                currenty = screen_yc + (int) (y + 0.5);
        !            90:                putchar( ESC );
        !            91:                printf(":%d;%dd", currentx, currenty);
        !            92:                tempX = x;
        !            93:                x = x*costheta - y*sintheta;
        !            94:                y = tempX*sintheta + y*costheta;
        !            95:        } while( side(x,y) == right_side );
        !            96: }

unix.superglobalmegacorp.com

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