|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */
4:
5: #include "gedit.h"
6:
7: #ifndef lint
8: static char *rcsid_garc_c = "$Header: garc.c,v 10.5 86/02/01 16:18:41 tony Rel $";
9: #endif lint
10:
11: /* arc drawing routines */
12:
13: double sqrt(),atan2(),sin(),cos();
14: char *malloc();
15:
16: /* construct a line object */
17: gptr mline(x1,y1,x2,y2,next)
18: gptr next;
19: { register gptr p;
20:
21: if ((p = (gptr)malloc(sizeof(struct segment))) == NULL) {
22: msg("out of room!");
23: return(next);
24: }
25: p->s.type = SEGMENT;
26: p->s.next = next;
27: p->s.parent = NULL;
28: p->s.x1 = x1;
29: p->s.y1 = y1;
30: p->s.x2 = x2;
31: p->s.y2 = y2;
32: p->s.angle = 0;
33: p->s.cache = NULL;
34: return(p);
35: }
36:
37: /* rounds the double x off to an integer */
38: int round(x)
39: double x;
40: { register int i;
41: if (x >= 0.0) i = x+0.5; else i = x-0.5;
42: return(i);
43: }
44:
45: /* compute center from arc end point and radius */
46: circcent(ang,fx,fy,tx,ty,xcp,ycp,rp)
47: int ang,fx,fy,tx,ty,*xcp,*ycp;
48: double *rp;
49: { double xx,yy,ss,dd,x1,y1;
50:
51: xx = tx - fx; yy = ty - fy;
52: dd = sqrt(xx*xx + yy*yy); /* length of chord */
53: if (dd == 0) { *xcp = fx; *ycp = fy; *rp = 0; return; }
54:
55: /* radius of arc */
56: *rp = dd / (2.0 * sin(3.141592653 * ang / 2048.0));
57:
58: /* length of perpendicular to chord */
59: ss = sqrt((*rp)*(*rp) - dd*dd/4.0);
60:
61: if (ang > 1024) ss = -ss;
62: x1 = (tx + fx) / 2.0; /* compute center point of chord */
63: y1 = (ty + fy) / 2.0;
64: x1 -= yy*ss/dd; /* now compute center of circle */
65: y1 += xx*ss/dd;
66:
67: *xcp = round(x1); *ycp = round(y1);
68: }
69:
70: /* calculate new arc list */
71: newalist(p,xa,ya,xb,yb)
72: register struct segment *p;
73: { double xx,yy,aa,bb;
74: double ainc,r;
75: int ix,iy,xc,yc;
76: int wherex,wherey;
77:
78: if (p->cache != NULL) {
79: rmalist(p->cache);
80: p->cache = NULL;
81: }
82:
83: if (p->angle == 0) return;
84: circcent(p->angle,xa,ya,xb,yb,&xc,&yc,&r);
85:
86: if (r < 2.0) {
87: p->cache = mline(xa-1,ya-1,xa+1,ya-1,p->cache);
88: p->cache = mline(xa-1,ya,xa+1,ya,p->cache);
89: p->cache = mline(xa-1,ya+1,xa+1,ya+1,p->cache);
90: return;
91: }
92:
93: xx = xa-xc; yy = ya-yc;
94: aa = atan2(yy,xx);
95: xx = xb-xc; yy = yb-yc;
96: bb = atan2(yy,xx);
97:
98: /* put aa and bb into proper relationship */
99: /* if (p->angle <= 1024) {
100: */ if (aa > bb) bb += 2*3.141592653;
101: /* } else {
102: if (bb > aa) aa += 2*3.141592653;
103: }
104: */
105: /* usually 32 lines/arc, but use enough to ensure that there would
106: * be at least 100 segments for a full circle.
107: */
108: ainc = (bb - aa)/32.0;
109: if (ainc > 0.628) ainc = 0.628;
110: else if (ainc < -0.628) ainc = -0.628;
111:
112: wherex = xa; wherey = ya;
113: while (1) {
114: ix = xc + r*cos(aa);
115: iy = yc + r*sin(aa);
116: p->cache = mline(wherex,wherey,ix,iy,p->cache);
117: wherex = ix; wherey = iy;
118: aa += ainc;
119: if ((ainc<0 && aa<=bb) || (ainc>=0 && aa>=bb)) break;
120: };
121: p->cache = mline(wherex,wherey,xb,yb,p->cache);
122: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.