# 2.11BSD#431 - /usr/src/usr.lib/libplot/bitgraph/arc.c

##### Functions

    arc               X

##### Macros

    side              X

       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: #if defined(DOSCCS) && !defined(lint)
       8: static char sccsid[] = "@(#)arc.c	5.2.1 (2.11BSD GTE) 1/1/94";
       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: }

#### Defined functions

arc defined in line 18; used 2 times

- in /usr/src/usr.lib/libplot/bitgraph/circle.c line 15-16(2)

#### Defined variables

sccsid defined in line 8; never used

#### Defined macros

side defined in line 15; used 2 times

- in line 81, 95

Last modified: 1994-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 906 |