|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "pic.h" ! 3: #include "y.tab.h" ! 4: ! 5: struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ ! 6: { ! 7: static int prevw = HT/10; ! 8: static int prevh = HT/5; ! 9: static int prevrad = HT/2; ! 10: static int dtox[2][4] ={ 1, -1, -1, 1, 1, 1, -1, -1 }; ! 11: static int dtoy[2][4] ={ 1, 1, -1, -1, -1, 1, 1, -1 }; ! 12: static int dctrx[2][4] ={ 0, -1, 0, 1, 0, 1, 0, -1 }; ! 13: static int dctry[2][4] ={ 1, 0, -1, 0, -1, 0, 1, 0 }; ! 14: static int nexthv[2][4] ={ U_DIR, L_DIR, D_DIR, R_DIR, D_DIR, R_DIR, U_DIR, L_DIR }; ! 15: double sqrt(), atan2(), sin(), cos(); ! 16: float dx2, dy2, ht, phi, r, d; ! 17: int i, head, to, at, cw, invis; ! 18: struct obj *p, *ppos; ! 19: coord fromx, fromy, tox, toy; ! 20: ! 21: prevrad = getvar("arcrad"); ! 22: prevh = getvar("arrowht"); ! 23: prevw = getvar("arrowwid"); ! 24: fromx = curx; ! 25: fromy = cury; ! 26: head = to = at = cw = invis = 0; ! 27: for (i = 0; i < nattr; i++) { ! 28: switch (attr[i].a_type) { ! 29: case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: ! 30: savetext(attr[i].a_type, attr[i].a_val); ! 31: break; ! 32: case HEAD: ! 33: head += attr[i].a_val; ! 34: break; ! 35: case INVIS: ! 36: invis = INVIS; ! 37: break; ! 38: case HEIGHT: /* length of arrowhead */ ! 39: prevh = attr[i].a_val; ! 40: break; ! 41: case WIDTH: /* width of arrowhead */ ! 42: prevw = attr[i].a_val; ! 43: break; ! 44: case RADIUS: ! 45: prevrad = attr[i].a_val; ! 46: break; ! 47: case DIAMETER: ! 48: prevrad = attr[i].a_val / 2; ! 49: break; ! 50: case CW: ! 51: cw = 1; ! 52: break; ! 53: case FROM: /* start point of arc */ ! 54: ppos = (struct obj *) attr[i].a_val; ! 55: fromx = ppos->o_x; ! 56: fromy = ppos->o_y; ! 57: break; ! 58: case TO: /* end point of arc */ ! 59: ppos = (struct obj *) attr[i].a_val; ! 60: tox = ppos->o_x; ! 61: toy = ppos->o_y; ! 62: to++; ! 63: break; ! 64: case AT: /* center of arc */ ! 65: ppos = (struct obj *) attr[i].a_val; ! 66: curx = ppos->o_x; ! 67: cury = ppos->o_y; ! 68: at = 1; ! 69: break; ! 70: case UP: ! 71: hvmode = U_DIR; ! 72: break; ! 73: case DOWN: ! 74: hvmode = D_DIR; ! 75: break; ! 76: case RIGHT: ! 77: hvmode = R_DIR; ! 78: break; ! 79: case LEFT: ! 80: hvmode = L_DIR; ! 81: break; ! 82: } ! 83: } ! 84: if (!at && !to) { /* the defaults are mostly OK */ ! 85: curx = fromx + prevrad * dctrx[cw][hvmode]; ! 86: cury = fromy + prevrad * dctry[cw][hvmode]; ! 87: tox = fromx + prevrad * dtox[cw][hvmode]; ! 88: toy = fromy + prevrad * dtoy[cw][hvmode]; ! 89: hvmode = nexthv[cw][hvmode]; ! 90: } ! 91: else if (!at) { ! 92: dx2 = (float)(tox - fromx) / 2; ! 93: dy2 = (float)(toy - fromy) / 2; ! 94: phi = atan2(dy2, dx2) + (cw ? -PI2 : PI2); ! 95: for (r=prevrad; (d = r*r - (dx2*dx2+dy2*dy2)) <= 0.0; r *= 2) ! 96: ; /* this kludge gets around too-small radii */ ! 97: ht = sqrt(d); ! 98: curx = fromx + dx2 + ht * cos(phi) + 0.5; ! 99: cury = fromy + dy2 + ht * sin(phi) + 0.5; ! 100: dprintf("dx2,dy2=%g,%g, phi=%g, r,ht=%g,%g\n", ! 101: dx2, dy2, phi, r, ht); ! 102: } ! 103: else if (at && !to) { /* do we have all the cases??? */ ! 104: tox = fromx + prevrad * dtox[cw][hvmode]; ! 105: toy = fromy + prevrad * dtoy[cw][hvmode]; ! 106: hvmode = nexthv[cw][hvmode]; ! 107: } ! 108: if (cw) { /* interchange roles of from-to and heads */ ! 109: coord temp; ! 110: temp = fromx; fromx = tox; tox = temp; ! 111: temp = fromy; fromy = toy; toy = temp; ! 112: if (head == HEAD1) ! 113: head = HEAD2; ! 114: else if (head == HEAD2) ! 115: head = HEAD1; ! 116: } ! 117: p = makenode(type, 6); ! 118: /* these are wrong in general */ ! 119: extreme(fromx, fromy); ! 120: extreme(tox, toy); ! 121: p->o_val[0] = fromx; ! 122: p->o_val[1] = fromy; ! 123: p->o_val[2] = tox; ! 124: p->o_val[3] = toy; ! 125: if (cw) { ! 126: curx = fromx; ! 127: cury = fromy; ! 128: } else { ! 129: curx = tox; ! 130: cury = toy; ! 131: } ! 132: p->o_val[4] = prevw; ! 133: p->o_val[5] = prevh; ! 134: p->o_attr = head | (cw ? CW_ARC : 0) | invis; ! 135: dprintf("arc at %d %d from %d %d to %d %d head %d %d\n", ! 136: p->o_x, p->o_y, ! 137: p->o_val[0], p->o_val[1], p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]); ! 138: return(p); ! 139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.