112 #define INVERT_TRISTRIPS FALSE 121 #define EQ(a, b) (fabs((a) - (b)) <= GPC_EPSILON) 123 #define PREV_INDEX(i, n) ((i - 1 + n) % n) 124 #define NEXT_INDEX(i, n) ((i + 1 ) % n) 126 #define OPTIMAL(v, i, n) ((v[PREV_INDEX(i, n)].y != v[i].y) || \ 127 (v[NEXT_INDEX(i, n)].y != v[i].y)) 129 #define FWD_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y >= v[i].vertex.y) \ 130 && (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y)) 132 #define NOT_FMAX(v, i, n) (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y) 134 #define REV_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) \ 135 && (v[NEXT_INDEX(i, n)].vertex.y >= v[i].vertex.y)) 137 #define NOT_RMAX(v, i, n) (v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) 139 #define VERTEX(e,p,s,x,y) {add_vertex(&((e)->outp[(p)]->v[(s)]), x, y); \ 140 (e)->outp[(p)]->active++;} 142 #define P_EDGE(d,e,p,i,j) {(d)= (e); \ 143 do {(d)= (d)->prev;} while (!(d)->outp[(p)]); \ 144 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);} 146 #define N_EDGE(d,e,p,i,j) {(d)= (e); \ 147 do {(d)= (d)->next;} while (!(d)->outp[(p)]); \ 148 (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);} 150 #define MALLOC(p, b, s, t) {if ((b) > 0) { \ 151 p= (t*)malloc(b); if (!(p)) { \ 152 fprintf(stderr, "gpc malloc failure: %s\n", s); \ 153 exit(0);}} else p= NULL;} 155 #define FREE(p) {if (p) {free(p); (p)= NULL;}} 221 : prev(0),next(0),pred(0),succ(0),next_bound(0)
346 if (e[0].bot.x < (*b)[0].
bot.
x)
355 if (e[0].bot.x == (*b)[0].
bot.
x)
358 if (e[0].dx < (*b)[0].dx)
390 (*lmt)->first_bound= NULL;
392 return &((*lmt)->first_bound);
401 (*lmt)->first_bound= NULL;
402 (*lmt)->next= existing_node;
403 return &((*lmt)->first_bound);
411 return &((*lmt)->first_bound);
422 (*sbtree)->less= NULL;
423 (*sbtree)->more= NULL;
428 if ((*sbtree)->y > y)
435 if ((*sbtree)->y < y)
449 sbt[*entries]= sbtree->
y;
487 int i, min, max, num_edges, v, num_vertices;
488 int total_vertices= 0, e_index=0;
496 for(
int k=0;k<total_vertices;++k)
518 edge_table[num_vertices].vertex.y);
524 for (min= 0; min < num_vertices; min++)
527 if (
FWD_MIN(edge_table, min, num_vertices))
532 while (
NOT_FMAX(edge_table, max, num_vertices))
539 e= &edge_table[e_index];
545 for (i= 0; i < num_edges; i++)
556 (e[i].top.y - e[i].
bot.
y);
562 e[i].
succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
564 e[i].
pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
574 for (min= 0; min < num_vertices; min++)
577 if (
REV_MIN(edge_table, min, num_vertices))
582 while (
NOT_RMAX(edge_table, max, num_vertices))
589 e= &edge_table[e_index];
595 for (i= 0; i < num_edges; i++)
606 (e[i].top.y - e[i].
bot.
y);
612 e[i].
succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
614 e[i].
pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
640 if (edge->
xb < (*aet)->xb)
650 if (edge->
xb == (*aet)->xb)
653 if (edge->
dx < (*aet)->dx)
694 if ((*it)->point.y > y)
703 (*it)->
next= existing_node;
730 den= ((*st)->xt - (*st)->xb) - (edge->
xt - edge->
xb);
733 if ((edge->
xt >= (*st)->xt) || (edge->
dx == (*st)->dx) ||
734 (fabs(den) <= DBL_EPSILON))
743 (*st)->prev= existing_node;
748 r= (edge->
xb - (*st)->xb) / den;
749 x= (*st)->
xb + r * ((*st)->xt - (*st)->xb);
772 for (edge= aet; edge; edge= edge->
next)
793 for (nc= 0; polygon; polygon= polygon->
next)
826 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
845 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
846 if(q == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
859 for (target= p->
proxy; list; list= list->
next)
861 if (list->
proxy == target)
875 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
895 if(p == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
896 if(q == NULL)
throw runtime_error(
"GPC: Something's wrong.") ;
909 for (target= p->
proxy; list; list= list->
next)
911 if (list->
proxy == target)
943 (*p)->next= existing_min;
958 for (total= 0; tn; tn= tn->
next)
989 (*tn)->v[
LEFT]= NULL;
990 (*tn)->v[
RIGHT]= NULL;
1012 box[c].
xmin= DBL_MAX;
1013 box[c].
ymin= DBL_MAX;
1014 box[c].
xmax= -DBL_MAX;
1015 box[c].
ymax= -DBL_MAX;
1036 bbox *s_bbox, *c_bbox;
1037 int *o_table, overlap;
1043 "overlap table creation",
int);
1049 (!((s_bbox[s].
xmax < c_bbox[c].
xmin) ||
1050 (s_bbox[s].
xmin > c_bbox[c].
xmax))) &&
1051 (!((s_bbox[s].
ymax < c_bbox[c].
ymin) ||
1052 (s_bbox[s].ymin > c_bbox[c].ymax)));
1058 for (
size_t s= 0; (!overlap) && (s < subj->num_contours); s++)
1072 for (
size_t c= 0; (!overlap) && (c < clip->num_contours); c++)
1137 if (write_hole_flags)
1138 fprintf(fp,
"%d\n", p->
hole[c]);
1141 fprintf(fp,
"% .*lf % .*lf\n",
1156 *
sizeof(
int),
"contour hole addition",
int);
1165 extended_hole[c]= p->
hole[c];
1166 extended_contour[c]= p->
contour[c];
1171 extended_hole[c]= hole;
1176 extended_contour[c].vertex[v]= new_contour->
vertex[v];
1184 p->
hole= extended_hole;
1193 it_node *it= NULL, *intersect=0;
1194 edge_node *edge=0, *prev_edge=0, *next_edge=0, *succ_edge=0, *e0=0, *e1=0;
1195 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL;
1197 polygon_node *out_poly= NULL, *p=0, *q=0, *poly=0, *npoly=0, *cf= NULL;
1200 int in[2], exists[2], parity[2]= {
LEFT,
LEFT};
1201 int c, v, contributing=0, search, scanbeam= 0, sbt_entries= 0;
1202 int vclass=0, bl=0, br=0, tl=0, tr=0;
1203 double *sbt= NULL, xb, px, yb, yt=0.0, dy=0.0, ix, iy;
1223 s_heap=
build_lmt(&lmt, &sbtree, &sbt_entries, subj,
SUBJ, op);
1225 c_heap=
build_lmt(&lmt, &sbtree, &sbt_entries, clip,
CLIP, op);
1240 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1258 while (scanbeam < sbt_entries)
1261 yb= sbt[scanbeam++];
1262 if (scanbeam < sbt_entries)
1273 if (local_min->y == yb)
1276 for (edge= local_min->first_bound; edge; edge= edge->
next_bound)
1279 local_min= local_min->next;
1295 for (next_edge= aet->
next; next_edge; next_edge= next_edge->
next)
1298 next_edge->bundle[
ABOVE][ next_edge->type]= (next_edge->top.y != yb);
1299 next_edge->bundle[
ABOVE][!next_edge->type]=
FALSE;
1303 if (next_edge->bundle[
ABOVE][next_edge->type])
1305 if (
EQ(e0->xb, next_edge->xb) &&
EQ(e0->dx, next_edge->dx)
1306 && (e0->top.y != yb))
1308 next_edge->bundle[
ABOVE][ next_edge->type]^=
1309 e0->bundle[
ABOVE][ next_edge->type];
1310 next_edge->bundle[
ABOVE][!next_edge->type]=
1311 e0->bundle[
ABOVE][!next_edge->type];
1325 for (edge= aet; edge; edge= edge->
next)
1343 contributing= (exists[
CLIP] && (parity[
SUBJ] || horiz[
SUBJ]))
1346 && (parity[
CLIP] == parity[
SUBJ]));
1357 contributing= exists[
CLIP] || exists[
SUBJ];
1368 contributing= (exists[
CLIP] && (!parity[
SUBJ] || horiz[
SUBJ]))
1371 && (parity[
CLIP] == parity[
SUBJ]));
1391 [((exists[
CLIP] - 1) << 1) + parity[
CLIP]];
1395 [((exists[
SUBJ] - 1) << 1) + parity[
SUBJ]];
1397 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1482 if (edge->
bot.
y == yb)
1488 if (edge->
bot.
y == yb)
1501 for (edge= aet; edge; edge= edge->
next)
1503 if (edge->
top.
y == yb)
1505 prev_edge= edge->
prev;
1506 next_edge= edge->
next;
1508 prev_edge->
next= next_edge;
1512 next_edge->
prev= prev_edge;
1521 if (prev_edge->prev)
1529 if (edge->
top.
y == yt)
1536 if (scanbeam < sbt_entries)
1543 for (intersect= it; intersect; intersect= intersect->
next)
1545 e0= intersect->ie[0];
1546 e1= intersect->ie[1];
1554 ix= intersect->point.x;
1555 iy= intersect->point.y + yb;
1560 && e0->bside[
CLIP] && e1->bside[
CLIP]);
1562 || ( e1->bundle[
ABOVE][SUBJ] && e1->bside[SUBJ])
1564 && e0->bside[
SUBJ] && e1->bside[
SUBJ]);
1574 && (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
1576 && (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1578 && (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1584 ^ (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
1586 ^ (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1588 ^ (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1594 || (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
1596 || (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1598 || (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
1602 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
1615 e0->outp[
ABOVE]= NULL;
1623 e1->outp[
ABOVE]= NULL;
1631 e0->outp[
ABOVE]= NULL;
1632 e1->outp[
ABOVE]= NULL;
1644 e0->outp[
ABOVE]= NULL;
1652 e1->outp[
ABOVE]= NULL;
1660 e0->outp[
ABOVE]= NULL;
1661 e1->outp[
ABOVE]= NULL;
1690 if (e1->bundle[
ABOVE][CLIP])
1692 if (e0->bundle[
ABOVE][SUBJ])
1694 if (e1->bundle[
ABOVE][SUBJ])
1698 prev_edge= e0->prev;
1699 next_edge= e1->next;
1701 next_edge->prev= e0;
1708 prev_edge= prev_edge->prev;
1730 if(e0->next == NULL)
throw runtime_error(
"GPC internal error.") ;
1731 if(e1->next == NULL)
throw runtime_error(
"GPC internal error.") ;
1732 e0->next->prev= prev_edge;
1734 e0->next= next_edge;
1738 for (edge= aet; edge; edge= next_edge)
1740 next_edge= edge->
next;
1741 succ_edge= edge->
succ;
1743 if ((edge->
top.
y == yt) && succ_edge)
1750 prev_edge= edge->
prev;
1752 prev_edge->
next= succ_edge;
1756 next_edge->
prev= succ_edge;
1757 succ_edge->
prev= prev_edge;
1758 succ_edge->
next= next_edge;
1781 *
sizeof(
int),
"hole flag table creation",
int);
1786 for (poly= out_poly; poly; poly= npoly)
1791 result->
hole[c]= poly->proxy->hole;
1798 for (vtx= poly->proxy->v[LEFT]; vtx; vtx= nv)
1813 for (poly= out_poly; poly; poly= npoly)
1853 it_node *it= NULL, *intersect;
1854 edge_node *edge=0, *prev_edge=0, *next_edge=0, *succ_edge=0, *e0=0, *e1=0;
1855 edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL, *cf=0;
1861 int in[2], exists[2], parity[2]= {
LEFT,
LEFT};
1862 int s, v, contributing=0, search, scanbeam= 0, sbt_entries= 0;
1863 int vclass=0, bl=0, br=0, tl=0, tr=0;
1864 double *sbt= NULL, xb, px, nx, yb, yt=0.0, dy=0.0, ix, iy;
1872 result->
strip= NULL;
1883 s_heap=
build_lmt(&lmt, &sbtree, &sbt_entries, subj,
SUBJ, op);
1885 c_heap=
build_lmt(&lmt, &sbtree, &sbt_entries, clip,
CLIP, op);
1891 result->
strip= NULL;
1899 MALLOC(sbt, sbt_entries *
sizeof(
double),
"sbt creation",
double);
1911 while (scanbeam < sbt_entries)
1914 yb= sbt[scanbeam++];
1915 if (scanbeam < sbt_entries)
1926 if (local_min->y == yb)
1929 for (edge= local_min->first_bound; edge; edge= edge->
next_bound)
1932 local_min= local_min->next;
1948 for (next_edge= aet->
next; next_edge; next_edge= next_edge->
next)
1951 next_edge->bundle[
ABOVE][ next_edge->type]= (next_edge->top.y != yb);
1952 next_edge->bundle[
ABOVE][!next_edge->type]=
FALSE;
1956 if (next_edge->bundle[
ABOVE][next_edge->type])
1958 if (
EQ(e0->xb, next_edge->xb) &&
EQ(e0->dx, next_edge->dx)
1959 && (e0->top.y != yb))
1961 next_edge->bundle[
ABOVE][ next_edge->type]^=
1962 e0->bundle[
ABOVE][ next_edge->type];
1963 next_edge->bundle[
ABOVE][!next_edge->type]=
1964 e0->bundle[
ABOVE][!next_edge->type];
1978 for (edge= aet; edge; edge= edge->
next)
1996 contributing= (exists[
CLIP] && (parity[
SUBJ] || horiz[
SUBJ]))
1999 && (parity[
CLIP] == parity[
SUBJ]));
2010 contributing= exists[
CLIP] || exists[
SUBJ];
2021 contributing= (exists[
CLIP] && (!parity[
SUBJ] || horiz[
SUBJ]))
2024 && (parity[
CLIP] == parity[
SUBJ]));
2044 [((exists[
CLIP] - 1) << 1) + parity[
CLIP]];
2048 [((exists[
SUBJ] - 1) << 1) + parity[
SUBJ]];
2050 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
2082 if (cf->bot.y != yb)
2097 if (cf->bot.y != yb)
2123 if (edge->
bot.
y == yb)
2133 if (cf->bot.y == yb)
2139 if (edge->
bot.
y == yb)
2161 for (edge= aet; edge; edge= edge->
next)
2163 if (edge->
top.
y == yb)
2165 prev_edge= edge->
prev;
2166 next_edge= edge->
next;
2168 prev_edge->
next= next_edge;
2172 next_edge->
prev= prev_edge;
2181 if (prev_edge->prev)
2189 if (edge->
top.
y == yt)
2196 if (scanbeam < sbt_entries)
2203 for (intersect= it; intersect; intersect= intersect->
next)
2205 e0= intersect->ie[0];
2206 e1= intersect->ie[1];
2214 ix= intersect->point.x;
2215 iy= intersect->point.y + yb;
2220 && e0->bside[
CLIP] && e1->bside[
CLIP]);
2222 || ( e1->bundle[
ABOVE][SUBJ] && e1->bside[SUBJ])
2224 && e0->bside[
SUBJ] && e1->bside[
SUBJ]);
2234 && (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
2236 && (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2238 && (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2244 ^ (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
2246 ^ (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2248 ^ (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2254 || (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ]);
2256 || (in[SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2258 || (in[SUBJ] ^ e1->bundle[
ABOVE][SUBJ] ^ e0->bundle[
ABOVE][SUBJ]);
2262 vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
2277 e0->outp[
ABOVE]= NULL;
2287 e1->outp[
ABOVE]= NULL;
2294 e0->outp[
ABOVE]= NULL;
2295 e1->outp[
ABOVE]= NULL;
2317 e0->outp[
ABOVE]= NULL;
2327 e1->outp[
ABOVE]= NULL;
2335 e0->outp[
ABOVE]= NULL;
2336 e1->outp[
ABOVE]= NULL;
2342 next_edge->outp[
ABOVE]= prev_edge->outp[
ABOVE];
2379 if (e1->bundle[
ABOVE][CLIP])
2381 if (e0->bundle[
ABOVE][SUBJ])
2383 if (e1->bundle[
ABOVE][SUBJ])
2387 prev_edge= e0->prev;
2388 next_edge= e1->next;
2397 prev_edge= prev_edge->prev;
2400 if (prev_edge->bundle[
ABOVE][CLIP]
2401 || prev_edge->bundle[
ABOVE][SUBJ]
2421 e0->
next= next_edge;
2425 for (edge= aet; edge; edge= next_edge)
2427 next_edge= edge->
next;
2428 succ_edge= edge->
succ;
2430 if ((edge->
top.
y == yt) && succ_edge)
2437 prev_edge= edge->
prev;
2439 prev_edge->
next= succ_edge;
2443 next_edge->
prev= succ_edge;
2444 succ_edge->
prev= prev_edge;
2445 succ_edge->
next= next_edge;
2462 result->
strip= NULL;
2470 for (tn= tlist; tn; tn= tnn)
2517 for (lt= tn->v[LEFT]; lt; lt= ltn)
2522 for (rt= tn->v[
RIGHT]; rt; rt=rtn)
static void free_sbtree(sb_tree **sbtree)
static edge_node ** bound_list(lmt_node **lmt, double y)
gpc_vertex_list * contour
struct sbt_t_shape sb_tree
struct v_shape vertex_node
void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_polygon *result)
static void add_edge_to_aet(edge_node **aet, edge_node *edge, edge_node *prev)
static void build_intersection_table(it_node **it, edge_node *aet, double dy)
#define MALLOC(p, b, s, t)
unsigned long num_contours
static bbox * create_contour_bboxes(gpc_polygon *p)
static void add_intersection(it_node **it, edge_node *edge0, edge_node *edge1, double x, double y)
#define NOT_FMAX(v, i, n)
static void build_sbt(int *entries, double *sbt, sb_tree *sbtree)
static void add_left(polygon_node *p, double x, double y)
#define VERTEX(e, p, s, x, y)
static void reset_it(it_node **it)
void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, gpc_tristrip *result)
static void add_right(polygon_node *p, double x, double y)
static void add_vertex(vertex_node **t, double x, double y)
struct sbt_t_shape * more
#define NOT_RMAX(v, i, n)
void gpc_free_tristrip(gpc_tristrip *t)
static void reset_lmt(lmt_node **lmt)
#define P_EDGE(d, e, p, i, j)
static void merge_right(polygon_node *p, polygon_node *q, polygon_node *list)
void gpc_polygon_to_tristrip(gpc_polygon *s, gpc_tristrip *t)
static int count_optimal_vertices(gpc_vertex_list c)
void gpc_free_polygon(gpc_polygon *p)
static void merge_left(polygon_node *p, polygon_node *q, polygon_node *list)
static void insert_bound(edge_node **b, edge_node *e)
void gpc_write_polygon(FILE *fp, int write_hole_flags, gpc_polygon *p)
static void add_to_sbtree(int *entries, sb_tree **sbtree, double y)
static void minimax_test(gpc_polygon *subj, gpc_polygon *clip, gpc_op op)
static void new_tristrip(polygon_node **tn, edge_node *edge, double x, double y)
void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole)
static void add_local_min(polygon_node **p, edge_node *edge, double x, double y)
static int count_tristrips(polygon_node *tn)
const h_state next_h_state[3][6]
struct sbt_t_shape * less
#define N_EDGE(d, e, p, i, j)
static void add_st_edge(st_node **st, it_node **it, edge_node *edge, double dy)
static int count_contours(polygon_node *polygon)
static edge_node * build_lmt(lmt_node **lmt, sb_tree **sbtree, int *sbt_entries, gpc_polygon *p, int type, gpc_op op)