23 #define SLOPE(p,q) ( ( ( p.y ) - ( q.y ) ) / ( ( p.x ) - ( q.x ) ) )
25 #define EQ_PT(v,w) (((v).x == (w).x) && ((v).y == (w).y))
27 #define after(v) (((v)==((v)->poly->finish))?((v)->poly->start):((v)+1))
28 #define prior(v) (((v)==((v)->poly->start))?((v)->poly->finish):((v)-1))
46 #ifdef RECORD_INTERSECTS
70 double a, b, c, d, e, f, g, h, t;
73 c =
after(l)->pos.x - a;
74 d =
after(l)->pos.y - b;
77 g =
after(m)->pos.x - a;
78 h =
after(m)->pos.y - b;
79 t = (c * f) - (d * e);
80 i[0] = ((t == 0) ? 0 : (t > 0 ? 1 : -1));
81 t = (c * h) - (d * g);
82 i[1] = ((t == 0) ? 0 : (t > 0 ? 1 : -1));
87 static int between(
double f,
double g,
double h)
89 if ((f == g) || (g == h))
91 return ((f < g) ? (g < h ? 1 : -1) : (h < g ? 1 : -1));
100 c = (i == 0) ? m->
pos :
after(m)->pos;
101 return ((a.
x == b.
x) ? ((a.
x == c.
x)
103 between(a.
y, c.
y, b.
y))) : between(a.
x,
109 static int intpoint(
vertex *l,
vertex *m,
double *x,
double *y,
int cond)
112 double m1, m2, c1, c2;
126 *y = me.
y +
SLOPE(ms, me) * (*x - me.
x);
127 }
else if (ms.
x == me.
x) {
129 *y = le.
y +
SLOPE(ls, le) * (*x - le.
x);
133 c1 = ms.
y - (m1 * ms.
x);
134 c2 = ls.
y - (m2 * ls.
x);
135 *x = (c2 - c1) / (m1 - m2);
136 *y = ((m1 * c2) - (c1 * m2)) / (m1 - m2);
141 if (online(l, m, 0) == -1) {
145 -1) ? ((online(m, l, 0) == -1) ? le : ls) : me;
146 }
else if (online(l, m, 1) == -1) {
150 -1) ? ((online(m, l, 0) == -1) ? le : ls) : ms;
153 if (online(m, l, 0) != -1)
159 *x = (pt1.
x + pt2.
x) / 2;
160 *y = (pt1.
y + pt2.
y) / 2;
164 if ((ls.
x - le.
x) * (ms.
y - ls.
y) == (ls.
y - le.
y) * (ms.
x - ls.
x)) {
178 fprintf(stderr,
"seg#%d : (%.3f, %.3f) (%.3f, %.3f)\n",
188 pointf vft, vsd, avft, avsd;
191 avft =
after(firstv)->pos;
193 avsd =
after(secondv)->pos;
195 if (((vft.
x != avft.
x) && (vsd.
x != avsd.
x)) ||
196 ((vft.
x == avft.
x) &&
199 ((vsd.
x == avsd.
x) &&
203 fprintf(stderr,
"\nintersection at %.3f %.3f\n",
217 static int find_intersection(
vertex *l,
234 (l, m, &x, &y, (i[2] < 0) ? 3 : online(m, l,
ABS(i[0]))))
238 else if (!intpoint(l, m, &x, &y, (i[0] == i[1]) ?
239 2 *
MAX(online(l, m, 0),
240 online(l, m, 1)) : online(l, m,
ABS(i[0]))))
243 #ifdef RECORD_INTERSECTS
245 agerr(
AGERR,
"using too many intersections\n");
259 return realIntersect(l, m, p);
266 if ((t = (*i)->pos.x - (*j)->pos.x) != 0.)
267 return ((t > 0.) ? 1 : -1);
268 if ((t = (*i)->pos.y - (*j)->pos.y) == 0.)
271 return ((t > 0.) ? 1 : -1);
279 find_ints(
vertex vertex_list[],
283 int i, j, k, found = 0;
286 vertex *pt1, *pt2, *templ, **pvertex;
295 pvertex[i] = vertex_list + i;
299 (
int (*)(
const void *,
const void *))gt);
304 templ = pt2 =
prior(pvertex[i]);
305 for (k = 0; k < 2; k++) {
306 switch (gt(&pt1, &pt2)) {
312 j++, tempa = tempa->
next) {
313 found = find_intersection(tempa->
name, templ, ilist, input);
338 if ((tempa = templ->
active) == 0) {
339 agerr(
AGERR,
"trying to delete a non-line\n");
344 else if (tempa == all.
first) {
347 }
else if (tempa == all.
final) {
354 free((
char *) tempa);
361 pt2 =
after(pvertex[i]);
376 #define INBOX(p,bb) ((p.x <= bb.UR.x) && (p.x >= bb.LL.x) && (p.y <= bb.UR.y) && (p.y >= bb.LL.y))
377 #define NESTED(a,b) (INBOX(a.LL,b) && INBOX(a.UR,b))
392 for (i = 0; i < n_polys; i++) {
395 for (j = i+1; j < n_polys; j++) {
397 if (
NESTED(polygon_list[i].bb,polygon_list[j].bb)) {
398 if (
in_poly(*p2, pt))
return 1;
400 else if (
NESTED(polygon_list[j].bb,polygon_list[i].bb)) {
414 int i, j, vno, nverts, found;
424 for (i = nverts = 0; i < n_polys; i++)
425 nverts += polys[i]->pn;
429 for (i = vno = 0; i < n_polys; i++) {
430 polygon_list[i].
start = &vertex_list[vno];
433 for (j = 0; j < polys[i]->
pn; j++) {
434 x = polys[i]->
ps[j].
x;
435 y = polys[i]->
ps[j].
y;
440 vertex_list[vno].
pos.
x = x;
441 vertex_list[vno].
pos.
y = y;
442 vertex_list[vno].
poly = &polygon_list[i];
443 vertex_list[vno].
active = 0;
446 polygon_list[i].
finish = &vertex_list[vno - 1];
447 polygon_list[i].
bb = bb;
458 found = find_ints(vertex_list, polygon_list, &input, ilist);
461 found = findInside(polys, n_polys, polygon_list);
struct active_edge_list active_edge_list
int agerr(agerrlevel_t level, const char *fmt,...)
int Plegal_arrangement(Ppoly_t **polys, int n_polys)
struct active_edge * next
int in_poly(Ppoly_t argpoly, Ppoint_t q)
struct active_edge * last
EXTERN unsigned char Verbose
int intersection(Point a, Point b, Point c, Point d, Point *p)