10 static double prevdx
= HT
;
11 static double prevdy
= 0;
12 static double prevw
= HT10
;
13 static double prevh
= HT5
;
14 int i
, j
, some
, head
, ddtype
, invis
, chop
, battr
, with
;
15 double ddval
, chop1
, chop2
, x0
, y0
, x1
, y1
;
18 double defx
, defy
, xwith
, ywith
;
20 static int xtab
[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */
21 static int ytab
[] = { 0, 1, 0, -1 };
22 double dx
[500], dy
[500];
25 Attr
*ap
, *chop_ap
[4];
29 defx
= getfval("linewid");
30 defy
= getfval("lineht");
31 prevh
= getfval("arrowht");
32 prevw
= getfval("arrowwid");
33 dx
[0] = dy
[0] = ndxy
= some
= head
= invis
= battr
= with
= 0;
34 chop
= chop1
= chop2
= 0;
35 ddtype
= ddval
= xwith
= ywith
= 0;
36 for (i
= 0; i
< nattr
; i
++) {
40 savetext(ap
->a_sub
, ap
->a_val
.p
);
53 ddtype
= ap
->a_type
==DOT
? DOTBIT
: DASHBIT
;
54 if (ap
->a_sub
== DEFAULT
)
55 ddval
= getfval("dashwid");
65 dx
[ndxy
] -= (ap
->a_sub
==DEFAULT
) ? defx
: ap
->a_val
.f
;
70 dx
[ndxy
] += (ap
->a_sub
==DEFAULT
) ? defx
: ap
->a_val
.f
;
75 dy
[ndxy
] += (ap
->a_sub
==DEFAULT
) ? defy
: ap
->a_val
.f
;
80 dy
[ndxy
] -= (ap
->a_sub
==DEFAULT
) ? defy
: ap
->a_val
.f
;
84 case HEIGHT
: /* length of arrowhead */
87 case WIDTH
: /* width of arrowhead */
95 dx
[ndxy
] = dy
[ndxy
] = some
= 0;
97 ppos
= attr
[i
].a_val
.o
;
99 ERROR
"no tag defined for `to'" FATAL
;
100 dx
[ndxy
] = ppos
->o_x
- nx
;
101 dy
[ndxy
] = ppos
->o_y
- ny
;
109 dx
[ndxy
] = dy
[ndxy
] = some
= 0;
113 ERROR
"no tag defined for `by'" FATAL
;
114 dx
[ndxy
] = ppos
->o_x
;
115 dy
[ndxy
] = ppos
->o_y
;
118 case THEN
: /* turn off any previous accumulation */
123 dx
[ndxy
] = dy
[ndxy
] = some
= 0;
130 ERROR
"no tag defined for `from' or `at'" FATAL
;
131 nx
= curx
= ppos
->o_x
;
132 ny
= cury
= ppos
->o_y
;
138 if (ap
->a_sub
!= PLACENAME
) {
140 chop1
= chop2
= ap
->a_val
.f
;
144 chop_ap
[chop
++] = ap
;
148 if (ap
->a_sub
== DEFAULT
)
149 fillval
= getfval("fillval");
151 fillval
= ap
->a_val
.f
;
155 if (with
) { /* this doesn't work at all */
158 xwith
= (dx
[1] - dx
[0]) / 2; ywith
= (dy
[1] - dy
[0]) / 2; break;
160 for (i
= 0; i
< ndxy
; i
++) {
174 defx
*= xtab
[hvmode
];
175 defy
*= ytab
[hvmode
];
185 if (chop
== 1 && chop1
== 0) /* just said "chop", so use default */
186 chop1
= chop2
= getfval("circlerad");
187 theta
= atan2(dy
[0], dx
[0]);
188 x0
= chop1
* cos(theta
);
189 y0
= chop1
* sin(theta
);
195 theta
= atan2(dy
[ndxy
-1], dx
[ndxy
-1]);
196 x1
= chop2
* cos(theta
);
197 y1
= chop2
* sin(theta
);
202 dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n",
203 x0
, y0
, x1
, y1
, curx
, cury
, nx
, ny
);
205 p
= makenode(type
, 5 + 2 * ndxy
);
206 curx
= p
->o_val
[0] = nx
;
207 cury
= p
->o_val
[1] = ny
;
208 if (head
|| type
== ARROW
) {
209 p
->o_nhead
= getfval("arrowhead");
213 head
= HEAD2
; /* default arrow head */
215 p
->o_attr
= head
| invis
| ddtype
| battr
;
216 p
->o_fillval
= fillval
;
220 for (i
= 0, j
= 5; i
< ndxy
; i
++, j
+= 2) {
222 p
->o_val
[j
+1] = dy
[i
];
223 if (type
== LINE
|| type
== ARROW
)
224 extreme(nx
+= dx
[i
], ny
+= dy
[i
]);
225 else if (type
== SPLINE
&& i
< ndxy
-1) {
226 /* to compute approx extreme of spline at p,
227 /* compute midway between p-1 and p+1,
228 /* then go 3/4 from there to p */
229 double ex
, ey
, xi
, yi
, xi1
, yi1
;
230 xi
= nx
+ dx
[i
]; yi
= ny
+ dy
[i
]; /* p */
231 xi1
= xi
+ dx
[i
+1]; yi1
= yi
+ dy
[i
+1]; /* p+1 */
232 ex
= (nx
+xi1
)/2; ey
= (ny
+yi1
)/2; /* midway */
233 ex
+= 0.75*(xi
-ex
); ey
+= 0.75*(yi
-ey
);
241 printf("S or L from %g %g to %g %g with %d elements:\n", p
->o_x
, p
->o_y
, curx
, cury
, ndxy
);
242 for (i
= 0, j
= 5; i
< ndxy
; i
++, j
+= 2)
243 printf("%g %g\n", p
->o_val
[j
], p
->o_val
[j
+1]);
245 extreme(p
->o_x
, p
->o_y
);