1*18197Sjaap #ifndef lint
2*18197Sjaap static char *sccsid ="opqpoly.c	(CWI)	1.1	85/03/01";
3*18197Sjaap #endif
4*18197Sjaap #include "ideal.h"
5*18197Sjaap #include "y.tab.h"
6*18197Sjaap 
7*18197Sjaap extern float interalpha[INTERSIZE];
8*18197Sjaap extern int internum;
9*18197Sjaap 
opqpoly(edgelist,linelist,inlines,outlines,both)10*18197Sjaap void opqpoly (edgelist, linelist, inlines, outlines, both)
11*18197Sjaap EDGEPTR edgelist;
12*18197Sjaap LINEPTR linelist;
13*18197Sjaap LINEPTR *inlines, *outlines, *both;
14*18197Sjaap {
15*18197Sjaap 	LINEPTR linewalk, circlearc;
16*18197Sjaap 	LINENODE nuin, nuout, nuboth;
17*18197Sjaap 	LINEPTR inwalk, outwalk, bothwalk;
18*18197Sjaap 	LINEPTR forfreeing;
19*18197Sjaap 
20*18197Sjaap 	inwalk = &nuin;
21*18197Sjaap 	inwalk->next = NULL;
22*18197Sjaap 	outwalk = &nuout;
23*18197Sjaap 	outwalk->next = NULL;
24*18197Sjaap 	bothwalk = &nuboth;
25*18197Sjaap 	bothwalk->next = NULL;
26*18197Sjaap 	linewalk = linelist;
27*18197Sjaap 	while (linewalk) {
28*18197Sjaap 		while (inwalk->next)
29*18197Sjaap 			inwalk = inwalk->next;
30*18197Sjaap 		while (outwalk->next)
31*18197Sjaap 			outwalk = outwalk->next;
32*18197Sjaap 		while (bothwalk->next)
33*18197Sjaap 			bothwalk = bothwalk->next;
34*18197Sjaap 		switch (linewalk->kind) {
35*18197Sjaap 		case LINE:
36*18197Sjaap 			polyline (
37*18197Sjaap 				edgelist,
38*18197Sjaap 				linewalk->x0,
39*18197Sjaap 				linewalk->y0,
40*18197Sjaap 				linewalk->x1,
41*18197Sjaap 				linewalk->y1,
42*18197Sjaap 				&inwalk->next,
43*18197Sjaap 				&outwalk->next,
44*18197Sjaap 				&bothwalk->next
45*18197Sjaap 			);
46*18197Sjaap 			forfreeing = linewalk;
47*18197Sjaap 			linewalk = linewalk->next;
48*18197Sjaap 			tryfree(forfreeing);
49*18197Sjaap 			break;
50*18197Sjaap 		case CIRCLE:
51*18197Sjaap 			circlearc = angularc (
52*18197Sjaap 				((CIRCPTR) linewalk)->x0,
53*18197Sjaap 				((CIRCPTR) linewalk)->y0,
54*18197Sjaap 				((CIRCPTR) linewalk)->r,
55*18197Sjaap 				0.0,
56*18197Sjaap 				2.0*PI
57*18197Sjaap 			);
58*18197Sjaap 			circlearc->next = linewalk->next;
59*18197Sjaap 			tryfree(linewalk);
60*18197Sjaap 			linewalk = circlearc;
61*18197Sjaap 			/* FALL THROUGH TO case arc */
62*18197Sjaap 		case ARC:
63*18197Sjaap 			polyarc (
64*18197Sjaap 				edgelist,
65*18197Sjaap 				((ARCPTR) linewalk)->x0,
66*18197Sjaap 				((ARCPTR) linewalk)->y0,
67*18197Sjaap 				((ARCPTR) linewalk)->radius,
68*18197Sjaap 				((ARCPTR) linewalk)->theta1,
69*18197Sjaap 				((ARCPTR) linewalk)->theta2,
70*18197Sjaap 				&inwalk->next,
71*18197Sjaap 				&outwalk->next,
72*18197Sjaap 				&bothwalk->next
73*18197Sjaap 			);
74*18197Sjaap 			forfreeing = linewalk;
75*18197Sjaap 			linewalk = linewalk->next;
76*18197Sjaap 			tryfree(forfreeing);
77*18197Sjaap 			break;
78*18197Sjaap 		case STRING:
79*18197Sjaap /*
80*18197Sjaap 			fprintf (stderr, "ideal: can't opaque over strings\n");
81*18197Sjaap */
82*18197Sjaap 			bothwalk->next = linewalk;
83*18197Sjaap 			linewalk = linewalk->next;
84*18197Sjaap 			bothwalk->next->next = NULL;
85*18197Sjaap 			break;
86*18197Sjaap 		case SPLINE:
87*18197Sjaap /*
88*18197Sjaap 			fprintf (stderr, "ideal: can't opaque over splines\n");
89*18197Sjaap */
90*18197Sjaap 			bothwalk->next = linewalk;
91*18197Sjaap 			linewalk = linewalk->next;
92*18197Sjaap 			bothwalk->next->next = NULL;
93*18197Sjaap 			break;
94*18197Sjaap 		default:
95*18197Sjaap 			impossible ("opqpoly");
96*18197Sjaap 			break;
97*18197Sjaap 		} /* switch */
98*18197Sjaap 	} /* while */
99*18197Sjaap 	*inlines = nuin.next;
100*18197Sjaap 	*outlines = nuout.next;
101*18197Sjaap 	*both = nuboth.next;
102*18197Sjaap } /* opqpoly */
103*18197Sjaap 
polyline(edgelist,candx0,candy0,candx1,candy1,inlines,outlines,both)104*18197Sjaap void polyline (edgelist, candx0,candy0, candx1,candy1, inlines, outlines, both)
105*18197Sjaap EDGEPTR edgelist;
106*18197Sjaap float candx0,candy0, candx1,candy1;
107*18197Sjaap LINEPTR *inlines, *outlines, *both;
108*18197Sjaap {
109*18197Sjaap 	OPQPTR interwalk;
110*18197Sjaap 	boolean inside, onedge;
111*18197Sjaap 	LINENODE nuin, nuout;
112*18197Sjaap 	LINEPTR inwalk, outwalk;
113*18197Sjaap 	LINEPTR linewalk;
114*18197Sjaap 	EDGEPTR prevedge, curedge;
115*18197Sjaap 	OPQPTR alphalist;
116*18197Sjaap 	float alpha, beta;
117*18197Sjaap 	float gamma[2], theta[2];
118*18197Sjaap 	boolean collinear;
119*18197Sjaap 	boolean X, Y, Z, W;
120*18197Sjaap 	int i;
121*18197Sjaap 	double dummy, rem;
122*18197Sjaap 
123*18197Sjaap 	alphalist = (OPQPTR) NULL;
124*18197Sjaap 	inwalk = &nuin;
125*18197Sjaap 	inwalk->next = NULL;
126*18197Sjaap 	outwalk = &nuout;
127*18197Sjaap 	outwalk->next = NULL;
128*18197Sjaap 	curedge = edgelist;
129*18197Sjaap 	do {
130*18197Sjaap 		if (curedge->fax == NULL) {
131*18197Sjaap 			if (
132*18197Sjaap 				llinter (
133*18197Sjaap 					candx0, candy0,
134*18197Sjaap 					candx1, candy1,
135*18197Sjaap 					curedge->sx, curedge->sy,
136*18197Sjaap 					curedge->ex, curedge->ey,
137*18197Sjaap 					&alpha,
138*18197Sjaap 					&beta,
139*18197Sjaap 					&collinear
140*18197Sjaap 				)
141*18197Sjaap 			) {
142*18197Sjaap 				if (EPSILON < beta && beta < 1.0 - EPSILON)
143*18197Sjaap 					curedge->code[0] = SIMPLE;
144*18197Sjaap 				else if (fabs(beta) < EPSILON)
145*18197Sjaap 					curedge->code[0] = AT0;
146*18197Sjaap 				else if (fabs(1.0-beta) < EPSILON)
147*18197Sjaap 					curedge->code[0] = AT1;
148*18197Sjaap 				else
149*18197Sjaap 					curedge->code[0] = UNUSED;
150*18197Sjaap 				curedge->alpha[0] = alpha;
151*18197Sjaap 				curedge->code[1] = UNUSED;
152*18197Sjaap 			} else
153*18197Sjaap 				if (collinear) {
154*18197Sjaap 					if (fabs(candx1 - candx0) < EPSILON) {
155*18197Sjaap 						curedge->alpha[0] = (curedge->sy - candy0)/(candy1 - candy0);
156*18197Sjaap 						curedge->alpha[1] = (curedge->ey - candy0)/(candy1 - candy0);
157*18197Sjaap 					} else {
158*18197Sjaap 						curedge->alpha[0] = (curedge->sx - candx0)/(candx1 - candx0);
159*18197Sjaap 						curedge->alpha[1] = (curedge->ex - candx0)/(candx1 - candx0);
160*18197Sjaap 					}
161*18197Sjaap 					if (curedge->alpha[0] < curedge->alpha[1]) {
162*18197Sjaap 						curedge->code[0] = ON0;
163*18197Sjaap 						curedge->code[1] = ON1;
164*18197Sjaap 					} else {
165*18197Sjaap 						curedge->code[0] = ON1;
166*18197Sjaap 						curedge->code[1] = ON0;
167*18197Sjaap 					}
168*18197Sjaap 				} else
169*18197Sjaap 					curedge->code[0] = curedge->code[1] = UNUSED;
170*18197Sjaap 		} else if (curedge->fax->kind == ARC) {
171*18197Sjaap 			if (
172*18197Sjaap 				!lcinter (
173*18197Sjaap 					candx0, candy0,
174*18197Sjaap 					candx1, candy1,
175*18197Sjaap 					curedge->fax->x0, curedge->fax->y0,
176*18197Sjaap 					fabs(curedge->fax->radius),
177*18197Sjaap 					&gamma[0], &theta[0],
178*18197Sjaap 					&gamma[1], &theta[1]
179*18197Sjaap 				)
180*18197Sjaap 			) {
181*18197Sjaap 				curedge->code[0] = curedge->code[1] = UNUSED;
182*18197Sjaap 				dprintf "line outside circle\n");
183*18197Sjaap 			} else if (fabs(theta[0] - theta[1]) < EPSILON) {
184*18197Sjaap 				if (fabs(theta[0] - curedge->fax->theta1) < EPSILON) {
185*18197Sjaap 					curedge->alpha[0] = gamma[0];
186*18197Sjaap 					curedge->code[0] = curedge->flipped?AT1:AT0;
187*18197Sjaap 					dprintf "%d\n", curedge->code[0]);
188*18197Sjaap 				} else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON) {
189*18197Sjaap 					curedge->alpha[0] = gamma[0];
190*18197Sjaap 					curedge->code[0] = curedge->flipped?AT0:AT1;
191*18197Sjaap 					dprintf "%d\n", curedge->code[0]);
192*18197Sjaap 				} else {
193*18197Sjaap 					curedge->code[0] = UNUSED;
194*18197Sjaap 					dprintf "line tangent\n");
195*18197Sjaap 				}
196*18197Sjaap 				curedge->code[1] = UNUSED;
197*18197Sjaap 			} else {
198*18197Sjaap 				for (i = 0; i < 2; i ++) {
199*18197Sjaap 					dprintf "disposition of %f\n", theta[i]);
200*18197Sjaap 					if (curedge->fax->theta2 < 2.0*PI) {
201*18197Sjaap 						if (theta[i] - curedge->fax->theta1 < -EPSILON
202*18197Sjaap 							|| curedge->fax->theta2 - theta[i] < -EPSILON) {
203*18197Sjaap 							curedge->code[i] = UNUSED;
204*18197Sjaap 							dprintf "intersection off arc\n");
205*18197Sjaap 							continue;
206*18197Sjaap 						}
207*18197Sjaap 					}
208*18197Sjaap 					if (curedge->fax->theta2 >= 2.0*PI) {
209*18197Sjaap 						if (theta[i] - curedge->fax->theta1 < -EPSILON
210*18197Sjaap 							&& curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) {
211*18197Sjaap 							curedge->code[i] = UNUSED;
212*18197Sjaap 							dprintf "intersection off arc\n");
213*18197Sjaap 							continue;
214*18197Sjaap 						}
215*18197Sjaap 					}
216*18197Sjaap 					rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2*PI), &dummy);
217*18197Sjaap 					dprintf "rem1 = %f\n", rem);
218*18197Sjaap 					if (rem < EPSILON || fabs(1.0-rem) < EPSILON) {
219*18197Sjaap 						curedge->alpha[i] = gamma[i];
220*18197Sjaap 						curedge->code[i] = curedge->flipped?AT1:AT0;
221*18197Sjaap 						dprintf "%d\n", curedge->code[i]);
222*18197Sjaap 						continue;
223*18197Sjaap 					}
224*18197Sjaap 					rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2*PI), &dummy);
225*18197Sjaap 					dprintf "rem2 = %f\n", rem);
226*18197Sjaap 					if (rem < EPSILON || fabs(1.0-rem) < EPSILON) {
227*18197Sjaap 						curedge->alpha[i] = gamma[i];
228*18197Sjaap 						curedge->code[i] = curedge->flipped?AT0:AT1;
229*18197Sjaap 						dprintf "%d\n", curedge->code[i]);
230*18197Sjaap 						continue;
231*18197Sjaap 					}
232*18197Sjaap 					dprintf "simple\n");
233*18197Sjaap 					curedge->code[i] = SIMPLE;
234*18197Sjaap 					curedge->alpha[i] = gamma[i];
235*18197Sjaap 				}
236*18197Sjaap 			}
237*18197Sjaap 		} else
238*18197Sjaap 			impossible ("polyline(A)");
239*18197Sjaap 		curedge = curedge->next;
240*18197Sjaap 	} while (curedge != edgelist);
241*18197Sjaap 	if (dbg) {
242*18197Sjaap 		curedge = edgelist;
243*18197Sjaap 		do {
244*18197Sjaap 			fprintf (stderr, "s (%f,%f); e (%f,%f)\n",
245*18197Sjaap 				curedge->sx, curedge->sy,
246*18197Sjaap 				curedge->ex, curedge->ey
247*18197Sjaap 			);
248*18197Sjaap 			fprintf (stderr, "st (%f,%f); et (%f,%f)\n",
249*18197Sjaap 				curedge->stx, curedge->sty,
250*18197Sjaap 				curedge->etx, curedge->ety
251*18197Sjaap 			);
252*18197Sjaap 			for (i = 0; i < POSSINTER; i ++)
253*18197Sjaap 				fprintf (stderr, "%d %f\n",
254*18197Sjaap 					curedge->code[i],
255*18197Sjaap 					curedge->alpha[i]
256*18197Sjaap 				);
257*18197Sjaap 			curedge = curedge->next;
258*18197Sjaap 		} while (curedge != edgelist);
259*18197Sjaap 	}
260*18197Sjaap 	prevedge = edgelist;
261*18197Sjaap 	curedge = edgelist->next;
262*18197Sjaap 	do {
263*18197Sjaap 		for (i = 0; i < POSSINTER; i ++)
264*18197Sjaap 			switch (curedge->code[i]) {
265*18197Sjaap 			case UNUSED:
266*18197Sjaap 				break;
267*18197Sjaap 			case SIMPLE:
268*18197Sjaap 				opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
269*18197Sjaap 				break;
270*18197Sjaap 			case AT0:
271*18197Sjaap 				dprintf "vertex intersection at (%f,%f)\n", curedge->sx, curedge->sy);
272*18197Sjaap 				X = arecollinear(curedge->sx,curedge->sy,curedge->stx,curedge->sty,prevedge->etx,prevedge->ety);
273*18197Sjaap 				Y = between(curedge->stx,curedge->sty,curedge->sx,curedge->sy,prevedge->etx,prevedge->ety);
274*18197Sjaap 				Z = arecollinear(candx0,candy0,candx1,candy1,curedge->stx,curedge->sty);
275*18197Sjaap 				dprintf "X=%d Y=%d Z=%d\n", X, Y, Z);
276*18197Sjaap 				if (X && !Z) {
277*18197Sjaap 					if (Y)
278*18197Sjaap 						opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
279*18197Sjaap 					break;
280*18197Sjaap 				}
281*18197Sjaap 				if (X && Z) {
282*18197Sjaap 					if (
283*18197Sjaap 						llinter (
284*18197Sjaap 							prevedge->sx, prevedge->sy,
285*18197Sjaap 							curedge->ex, curedge->ey,
286*18197Sjaap 							candx0, candy0,
287*18197Sjaap 							candx1, candy1,
288*18197Sjaap 							&alpha,
289*18197Sjaap 							&beta,
290*18197Sjaap 							&collinear
291*18197Sjaap 						)
292*18197Sjaap 						&& (0.0 < alpha)
293*18197Sjaap 						&& (alpha < 1.0)
294*18197Sjaap 					)
295*18197Sjaap 						opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
296*18197Sjaap 					break;
297*18197Sjaap 				}
298*18197Sjaap 				if (!X) {
299*18197Sjaap 					if (
300*18197Sjaap 						llinter (
301*18197Sjaap 							prevedge->etx, prevedge->ety,
302*18197Sjaap 							curedge->stx, curedge->sty,
303*18197Sjaap 							candx0, candy0,
304*18197Sjaap 							candx1, candy1,
305*18197Sjaap 							&alpha,
306*18197Sjaap 							&beta,
307*18197Sjaap 							&collinear
308*18197Sjaap 						)
309*18197Sjaap 						&& (alpha > 0.0)
310*18197Sjaap 						&& (alpha < 1.0)
311*18197Sjaap 					)
312*18197Sjaap 					opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
313*18197Sjaap 					break;
314*18197Sjaap 				}
315*18197Sjaap 				impossible("polyline(II:AT0)");
316*18197Sjaap 				break;
317*18197Sjaap 			case AT1:
318*18197Sjaap 				/* should be taken care of by next AT0 */
319*18197Sjaap 				break;
320*18197Sjaap 			case ON0:
321*18197Sjaap 			case ON1:
322*18197Sjaap 				X = arecollinear(prevedge->etx,prevedge->ety,curedge->sx,curedge->sy,curedge->next->stx,curedge->next->sty);
323*18197Sjaap 				Y = llinter(
324*18197Sjaap 					prevedge->etx,prevedge->ety,
325*18197Sjaap 					curedge->next->stx,curedge->sty,
326*18197Sjaap 					candx0,candy0,
327*18197Sjaap 					candx1,candy1,
328*18197Sjaap 					&alpha,
329*18197Sjaap 					&beta,
330*18197Sjaap 					&collinear
331*18197Sjaap 				)
332*18197Sjaap 				&& (alpha > 0.0)
333*18197Sjaap 				&& (alpha < 1.0)
334*18197Sjaap 				;
335*18197Sjaap 				Z = llinter (
336*18197Sjaap 					prevedge->sx,prevedge->sy,
337*18197Sjaap 					curedge->next->ex,curedge->next->ey,
338*18197Sjaap 					candx0,candy0,
339*18197Sjaap 					candx1,candy1,
340*18197Sjaap 					&alpha,
341*18197Sjaap 					&beta,
342*18197Sjaap 					&collinear
343*18197Sjaap 				)
344*18197Sjaap 				&& (alpha > 0.0)
345*18197Sjaap 				&& (alpha < 1.0)
346*18197Sjaap 				;
347*18197Sjaap 				W = prevedge == curedge->next->next;
348*18197Sjaap 				dprintf "X=%d Y=%d, Z=%d, W=%d\n", X, Y, Z, W);
349*18197Sjaap 				if (!Y && W)
350*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?EXT0:EXT1, curedge->alpha[i], &alphalist);
351*18197Sjaap 				else if (!X && Y)
352*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?INFL0:INFL1, curedge->alpha[i], &alphalist);
353*18197Sjaap 				else if (X && Z)
354*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?INFL0:INFL1, curedge->alpha[i], &alphalist);
355*18197Sjaap 				else
356*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?EXT0:EXT1, curedge->alpha[i], &alphalist);
357*18197Sjaap 				break;
358*18197Sjaap 			case TANGENT:
359*18197Sjaap 			default:
360*18197Sjaap 				impossible ("polyline(B)");
361*18197Sjaap 				break;
362*18197Sjaap 			}
363*18197Sjaap 		prevedge = curedge;
364*18197Sjaap 		curedge = curedge->next;
365*18197Sjaap 	} while (prevedge != edgelist);
366*18197Sjaap 	opqinsert(INHERIT, 0.0, &alphalist);
367*18197Sjaap 	opqinsert(INHERIT, 1.0, &alphalist);
368*18197Sjaap 	if (dbg) {
369*18197Sjaap 		fprintf (stderr, "interalpha:\n");
370*18197Sjaap 		for (interwalk = alphalist;
371*18197Sjaap 			interwalk;
372*18197Sjaap 			interwalk = interwalk->next)
373*18197Sjaap 			fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
374*18197Sjaap 		fprintf (stderr, "\n");
375*18197Sjaap 	}
376*18197Sjaap 	inside = onedge = FALSE;
377*18197Sjaap 	for (interwalk = alphalist; interwalk; interwalk = interwalk->next)
378*18197Sjaap 		switch (interwalk->code) {
379*18197Sjaap 		case SIMPLE:
380*18197Sjaap 			interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
381*18197Sjaap 			inside = !inside;
382*18197Sjaap 			break;
383*18197Sjaap 		case EXT1:
384*18197Sjaap 			interwalk->code = inside?INBEGIN:OUTBEGIN;
385*18197Sjaap 			onedge = FALSE;
386*18197Sjaap 			break;
387*18197Sjaap 		case EXT0:
388*18197Sjaap 			interwalk->code = ONBEGIN;
389*18197Sjaap 			onedge = TRUE;
390*18197Sjaap 			break;
391*18197Sjaap 		case INFL1:
392*18197Sjaap 			interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
393*18197Sjaap 			onedge = FALSE;
394*18197Sjaap 			inside = !inside;
395*18197Sjaap 			break;
396*18197Sjaap 		case INFL0:
397*18197Sjaap 			interwalk->code = ONBEGIN;
398*18197Sjaap 			onedge = TRUE;
399*18197Sjaap 			break;
400*18197Sjaap 		case INHERIT:
401*18197Sjaap 		case IGNORE:
402*18197Sjaap 			interwalk->code = onedge?ONBEGIN:(inside?INBEGIN:OUTBEGIN);
403*18197Sjaap 			break;
404*18197Sjaap 			break;
405*18197Sjaap 		default:
406*18197Sjaap 			impossible("polyline(C)");
407*18197Sjaap 			break;
408*18197Sjaap 		}
409*18197Sjaap 	if (dbg) {
410*18197Sjaap 		fprintf (stderr, "interalpha:\n");
411*18197Sjaap 		for (interwalk = alphalist;
412*18197Sjaap 			interwalk;
413*18197Sjaap 			interwalk = interwalk->next)
414*18197Sjaap 			fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
415*18197Sjaap 		fprintf (stderr, "\n");
416*18197Sjaap 	}
417*18197Sjaap 	for (interwalk = alphalist; interwalk; interwalk = interwalk->next) {
418*18197Sjaap 		linewalk = linegen (
419*18197Sjaap 			candx0 + interwalk->alpha*(candx1 - candx0),
420*18197Sjaap 			candy0 + interwalk->alpha*(candy1 - candy0),
421*18197Sjaap 			candx0 + interwalk->next->alpha*(candx1 - candx0),
422*18197Sjaap 			candy0 + interwalk->next->alpha*(candy1 - candy0)
423*18197Sjaap 		);
424*18197Sjaap 		if (
425*18197Sjaap 			interwalk->alpha > -EPSILON
426*18197Sjaap 			&& interwalk->next
427*18197Sjaap 			&& interwalk->next->alpha < 1.0 + EPSILON
428*18197Sjaap 		)
429*18197Sjaap 			switch (interwalk->code) {
430*18197Sjaap 			case INBEGIN:
431*18197Sjaap 				inwalk->next = linewalk;
432*18197Sjaap 				inwalk = inwalk->next;
433*18197Sjaap 				break;
434*18197Sjaap 			case OUTBEGIN:
435*18197Sjaap 				outwalk->next = linewalk;
436*18197Sjaap 				outwalk = outwalk->next;
437*18197Sjaap 				break;
438*18197Sjaap 			case ONBEGIN:
439*18197Sjaap 				tryfree(linewalk);
440*18197Sjaap 				break;
441*18197Sjaap 			default:
442*18197Sjaap 				impossible("polyline(D)");
443*18197Sjaap 				break;
444*18197Sjaap 			}
445*18197Sjaap 	}
446*18197Sjaap 	*inlines = nuin.next;
447*18197Sjaap 	*outlines = nuout.next;
448*18197Sjaap 	*both = NULL;
449*18197Sjaap }
450*18197Sjaap 
451*18197Sjaap #define	xtanp(x,y,r,t)	x+r*cos(t)+sin(t)
452*18197Sjaap #define	ytanp(x,y,r,t)	y+r*sin(t)-cos(t)
453*18197Sjaap #define	xtane(x,y,r,t)	x+r*cos(t)-sin(t)
454*18197Sjaap #define	ytane(x,y,r,t)	y+r*sin(t)+cos(t)
455*18197Sjaap 
ptinpoly(edgelist,x,y)456*18197Sjaap boolean ptinpoly (edgelist, x, y)
457*18197Sjaap EDGEPTR edgelist;
458*18197Sjaap float x, y;
459*18197Sjaap {
460*18197Sjaap 	LINEPTR inlines, outlines, both;
461*18197Sjaap 	polyline (
462*18197Sjaap 		edgelist,
463*18197Sjaap 		x - 100*EPSILON, y - 100*EPSILON,
464*18197Sjaap 		x + 100*EPSILON, y + 100*EPSILON,
465*18197Sjaap 		&inlines, &outlines, &both
466*18197Sjaap 	);
467*18197Sjaap 	if (inlines) {
468*18197Sjaap 		if (outlines || both)
469*18197Sjaap 			impossible ("ptinpoly(A)");
470*18197Sjaap 		else {
471*18197Sjaap 			linefree(inlines);
472*18197Sjaap 			dprintf "ptinpoly: TRUE\n");
473*18197Sjaap 			return TRUE;
474*18197Sjaap 		}
475*18197Sjaap 	} else if (outlines) {
476*18197Sjaap 		if (inlines || both)
477*18197Sjaap 			impossible ("ptinpoly(B)");
478*18197Sjaap 		else {
479*18197Sjaap 			linefree(outlines);
480*18197Sjaap 			dprintf "ptinpoly: FALSE\n");
481*18197Sjaap 			return FALSE;
482*18197Sjaap 		}
483*18197Sjaap 	} else
484*18197Sjaap 		impossible ("ptinpoly(C)");
485*18197Sjaap }
486*18197Sjaap 
polyarc(edgelist,x0,y0,radius,startang,endang,inlines,outlines,both)487*18197Sjaap void polyarc (edgelist, x0,y0, radius, startang, endang, inlines, outlines, both)
488*18197Sjaap EDGEPTR edgelist;
489*18197Sjaap float x0, y0, radius, startang, endang;
490*18197Sjaap LINEPTR *inlines, *outlines, *both;
491*18197Sjaap {
492*18197Sjaap 	OPQPTR interwalk;
493*18197Sjaap 	boolean inside, onedge;
494*18197Sjaap 	LINENODE nuin, nuout;
495*18197Sjaap 	LINEPTR inwalk, outwalk;
496*18197Sjaap 	LINEPTR linewalk;
497*18197Sjaap 	EDGEPTR prevedge, curedge;
498*18197Sjaap 	OPQPTR alphalist;
499*18197Sjaap 	float alpha[2], beta[2], gamma[2], theta[2];
500*18197Sjaap 	boolean collinear;
501*18197Sjaap 	boolean X, Y, Z, W;
502*18197Sjaap 	float stx, sty, etx, ety;
503*18197Sjaap 	int i;
504*18197Sjaap 	double dummy, rem;
505*18197Sjaap 
506*18197Sjaap 	alphalist = (OPQPTR) NULL;
507*18197Sjaap 	inwalk = &nuin;
508*18197Sjaap 	inwalk->next = NULL;
509*18197Sjaap 	outwalk = &nuout;
510*18197Sjaap 	outwalk->next = NULL;
511*18197Sjaap 	curedge = edgelist;
512*18197Sjaap 	do {
513*18197Sjaap 		if (curedge->fax == NULL) {
514*18197Sjaap 			if (
515*18197Sjaap 				lcinter (
516*18197Sjaap 					curedge->sx, curedge->sy,
517*18197Sjaap 					curedge->ex, curedge->ey,
518*18197Sjaap 					x0, y0,
519*18197Sjaap 					radius,
520*18197Sjaap 					&alpha[0], &theta[0],
521*18197Sjaap 					&alpha[1], &theta[1]
522*18197Sjaap 				)
523*18197Sjaap 			) {
524*18197Sjaap 				if (fabs(theta[0] - theta[1]) < EPSILON) {
525*18197Sjaap 					if (fabs(alpha[0]) < EPSILON)
526*18197Sjaap 						curedge->code[0] = AT0;
527*18197Sjaap 					else if (fabs(1.0-alpha[0]) < EPSILON)
528*18197Sjaap 						curedge->code[0] = AT1;
529*18197Sjaap 					else
530*18197Sjaap 						curedge->code[0] = TANGENT;
531*18197Sjaap 					curedge->alpha[0] = rprin(theta[0]);
532*18197Sjaap 					curedge->code[1] = UNUSED;
533*18197Sjaap 				} else {
534*18197Sjaap 					for (i = 0; i < 2; i ++) {
535*18197Sjaap 						if (EPSILON < alpha[i] && alpha[i] < 1.0 - EPSILON)
536*18197Sjaap 							curedge->code[i] = SIMPLE;
537*18197Sjaap 						else if (fabs(alpha[i]) < EPSILON)
538*18197Sjaap 							curedge->code[i] = AT0;
539*18197Sjaap 						else if (fabs(alpha[i] - 1.0) < EPSILON)
540*18197Sjaap 							curedge->code[i] = AT1;
541*18197Sjaap 						else
542*18197Sjaap 							curedge->code[i] = UNUSED;
543*18197Sjaap 						curedge->alpha[i] = rprin(theta[i]);
544*18197Sjaap 					}
545*18197Sjaap 				}
546*18197Sjaap 			}
547*18197Sjaap 		} else if (curedge->fax->kind == ARC) {
548*18197Sjaap 			if (!ccinter (
549*18197Sjaap 					x0, y0,
550*18197Sjaap 					radius,
551*18197Sjaap 					curedge->fax->x0, curedge->fax->y0,
552*18197Sjaap 					curedge->fax->radius,
553*18197Sjaap 					&gamma[0], &theta[0],
554*18197Sjaap 					&gamma[1], &theta[1]
555*18197Sjaap 				)
556*18197Sjaap 			) {
557*18197Sjaap 				if (fabs(x0 - curedge->fax->x0) < EPSILON
558*18197Sjaap 					&& fabs(y0 - curedge->fax->y0) < EPSILON
559*18197Sjaap 					&& fabs(fabs(radius) - fabs(curedge->fax->radius)) < EPSILON
560*18197Sjaap 				) {
561*18197Sjaap 					curedge->alpha[0] = rprin(curedge->fax->theta1);
562*18197Sjaap 					curedge->alpha[1] = rprin(curedge->fax->theta2);
563*18197Sjaap 					curedge->code[0] = ON0;
564*18197Sjaap 					curedge->code[1] = ON1;
565*18197Sjaap 				} else {
566*18197Sjaap 					curedge->code[0] = curedge->code[1] = UNUSED;
567*18197Sjaap 				}
568*18197Sjaap 			} else if (fabs(theta[0] - theta[1]) < EPSILON) {
569*18197Sjaap 				if (fabs(theta[0] - curedge->fax->theta1) < EPSILON)
570*18197Sjaap 					curedge->code[0] = curedge->flipped?AT1:AT0;
571*18197Sjaap 				else if (fabs(theta[0] - curedge->fax->theta2) < EPSILON)
572*18197Sjaap 					curedge->code[0] = curedge->flipped?AT0:AT1;
573*18197Sjaap 				else
574*18197Sjaap 					curedge->code[0] = TANGENT;
575*18197Sjaap 				curedge->alpha[0] = rprin(gamma[0]);
576*18197Sjaap 				curedge->code[1] = UNUSED;
577*18197Sjaap 			} else {
578*18197Sjaap 				for (i = 0; i < 2; i ++) {
579*18197Sjaap 					dprintf "disposition of %f\n", theta[i]);
580*18197Sjaap 					if (curedge->fax->theta2 < 2.0*PI) {
581*18197Sjaap 						if (theta[i] - curedge->fax->theta1 < -EPSILON
582*18197Sjaap 							|| curedge->fax->theta2 - theta[i] < -EPSILON) {
583*18197Sjaap 							curedge->code[i] = UNUSED;
584*18197Sjaap 							dprintf "intersection off arc\n");
585*18197Sjaap 							continue;
586*18197Sjaap 						}
587*18197Sjaap 					}
588*18197Sjaap 					if (curedge->fax->theta2 > 2.0*PI) {
589*18197Sjaap 						if (theta[i] - curedge->fax->theta1 < -EPSILON
590*18197Sjaap 							&& curedge->fax->theta2 - theta[i] < 2.0*PI - EPSILON) {
591*18197Sjaap 							curedge->code[i] = UNUSED;
592*18197Sjaap 							dprintf "intersection off arc\n");
593*18197Sjaap 							continue;
594*18197Sjaap 						}
595*18197Sjaap 					}
596*18197Sjaap 					rem = modf(fabs(theta[i] - curedge->fax->theta1)/(2.0*PI), &dummy);
597*18197Sjaap 					dprintf "rem1 = %f\n", rem);
598*18197Sjaap 					if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) {
599*18197Sjaap 						curedge->alpha[i] = rprin(gamma[i]);
600*18197Sjaap 						curedge->code[i] = curedge->flipped?AT1:AT0;
601*18197Sjaap 						continue;
602*18197Sjaap 					}
603*18197Sjaap 					rem = modf(fabs(theta[i] - curedge->fax->theta2)/(2.0*PI), &dummy);
604*18197Sjaap 					dprintf "rem2 = %f\n", rem);
605*18197Sjaap 					if (rem < EPSILON || fabs(1.0 - rem) < EPSILON) {
606*18197Sjaap 						curedge->alpha[i] = rprin(gamma[i]);
607*18197Sjaap 						curedge->code[i] = curedge->flipped?AT0:AT1;
608*18197Sjaap 						continue;
609*18197Sjaap 					}
610*18197Sjaap 					dprintf "simple\n");
611*18197Sjaap 					curedge->code[i] = SIMPLE;
612*18197Sjaap 					curedge->alpha[i] = rprin(gamma[i]);
613*18197Sjaap 				}
614*18197Sjaap 			}
615*18197Sjaap 		} else {
616*18197Sjaap 			impossible ("polyarc(D)");
617*18197Sjaap 		}
618*18197Sjaap 		curedge = curedge->next;
619*18197Sjaap 	} while (curedge != edgelist);
620*18197Sjaap 	if (dbg) {
621*18197Sjaap 		curedge = edgelist;
622*18197Sjaap 		do {
623*18197Sjaap 			fprintf (stderr, "s (%f,%f); e (%f,%f)\n",
624*18197Sjaap 				curedge->sx, curedge->sy,
625*18197Sjaap 				curedge->ex, curedge->ey
626*18197Sjaap 			);
627*18197Sjaap 			fprintf (stderr, "st (%f,%f); et (%f,%f)\n",
628*18197Sjaap 				curedge->stx, curedge->sty,
629*18197Sjaap 				curedge->etx, curedge->ety
630*18197Sjaap 			);
631*18197Sjaap 			for (i = 0; i < POSSINTER; i ++)
632*18197Sjaap 				fprintf (stderr, "%d %f\n",
633*18197Sjaap 					curedge->code[i],
634*18197Sjaap 					curedge->alpha[i]
635*18197Sjaap 				);
636*18197Sjaap 			curedge = curedge->next;
637*18197Sjaap 		} while (curedge != edgelist);
638*18197Sjaap 	}
639*18197Sjaap 	prevedge = edgelist;
640*18197Sjaap 	curedge = edgelist->next;
641*18197Sjaap 	do {
642*18197Sjaap 		for (i = 0; i < POSSINTER; i ++) {
643*18197Sjaap 			stx = xtanp(x0,y0,radius,curedge->alpha[i]);
644*18197Sjaap 			sty = ytanp(x0,y0,radius,curedge->alpha[i]);
645*18197Sjaap 			etx = xtane(x0,y0,radius,curedge->alpha[i]);
646*18197Sjaap 			ety = ytane(x0,y0,radius,curedge->alpha[i]);
647*18197Sjaap 			switch (curedge->code[i]) {
648*18197Sjaap 			case UNUSED:
649*18197Sjaap 				break;
650*18197Sjaap 			case SIMPLE:
651*18197Sjaap 				opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
652*18197Sjaap 				break;
653*18197Sjaap 			case AT0:
654*18197Sjaap 				dprintf "vertex intersection at (%f,%f)\n", curedge->sx, curedge->sy);
655*18197Sjaap 				X = arecollinear(curedge->sx,curedge->sy,curedge->stx,curedge->sty,prevedge->etx,prevedge->ety);
656*18197Sjaap 				Y = between(curedge->stx,curedge->sty,curedge->sx,curedge->sy,prevedge->etx,prevedge->ety);
657*18197Sjaap 				Z = arecollinear(stx,sty,etx,ety,curedge->stx, curedge->sty);
658*18197Sjaap 				dprintf "X=%d Y=%d Z=%d\n", X, Y, Z);
659*18197Sjaap 				if (X && !Z) {
660*18197Sjaap 					if (Y)
661*18197Sjaap 						opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
662*18197Sjaap 					break;
663*18197Sjaap 				}
664*18197Sjaap 				if (X && Z) {
665*18197Sjaap 					if (
666*18197Sjaap 						llinter (
667*18197Sjaap 							prevedge->sx, prevedge->sy,
668*18197Sjaap 							curedge->ex, curedge->ey,
669*18197Sjaap 							stx, sty,
670*18197Sjaap 							etx, ety,
671*18197Sjaap 							&alpha[0],
672*18197Sjaap 							&alpha[1],
673*18197Sjaap 							&collinear
674*18197Sjaap 						)
675*18197Sjaap 						&& (0.0 < alpha[0])
676*18197Sjaap 						&& (alpha[0] < 1.0)
677*18197Sjaap 					)
678*18197Sjaap 						opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
679*18197Sjaap 					break;
680*18197Sjaap 				}
681*18197Sjaap 				if (!X) {
682*18197Sjaap 					if (
683*18197Sjaap 						llinter (
684*18197Sjaap 							prevedge->etx, prevedge->ety,
685*18197Sjaap 							curedge->stx, curedge->sty,
686*18197Sjaap 							stx, sty,
687*18197Sjaap 							etx, ety,
688*18197Sjaap 							&alpha[0],
689*18197Sjaap 							&alpha[1],
690*18197Sjaap 							&collinear
691*18197Sjaap 						)
692*18197Sjaap 						&& (alpha[0] > 0.0)
693*18197Sjaap 						&& (alpha[0] < 1.0)
694*18197Sjaap 					)
695*18197Sjaap 					opqinsert(SIMPLE, curedge->alpha[i], &alphalist);
696*18197Sjaap 					break;
697*18197Sjaap 				}
698*18197Sjaap 				impossible("polyline(II:AT0)");
699*18197Sjaap 				break;
700*18197Sjaap 			case AT1:
701*18197Sjaap 				/* should be taken care of by next AT0 */
702*18197Sjaap 				break;
703*18197Sjaap 			case ON0:
704*18197Sjaap 			case ON1:
705*18197Sjaap 				X = hypot(prevedge->etx - x0, prevedge->ety - y0) > fabs(radius);
706*18197Sjaap 				Y = hypot(curedge->next->stx - x0, curedge->next->sty - y0) > fabs(radius);
707*18197Sjaap 				dprintf "X=%d Y=%d\n", X, Y);
708*18197Sjaap 				Z = X && Y;
709*18197Sjaap 				W = !X && !Y;
710*18197Sjaap 				if (Z || W)
711*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?EXT0:EXT1, curedge->alpha[i], &alphalist);
712*18197Sjaap 				else
713*18197Sjaap 					opqinsert((curedge->code[i] == ON0)?INFL0:INFL1, curedge->alpha[i], &alphalist);
714*18197Sjaap 				break;
715*18197Sjaap 			case TANGENT:
716*18197Sjaap 				opqinsert(IGNORE, curedge->alpha[i], &alphalist);
717*18197Sjaap 				break;
718*18197Sjaap 			default:
719*18197Sjaap 				impossible ("polyline(B)");
720*18197Sjaap 				break;
721*18197Sjaap 			}
722*18197Sjaap 		}
723*18197Sjaap 		prevedge = curedge;
724*18197Sjaap 		curedge = curedge->next;
725*18197Sjaap 	} while (prevedge != edgelist);
726*18197Sjaap 	opqinsert(INHERIT, rprin(startang), &alphalist);
727*18197Sjaap 	opqinsert(INHERIT, rprin(endang), &alphalist);
728*18197Sjaap 	if (dbg) {
729*18197Sjaap 		fprintf (stderr, "interalpha:\n");
730*18197Sjaap 		for (interwalk = alphalist;
731*18197Sjaap 			interwalk;
732*18197Sjaap 			interwalk = interwalk->next)
733*18197Sjaap 			fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
734*18197Sjaap 		fprintf (stderr, "\n");
735*18197Sjaap 	}
736*18197Sjaap 	((OPQPTR) tail((NAMEPTR) alphalist))->next = alphalist;
737*18197Sjaap 	interwalk = alphalist;
738*18197Sjaap 	onedge = FALSE;
739*18197Sjaap 	do {
740*18197Sjaap 		switch (interwalk->code) {
741*18197Sjaap 		case EXT0:
742*18197Sjaap 			alpha[0] = interwalk->alpha;
743*18197Sjaap 			onedge = TRUE;
744*18197Sjaap 			break;
745*18197Sjaap 		case EXT1:
746*18197Sjaap 			alpha[1] = interwalk->alpha;
747*18197Sjaap 			onedge = TRUE;
748*18197Sjaap 			break;
749*18197Sjaap 		case INFL0:
750*18197Sjaap 			alpha[0] = interwalk->alpha;
751*18197Sjaap 			onedge = TRUE;
752*18197Sjaap 			break;
753*18197Sjaap 		case INFL1:
754*18197Sjaap 			alpha[1] = interwalk->alpha;
755*18197Sjaap 			onedge = TRUE;
756*18197Sjaap 			break;
757*18197Sjaap 		default:
758*18197Sjaap 			break;
759*18197Sjaap 		}
760*18197Sjaap 		interwalk = interwalk->next;
761*18197Sjaap 	} while (interwalk != alphalist);
762*18197Sjaap 	if (onedge) {
763*18197Sjaap 		rem = modf(fabs(alpha[0]-alpha[1])/(2.0*PI), &dummy);
764*18197Sjaap 		if (rem < EPSILON || fabs(1.0-rem) < EPSILON)
765*18197Sjaap 			return;
766*18197Sjaap 	}
767*18197Sjaap 	interwalk = alphalist;
768*18197Sjaap 	do {
769*18197Sjaap 		if (interwalk->code == EXT0 || interwalk->code == INFL0 || interwalk->code == INHERIT)
770*18197Sjaap 			interwalk = interwalk->next;
771*18197Sjaap 		else
772*18197Sjaap 			break;
773*18197Sjaap 	} while (interwalk != alphalist);
774*18197Sjaap 	inside = ptinpoly (
775*18197Sjaap 		edgelist,
776*18197Sjaap 		x0 + fabs(radius)*cos((interwalk->alpha + interwalk->next->alpha)/2.0),
777*18197Sjaap 		y0 + fabs(radius)*sin((interwalk->alpha + interwalk->next->alpha)/2.0)
778*18197Sjaap 	);
779*18197Sjaap 	dprintf "inside: %d\n", inside);
780*18197Sjaap 	alphalist = interwalk->next;
781*18197Sjaap 	interwalk = alphalist;
782*18197Sjaap 	onedge = FALSE;
783*18197Sjaap 	do {
784*18197Sjaap 		switch (interwalk->code) {
785*18197Sjaap 		case SIMPLE:
786*18197Sjaap 			interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
787*18197Sjaap 			inside = !inside;
788*18197Sjaap 			break;
789*18197Sjaap 		case EXT1:
790*18197Sjaap 			interwalk->code = inside?INBEGIN:OUTBEGIN;
791*18197Sjaap 			onedge = FALSE;
792*18197Sjaap 			break;
793*18197Sjaap 		case EXT0:
794*18197Sjaap 			interwalk->code = ONBEGIN;
795*18197Sjaap 			onedge = TRUE;
796*18197Sjaap 			break;
797*18197Sjaap 		case INFL1:
798*18197Sjaap 			interwalk->code = (!inside)?INBEGIN:OUTBEGIN;
799*18197Sjaap 			inside = !inside;
800*18197Sjaap 			onedge = FALSE;
801*18197Sjaap 			break;
802*18197Sjaap 		case INFL0:
803*18197Sjaap 			interwalk->code = ONBEGIN;
804*18197Sjaap 			onedge = TRUE;
805*18197Sjaap 			break;
806*18197Sjaap 		case INHERIT:
807*18197Sjaap 		case IGNORE:
808*18197Sjaap 			interwalk->code = onedge?ONBEGIN:(inside?INBEGIN:OUTBEGIN);
809*18197Sjaap 			break;
810*18197Sjaap 		default:
811*18197Sjaap 			impossible("polyline(C)");
812*18197Sjaap 			break;
813*18197Sjaap 		}
814*18197Sjaap 		interwalk = interwalk->next;
815*18197Sjaap 	} while (interwalk != alphalist);
816*18197Sjaap 	while (alphalist->alpha < alphalist->next->alpha)
817*18197Sjaap 		alphalist = alphalist->next;
818*18197Sjaap 	alphalist = alphalist->next;
819*18197Sjaap 	if (dbg) {
820*18197Sjaap 		fprintf (stderr, "interalpha:\n");
821*18197Sjaap 		interwalk = alphalist;
822*18197Sjaap 		do {
823*18197Sjaap 			fprintf (stderr, "%d %f, ", interwalk->code, interwalk->alpha);
824*18197Sjaap 			interwalk = interwalk->next;
825*18197Sjaap 		} while (interwalk != alphalist);
826*18197Sjaap 		fprintf (stderr, "\n");
827*18197Sjaap 	}
828*18197Sjaap 	interwalk = alphalist;
829*18197Sjaap 	do {
830*18197Sjaap 		if (interwalk->alpha > interwalk->next->alpha)
831*18197Sjaap 			break;
832*18197Sjaap 		if (endang < 2.0*PI + EPSILON) {
833*18197Sjaap 			if (interwalk->alpha < startang - EPSILON || interwalk->alpha > endang + EPSILON) {
834*18197Sjaap 				dprintf "arc rejected (A)\n");
835*18197Sjaap 				interwalk = interwalk->next;
836*18197Sjaap 				continue;
837*18197Sjaap 			}
838*18197Sjaap 			if (interwalk->next->alpha < startang - EPSILON || interwalk->next->alpha > endang + EPSILON) {
839*18197Sjaap 				dprintf "arc rejected (B)\n");
840*18197Sjaap 				interwalk = interwalk->next;
841*18197Sjaap 				continue;
842*18197Sjaap 			}
843*18197Sjaap 		} else {
844*18197Sjaap 			if (interwalk->alpha < startang - EPSILON && interwalk->alpha > endang + EPSILON - 2.0*PI) {
845*18197Sjaap 				dprintf "arc rejected (C)\n");
846*18197Sjaap 				interwalk = interwalk->next;
847*18197Sjaap 				continue;
848*18197Sjaap 			}
849*18197Sjaap 			if (interwalk->next->alpha < startang - EPSILON && interwalk->next->alpha > endang + EPSILON - 2.0*PI) {
850*18197Sjaap 				dprintf "arc rejected (D)\n");
851*18197Sjaap 				interwalk = interwalk->next;
852*18197Sjaap 				continue;
853*18197Sjaap 			}
854*18197Sjaap 		}
855*18197Sjaap 		linewalk = angularc (
856*18197Sjaap 			x0, y0,
857*18197Sjaap 			radius,
858*18197Sjaap 			interwalk->alpha,
859*18197Sjaap 			interwalk->next->alpha
860*18197Sjaap 		);
861*18197Sjaap 		switch (interwalk->code) {
862*18197Sjaap 		case INBEGIN:
863*18197Sjaap 			inwalk->next = linewalk;
864*18197Sjaap 			inwalk = inwalk->next;
865*18197Sjaap 			break;
866*18197Sjaap 		case OUTBEGIN:
867*18197Sjaap 			outwalk->next = linewalk;
868*18197Sjaap 			outwalk = outwalk->next;
869*18197Sjaap 			break;
870*18197Sjaap 		case ONBEGIN:
871*18197Sjaap 			tryfree(linewalk);
872*18197Sjaap 			break;
873*18197Sjaap 		default:
874*18197Sjaap 			impossible("polyline(D)");
875*18197Sjaap 			break;
876*18197Sjaap 		}
877*18197Sjaap 		interwalk = interwalk->next;
878*18197Sjaap 	} while (interwalk != alphalist);
879*18197Sjaap 	*inlines = nuin.next;
880*18197Sjaap 	*outlines = nuout.next;
881*18197Sjaap 	*both = NULL;
882*18197Sjaap }
883