|
|
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.