25#define SLOPE(p,q) ( ( ( p.y ) - ( q.y ) ) / ( ( p.x ) - ( q.x ) ) )
27#define EQ_PT(v,w) (((v).x == (w).x) && ((v).y == (w).y))
29#define after(v) (((v)==((v)->poly->finish))?((v)->poly->start):((v)+1))
30#define prior(v) (((v)==((v)->poly->start))?((v)->poly->finish):((v)-1))
58 double a, b, c, d, e, f, g, h, t;
61 c =
after(l)->pos.x - a;
62 d =
after(l)->pos.y - b;
65 g =
after(m)->pos.x - a;
66 h =
after(m)->pos.y - b;
86static int between(
double f,
double g,
double h) {
114 c = i == 0 ? m->
pos :
after(m)->pos;
124 double m1, m2, c1, c2;
138 *y = me.
y +
SLOPE(ms, me) * (*x - me.
x);
139 }
else if (ms.
x == me.
x) {
145 c1 = ms.
y - m1 * ms.
x;
146 c2 = ls.
y - m2 * ls.
x;
147 *x = (c2 - c1) / (m1 - m2);
148 *y = (m1 * c2 - c1 * m2) / (m1 - m2);
153 if (
online(l, m, 0) == -1) {
155 pt2 =
online(m, l, 1) == -1
156 ? (
online(m, l, 0) == -1 ?
le : ls) : me;
157 }
else if (
online(l, m, 1) == -1) {
159 pt2 =
online(l, m, 0) == -1
160 ? (
online(m, l, 0) == -1 ?
le : ls) : ms;
163 if (
online(m, l, 0) != -1)
169 *x = (pt1.
x + pt2.
x) / 2;
170 *y = (pt1.
y + pt2.
y) / 2;
174 if ((ls.
x -
le.x) * (ms.
y - ls.
y) == (ls.
y -
le.y) * (ms.
x - ls.
x)) {
188 fprintf(stderr,
"seg#%d : (%.3f, %.3f) (%.3f, %.3f)\n",
199 if ((vft.
x != avft.
x && vsd.
x != avsd.
x) ||
200 (vft.
x == avft.
x && !
EQ_PT(vft, p) && !
EQ_PT(avft, p)) ||
204 fprintf(stderr,
"\nintersection at %.3f %.3f\n",
229 if (!
intpoint(l, m, &x, &y, i[2] < 0 ? 3 :
online(m, l, abs(i[0]))))
233 else if (!
intpoint(l, m, &x, &y, i[0] == i[1] ?
241static int gt(
const void *a,
const void *b) {
242 const vertex *
const *i = a;
243 const vertex *
const *j = b;
244 if ((*i)->pos.x > (*j)->pos.x) {
247 if ((*i)->pos.x < (*j)->pos.x) {
250 if ((*i)->pos.y > (*j)->pos.y) {
253 if ((*i)->pos.y < (*j)->pos.y) {
269 for (
size_t i = 0; i < nvertices; i++)
270 pvertex[i] = vertex_list + i;
273 qsort(pvertex, nvertices,
sizeof(
vertex *),
gt);
276 for (
size_t i = 0; i < nvertices; i++) {
277 vertex *
const pt1 = pvertex[i];
280 for (
int k = 0; k < 2; k++) {
281 switch (
gt(&pt1, &pt2)) {
286 for (
size_t j = 0; j <
LIST_SIZE(&all); ++j) {
299 if ((tempa = templ->
active) == 0) {
300 agerrorf(
"trying to delete a non-line\n");
312 pt2 =
after(pvertex[i]);
323#define INBOX(p,bb) ((p.x <= bb.UR.x) && (p.x >= bb.LL.x) && (p.y <= bb.UR.y) && (p.y >= bb.LL.y))
324#define NESTED(a,b) (INBOX(a.LL,b) && INBOX(a.UR,b))
338 for (i = 0; i < n_polys; i++) {
341 for (j = i+1; j < n_polys; j++) {
343 if (
NESTED(polygon_list[i].bb,polygon_list[j].bb)) {
344 if (
in_poly(*p2, pt))
return 1;
346 else if (
NESTED(polygon_list[j].bb,polygon_list[i].bb)) {
366 for (nverts = 0, i = 0; i < n_polys; i++) {
367 nverts += polys[i]->
pn;
372 for (i = vno = 0; i < n_polys; i++) {
373 polygon_list[i].
start = &vertex_list[vno];
374 bb.
LL.
x = bb.
LL.
y = DBL_MAX;
375 bb.
UR.
x = bb.
UR.
y = -DBL_MAX;
376 for (
size_t j = 0; j < polys[i]->
pn; j++) {
377 x = polys[i]->
ps[j].
x;
378 y = polys[i]->
ps[j].
y;
379 bb.
LL.
x = fmin(bb.
LL.
x,x);
380 bb.
LL.
y = fmin(bb.
LL.
y,y);
381 bb.
UR.
x = fmax(bb.
UR.
x,x);
382 bb.
UR.
y = fmax(bb.
UR.
y,y);
383 vertex_list[vno].
pos.
x = x;
384 vertex_list[vno].
pos.
y = y;
385 vertex_list[vno].
poly = &polygon_list[i];
386 vertex_list[vno].
active = 0;
389 polygon_list[i].
finish = &vertex_list[vno - 1];
390 polygon_list[i].
bb = bb;
401 found =
findInside(polys, n_polys, polygon_list);
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, 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 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[])
static bool find_intersection(vertex *l, vertex *m)
int Plegal_arrangement(Ppoly_t **polys, int n_polys)
static bool realIntersect(vertex *firstv, vertex *secondv, pointf p)
return true if a real intersection has been found
static int sign(double v)
static int online(vertex *l, vertex *m, int i)
static void putSeg(int i, vertex *v)
static int findInside(Ppoly_t **polys, int n_polys, polygon *polygon_list)
type-generic dynamically expanding list
#define LIST_APPEND(list, item)
#define LIST_REMOVE(list, item)
#define LIST_GET(list, index)