21#define SLOPE(p,q) ( ( ( p.y ) - ( q.y ) ) / ( ( p.x ) - ( q.x ) ) )
23#define EQ_PT(v,w) (((v).x == (w).x) && ((v).y == (w).y))
25#define after(v) (((v)==((v)->poly->finish))?((v)->poly->start):((v)+1))
26#define prior(v) (((v)==((v)->poly->start))?((v)->poly->finish):((v)-1))
67 double a, b, c, d, e, f, g, h, t;
70 c =
after(l)->pos.x - a;
71 d =
after(l)->pos.y - b;
74 g =
after(m)->pos.x - a;
75 h =
after(m)->pos.y - b;
95static int between(
double f,
double g,
double h) {
123 c = i == 0 ? m->
pos :
after(m)->pos;
133 double m1, m2, c1, c2;
147 *y = me.
y +
SLOPE(ms, me) * (*x - me.
x);
148 }
else if (ms.
x == me.
x) {
154 c1 = ms.
y - m1 * ms.
x;
155 c2 = ls.
y - m2 * ls.
x;
156 *x = (c2 - c1) / (m1 - m2);
157 *y = (m1 * c2 - c1 * m2) / (m1 - m2);
162 if (
online(l, m, 0) == -1) {
164 pt2 =
online(m, l, 1) == -1
165 ? (
online(m, l, 0) == -1 ?
le : ls) : me;
166 }
else if (
online(l, m, 1) == -1) {
168 pt2 =
online(l, m, 0) == -1
169 ? (
online(m, l, 0) == -1 ?
le : ls) : ms;
172 if (
online(m, l, 0) != -1)
178 *x = (pt1.
x + pt2.
x) / 2;
179 *y = (pt1.
y + pt2.
y) / 2;
183 if ((ls.
x -
le.x) * (ms.
y - ls.
y) == (ls.
y -
le.y) * (ms.
x - ls.
x)) {
197 fprintf(stderr,
"seg#%d : (%.3f, %.3f) (%.3f, %.3f)\n",
207 pointf vft, vsd, avft, avsd;
210 avft =
after(firstv)->pos;
212 avsd =
after(secondv)->pos;
214 if ((vft.
x != avft.
x && vsd.
x != avsd.
x) ||
215 (vft.
x == avft.
x && !
EQ_PT(vft, p) && !
EQ_PT(avft, p)) ||
219 fprintf(stderr,
"\nintersection at %.3f %.3f\n",
246 if (!
intpoint(l, m, &x, &y, i[2] < 0 ? 3 :
online(m, l, abs(i[0]))))
250 else if (!
intpoint(l, m, &x, &y, i[0] == i[1] ?
260static int gt(
const void *a,
const void *b) {
261 const vertex *
const *i = a;
262 const vertex *
const *j = b;
263 if ((*i)->pos.x > (*j)->pos.x) {
266 if ((*i)->pos.x < (*j)->pos.x) {
269 if ((*i)->pos.y > (*j)->pos.y) {
272 if ((*i)->pos.y < (*j)->pos.y) {
286 vertex *pt1, *pt2, *templ;
294 pvertex[i] = vertex_list + i;
302 templ = pt2 =
prior(pvertex[i]);
303 for (k = 0; k < 2; k++) {
304 switch (
gt(&pt1, &pt2)) {
310 j++, tempa = tempa->
next) {
336 if ((tempa = templ->
active) == 0) {
337 agerrorf(
"trying to delete a non-line\n");
342 else if (tempa == all.
first) {
345 }
else if (tempa == all.
final) {
362 pt2 =
after(pvertex[i]);
377#define INBOX(p,bb) ((p.x <= bb.UR.x) && (p.x >= bb.LL.x) && (p.y <= bb.UR.y) && (p.y >= bb.LL.y))
378#define NESTED(a,b) (INBOX(a.LL,b) && INBOX(a.UR,b))
393 for (i = 0; i < n_polys; i++) {
396 for (j = i+1; j < n_polys; j++) {
398 if (
NESTED(polygon_list[i].bb,polygon_list[j].bb)) {
399 if (
in_poly(*p2, pt))
return 1;
401 else if (
NESTED(polygon_list[j].bb,polygon_list[i].bb)) {
422 for (nverts = 0, i = 0; i < n_polys; i++) {
423 nverts += polys[i]->
pn;
428 for (i = vno = 0; i < n_polys; i++) {
429 polygon_list[i].
start = &vertex_list[vno];
430 bb.
LL.
x = bb.
LL.
y = DBL_MAX;
431 bb.
UR.
x = bb.
UR.
y = -DBL_MAX;
432 for (
size_t j = 0; j < polys[i]->
pn; j++) {
433 x = polys[i]->
ps[j].
x;
434 y = polys[i]->
ps[j].
y;
435 bb.
LL.
x = fmin(bb.
LL.
x,x);
436 bb.
LL.
y = fmin(bb.
LL.
y,y);
437 bb.
UR.
x = fmax(bb.
UR.
x,x);
438 bb.
UR.
y = fmax(bb.
UR.
y,y);
439 vertex_list[vno].
pos.
x = x;
440 vertex_list[vno].
pos.
y = y;
441 vertex_list[vno].
poly = &polygon_list[i];
442 vertex_list[vno].
active = 0;
445 polygon_list[i].
finish = &vertex_list[vno - 1];
446 polygon_list[i].
bb = bb;
457 found =
findInside(polys, n_polys, polygon_list);
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
void agerrorf(const char *fmt,...)
bool in_poly(const Ppoly_t poly, Ppoint_t q)
static int between(double f, double g, double h)
static int intpoint(vertex *l, vertex *m, double *x, double *y, int cond)
static int realIntersect(vertex *firstv, vertex *secondv, pointf p)
static int find_ints(vertex vertex_list[], size_t nvertices)
static int gt(const void *a, const void *b)
static void sgnarea(vertex *l, vertex *m, int i[])
int Plegal_arrangement(Ppoly_t **polys, int n_polys)
struct active_edge_list active_edge_list
static int sign(double v)
static int online(vertex *l, vertex *m, int i)
static int find_intersection(vertex *l, vertex *m)
static void putSeg(int i, vertex *v)
static int findInside(Ppoly_t **polys, int n_polys, polygon *polygon_list)
struct active_edge * next
struct active_edge * last