From: Matthew Fernandez Date: Thu, 24 Nov 2022 16:48:48 +0000 (-0800) Subject: ortho: track number of trapezoids along with its array X-Git-Tag: 7.0.4~2^2~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=224b5ff242a9c3b2396e15a2689b3ee1ccc94a56;p=graphviz ortho: track number of trapezoids along with its array This is an alternative to passing around `ntraps` or relying on the `TRSIZE` computation. It is a step towards fixing an issue where the allocated number of trapezoids is exceeded. The diff looks large but most of this change is mechanical, migrating `tr` uses to be aware of the new structure. This introduces some new warnings, but the intention is to remove these in upcoming commits as we switch to on-demand allocation. Gitlab: #56 --- diff --git a/lib/ortho/partition.c b/lib/ortho/partition.c index afddf1036..0c61fc9ba 100644 --- a/lib/ortho/partition.c +++ b/lib/ortho/partition.c @@ -313,10 +313,9 @@ make_new_monotone_poly (int mcur, int v0, int v1) } /* recursively visit all the trapezoids */ -static int -traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* tr, - int mcur, int trnum, int from, int flip, int dir) -{ +static int traverse_polygon(int *visited, boxf *decomp, int size, + segment_t *seg, traps_t *tr, int mcur, int trnum, + int from, int flip, int dir) { trap_t *t; int mnew; int v0, v1; @@ -324,7 +323,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* if (trnum <= 0 || visited[trnum]) return size; - t = &tr[trnum]; + t = &tr->data[trnum]; visited[trnum] = TRUE; @@ -358,7 +357,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* { if (t->d0 > 0 && t->d1 > 0) /* downward opening triangle */ { - v0 = tr[t->d1].lseg; + v0 = tr->data[t->d1].lseg; v1 = t->lseg; if (from == t->d1) { @@ -388,7 +387,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* if (t->u0 > 0 && t->u1 > 0) /* upward opening triangle */ { v0 = t->rseg; - v1 = tr[t->u0].rseg; + v1 = tr->data[t->u0].rseg; if (from == t->u1) { mnew = make_new_monotone_poly(mcur, v1, v0); @@ -416,8 +415,8 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* { if (t->d0 > 0 && t->d1 > 0) /* downward + upward cusps */ { - v0 = tr[t->d1].lseg; - v1 = tr[t->u0].rseg; + v0 = tr->data[t->d1].lseg; + v1 = tr->data[t->u0].rseg; if ((dir == TR_FROM_DN && t->d1 == from) || (dir == TR_FROM_UP && t->u1 == from)) { @@ -440,7 +439,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* { if (_equal_to(&t->lo, &seg[t->lseg].v1)) { - v0 = tr[t->u0].rseg; + v0 = tr->data[t->u0].rseg; v1 = seg[t->lseg].next; if (dir == TR_FROM_UP && t->u0 == from) @@ -463,7 +462,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* else { v0 = t->rseg; - v1 = tr[t->u0].rseg; + v1 = tr->data[t->u0].rseg; if (dir == TR_FROM_UP && t->u1 == from) { mnew = make_new_monotone_poly(mcur, v1, v0); @@ -489,7 +488,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* { if (_equal_to(&t->hi, &seg[t->lseg].v0)) { - v0 = tr[t->d1].lseg; + v0 = tr->data[t->d1].lseg; v1 = t->lseg; if (!(dir == TR_FROM_DN && t->d0 == from)) { @@ -510,7 +509,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* } else { - v0 = tr[t->d1].lseg; + v0 = tr->data[t->d1].lseg; v1 = seg[t->rseg].next; if (dir == TR_FROM_DN && t->d1 == from) @@ -592,7 +591,7 @@ traverse_polygon (int* visited, boxf* decomp, int size, segment_t* seg, trap_t* } static int -monotonate_trapezoids(int nsegs, segment_t*seg, trap_t* tr, +monotonate_trapezoids(int nsegs, segment_t *seg, traps_t *tr, int flip, boxf* decomp) { int i, size; @@ -607,7 +606,7 @@ monotonate_trapezoids(int nsegs, segment_t*seg, trap_t* tr, /* First locate a trapezoid which lies inside the polygon */ /* and which is triangular */ for (i = 0; i < TRSIZE(nsegs); i++) - if (inside_polygon(&tr[i], seg)) break; + if (inside_polygon(&tr->data[i], seg)) break; tr_start = i; /* Initialise the mon data-structure and start spanning all the */ @@ -629,10 +628,12 @@ monotonate_trapezoids(int nsegs, segment_t*seg, trap_t* tr, /* chain */ /* traverse the polygon */ - if (tr[tr_start].u0 > 0) - size = traverse_polygon (visited, decomp, 0, seg, tr, 0, tr_start, tr[tr_start].u0, flip, TR_FROM_UP); - else if (tr[tr_start].d0 > 0) - size = traverse_polygon (visited, decomp, 0, seg, tr, 0, tr_start, tr[tr_start].d0, flip, TR_FROM_DN); + if (tr->data[tr_start].u0 > 0) + size = traverse_polygon(visited, decomp, 0, seg, tr, 0, tr_start, + tr->data[tr_start].u0, flip, TR_FROM_UP); + else if (tr->data[tr_start].d0 > 0) + size = traverse_polygon(visited, decomp, 0, seg, tr, 0, tr_start, + tr->data[tr_start].d0, flip, TR_FROM_DN); else size = 0; @@ -699,7 +700,8 @@ partition (cell* cells, int ncells, int* nrects, boxf bb) int i, j, cnt = 0; boxf* rs; int ntraps = TRSIZE(nsegs); - trap_t* trs = gv_calloc(ntraps, sizeof(trap_t)); + traps_t trs = {.length = ntraps, + .data = gv_calloc(ntraps, sizeof(trap_t))}; boxf* hor_decomp = gv_calloc(ntraps, sizeof(boxf)); boxf* vert_decomp = gv_calloc(ntraps, sizeof(boxf)); int nt; @@ -718,19 +720,19 @@ partition (cell* cells, int ncells, int* nrects, boxf bb) } srand48(173); generateRandomOrdering (nsegs, permute); - nt = construct_trapezoids(nsegs, segs, permute, ntraps, trs); + nt = construct_trapezoids(nsegs, segs, permute, &trs); if (DEBUG) { fprintf (stderr, "hor traps = %d\n", nt); } - hd_size = monotonate_trapezoids (nsegs, segs, trs, 0, hor_decomp); + hd_size = monotonate_trapezoids(nsegs, segs, &trs, 0, hor_decomp); genSegments (cells, ncells, bb, segs, 1); generateRandomOrdering (nsegs, permute); - nt = construct_trapezoids(nsegs, segs, permute, ntraps, trs); + nt = construct_trapezoids(nsegs, segs, permute, &trs); if (DEBUG) { fprintf (stderr, "ver traps = %d\n", nt); } - vd_size = monotonate_trapezoids (nsegs, segs, trs, 1, vert_decomp); + vd_size = monotonate_trapezoids(nsegs, segs, &trs, 1, vert_decomp); rs = gv_calloc(hd_size * vd_size, sizeof(boxf)); for (i=0; i +#include /* Segment attributes */ @@ -43,6 +44,12 @@ typedef struct { int state; } trap_t; +/// an array of trapezoids +typedef struct { + size_t length; + trap_t *data; +} traps_t; + #define ST_VALID 1 /* for trapezium state */ #define ST_INVALID 2 @@ -76,4 +83,4 @@ static inline int dfp_cmp(double f1, double f2) { #define _greater_than(v0, v1) \ (((v0)->y > (v1)->y + C_EPS) ? true : (((v0)->y < (v1)->y - C_EPS) ? false : ((v0)->x > (v1)->x))) -extern int construct_trapezoids(int, segment_t*, int*, int, trap_t*); +extern int construct_trapezoids(int, segment_t*, int*, traps_t *tr); diff --git a/lib/ortho/trapezoid.c b/lib/ortho/trapezoid.c index 1363ea6fa..4645ad4b0 100644 --- a/lib/ortho/trapezoid.c +++ b/lib/ortho/trapezoid.c @@ -72,12 +72,11 @@ static int newnode(void) } /* Return a free trapezoid */ -static int newtrap(trap_t* tr) -{ +static int newtrap(traps_t *tr) { if (tr_idx < TRSIZE) { - tr[tr_idx].lseg = -1; - tr[tr_idx].rseg = -1; - tr[tr_idx].state = ST_VALID; + tr->data[tr_idx].lseg = -1; + tr->data[tr_idx].rseg = -1; + tr->data[tr_idx].state = ST_VALID; return tr_idx++; } else { @@ -148,8 +147,7 @@ static bool _less_than (pointf *v0, pointf *v1) */ static int -init_query_structure(int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) -{ +init_query_structure(int segnum, segment_t *seg, traps_t *tr, qnode_t *qs) { int i1, i2, i3, i4, i5, i6, i7, root; int t1, t2, t3, t4; segment_t *s = &seg[segnum]; @@ -190,25 +188,25 @@ init_query_structure(int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) t3 = newtrap(tr); /* bottom-most */ t4 = newtrap(tr); /* topmost */ - tr[t1].hi = tr[t2].hi = tr[t4].lo = qs[i1].yval; - tr[t1].lo = tr[t2].lo = tr[t3].hi = qs[i3].yval; - tr[t4].hi.y = (double) (INF); - tr[t4].hi.x = (double) (INF); - tr[t3].lo.y = (double) -1* (INF); - tr[t3].lo.x = (double) -1* (INF); - tr[t1].rseg = tr[t2].lseg = segnum; - tr[t1].u0 = tr[t2].u0 = t4; - tr[t1].d0 = tr[t2].d0 = t3; - tr[t4].d0 = tr[t3].u0 = t1; - tr[t4].d1 = tr[t3].u1 = t2; - - tr[t1].sink = i6; - tr[t2].sink = i7; - tr[t3].sink = i4; - tr[t4].sink = i2; - - tr[t1].state = tr[t2].state = ST_VALID; - tr[t3].state = tr[t4].state = ST_VALID; + tr->data[t1].hi = tr->data[t2].hi = tr->data[t4].lo = qs[i1].yval; + tr->data[t1].lo = tr->data[t2].lo = tr->data[t3].hi = qs[i3].yval; + tr->data[t4].hi.y = (double)(INF); + tr->data[t4].hi.x = (double)(INF); + tr->data[t3].lo.y = (double)-1 * (INF); + tr->data[t3].lo.x = (double)-1 * (INF); + tr->data[t1].rseg = tr->data[t2].lseg = segnum; + tr->data[t1].u0 = tr->data[t2].u0 = t4; + tr->data[t1].d0 = tr->data[t2].d0 = t3; + tr->data[t4].d0 = tr->data[t3].u0 = t1; + tr->data[t4].d1 = tr->data[t3].u1 = t2; + + tr->data[t1].sink = i6; + tr->data[t2].sink = i7; + tr->data[t3].sink = i4; + tr->data[t4].sink = i2; + + tr->data[t1].state = tr->data[t2].state = ST_VALID; + tr->data[t3].state = tr->data[t4].state = ST_VALID; qs[i2].trnum = t4; qs[i4].trnum = t3; @@ -344,57 +342,57 @@ locate_endpoint (pointf *v, pointf *vo, int r, segment_t* seg, qnode_t* qs) * divided because of its insertion */ static void -merge_trapezoids (int segnum, int tfirst, int tlast, int side, trap_t* tr, +merge_trapezoids(int segnum, int tfirst, int tlast, int side, traps_t *tr, qnode_t* qs) { int t; /* First merge polys on the LHS */ t = tfirst; - while (t > 0 && _greater_than_equal_to(&tr[t].lo, &tr[tlast].lo)) + while (t > 0 && _greater_than_equal_to(&tr->data[t].lo, &tr->data[tlast].lo)) { int tnext, ptnext; bool cond; if (side == S_LEFT) - cond = ((tnext = tr[t].d0) > 0 && tr[tnext].rseg == segnum) || - ((tnext = tr[t].d1) > 0 && tr[tnext].rseg == segnum); + cond = ((tnext = tr->data[t].d0) > 0 && tr->data[tnext].rseg == segnum) || + ((tnext = tr->data[t].d1) > 0 && tr->data[tnext].rseg == segnum); else - cond = ((tnext = tr[t].d0) > 0 && tr[tnext].lseg == segnum) || - ((tnext = tr[t].d1) > 0 && tr[tnext].lseg == segnum); + cond = ((tnext = tr->data[t].d0) > 0 && tr->data[tnext].lseg == segnum) || + ((tnext = tr->data[t].d1) > 0 && tr->data[tnext].lseg == segnum); if (cond) { - if (tr[t].lseg == tr[tnext].lseg && - tr[t].rseg == tr[tnext].rseg) /* good neighbours */ + if (tr->data[t].lseg == tr->data[tnext].lseg && + tr->data[t].rseg == tr->data[tnext].rseg) /* good neighbours */ { /* merge them */ /* Use the upper node as the new node i.e. t */ - ptnext = qs[tr[tnext].sink].parent; + ptnext = qs[tr->data[tnext].sink].parent; - if (qs[ptnext].left == tr[tnext].sink) - qs[ptnext].left = tr[t].sink; + if (qs[ptnext].left == tr->data[tnext].sink) + qs[ptnext].left = tr->data[t].sink; else - qs[ptnext].right = tr[t].sink; /* redirect parent */ + qs[ptnext].right = tr->data[t].sink; /* redirect parent */ /* Change the upper neighbours of the lower trapezoids */ - if ((tr[t].d0 = tr[tnext].d0) > 0) { - if (tr[tr[t].d0].u0 == tnext) - tr[tr[t].d0].u0 = t; - else if (tr[tr[t].d0].u1 == tnext) - tr[tr[t].d0].u1 = t; + if ((tr->data[t].d0 = tr->data[tnext].d0) > 0) { + if (tr->data[tr->data[t].d0].u0 == tnext) + tr->data[tr->data[t].d0].u0 = t; + else if (tr->data[tr->data[t].d0].u1 == tnext) + tr->data[tr->data[t].d0].u1 = t; } - if ((tr[t].d1 = tr[tnext].d1) > 0) { - if (tr[tr[t].d1].u0 == tnext) - tr[tr[t].d1].u0 = t; - else if (tr[tr[t].d1].u1 == tnext) - tr[tr[t].d1].u1 = t; + if ((tr->data[t].d1 = tr->data[tnext].d1) > 0) { + if (tr->data[tr->data[t].d1].u0 == tnext) + tr->data[tr->data[t].d1].u0 = t; + else if (tr->data[tr->data[t].d1].u1 == tnext) + tr->data[tr->data[t].d1].u1 = t; } - tr[t].lo = tr[tnext].lo; - tr[tnext].state = ST_INVALID; /* invalidate the lower */ + tr->data[t].lo = tr->data[tnext].lo; + tr->data[tnext].state = ST_INVALID; /* invalidate the lower */ /* trapezium */ } else /* not good neighbours */ @@ -412,9 +410,7 @@ merge_trapezoids (int segnum, int tfirst, int tlast, int side, trap_t* tr, * Q-structure. Then start from the topmost trapezoid and go down to * the lower trapezoid dividing all the trapezoids in between . */ -static int -add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) -{ +static int add_segment(int segnum, segment_t *seg, traps_t *tr, qnode_t *qs) { segment_t s; int tu, tl, sk, tfirst, tlast; int tfirstr = 0, tlastr = 0, tfirstl = 0, tlastl = 0; @@ -444,31 +440,31 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) tu = locate_endpoint(&s.v0, &s.v1, s.root0, seg, qs); tl = newtrap(tr); /* tl is the new lower trapezoid */ - tr[tl].state = ST_VALID; - tr[tl] = tr[tu]; - tr[tu].lo.y = tr[tl].hi.y = s.v0.y; - tr[tu].lo.x = tr[tl].hi.x = s.v0.x; - tr[tu].d0 = tl; - tr[tu].d1 = 0; - tr[tl].u0 = tu; - tr[tl].u1 = 0; - - if ((tmp_d = tr[tl].d0) > 0 && tr[tmp_d].u0 == tu) - tr[tmp_d].u0 = tl; - if ((tmp_d = tr[tl].d0) > 0 && tr[tmp_d].u1 == tu) - tr[tmp_d].u1 = tl; - - if ((tmp_d = tr[tl].d1) > 0 && tr[tmp_d].u0 == tu) - tr[tmp_d].u0 = tl; - if ((tmp_d = tr[tl].d1) > 0 && tr[tmp_d].u1 == tu) - tr[tmp_d].u1 = tl; + tr->data[tl].state = ST_VALID; + tr->data[tl] = tr->data[tu]; + tr->data[tu].lo.y = tr->data[tl].hi.y = s.v0.y; + tr->data[tu].lo.x = tr->data[tl].hi.x = s.v0.x; + tr->data[tu].d0 = tl; + tr->data[tu].d1 = 0; + tr->data[tl].u0 = tu; + tr->data[tl].u1 = 0; + + if ((tmp_d = tr->data[tl].d0) > 0 && tr->data[tmp_d].u0 == tu) + tr->data[tmp_d].u0 = tl; + if ((tmp_d = tr->data[tl].d0) > 0 && tr->data[tmp_d].u1 == tu) + tr->data[tmp_d].u1 = tl; + + if ((tmp_d = tr->data[tl].d1) > 0 && tr->data[tmp_d].u0 == tu) + tr->data[tmp_d].u0 = tl; + if ((tmp_d = tr->data[tl].d1) > 0 && tr->data[tmp_d].u1 == tu) + tr->data[tmp_d].u1 = tl; /* Now update the query structure and obtain the sinks for the */ /* two trapezoids */ i1 = newnode(); /* Upper trapezoid sink */ i2 = newnode(); /* Lower trapezoid sink */ - sk = tr[tu].sink; + sk = tr->data[tu].sink; qs[sk].nodetype = T_Y; qs[sk].yval = s.v0; @@ -484,8 +480,8 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) qs[i2].trnum = tl; qs[i2].parent = sk; - tr[tu].sink = i1; - tr[tl].sink = i2; + tr->data[tu].sink = i1; + tr->data[tl].sink = i2; tfirst = tl; } else /* v0 already present */ @@ -502,31 +498,31 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) tu = locate_endpoint(&s.v1, &s.v0, s.root1, seg, qs); tl = newtrap(tr); /* tl is the new lower trapezoid */ - tr[tl].state = ST_VALID; - tr[tl] = tr[tu]; - tr[tu].lo.y = tr[tl].hi.y = s.v1.y; - tr[tu].lo.x = tr[tl].hi.x = s.v1.x; - tr[tu].d0 = tl; - tr[tu].d1 = 0; - tr[tl].u0 = tu; - tr[tl].u1 = 0; - - if ((tmp_d = tr[tl].d0) > 0 && tr[tmp_d].u0 == tu) - tr[tmp_d].u0 = tl; - if ((tmp_d = tr[tl].d0) > 0 && tr[tmp_d].u1 == tu) - tr[tmp_d].u1 = tl; - - if ((tmp_d = tr[tl].d1) > 0 && tr[tmp_d].u0 == tu) - tr[tmp_d].u0 = tl; - if ((tmp_d = tr[tl].d1) > 0 && tr[tmp_d].u1 == tu) - tr[tmp_d].u1 = tl; + tr->data[tl].state = ST_VALID; + tr->data[tl] = tr->data[tu]; + tr->data[tu].lo.y = tr->data[tl].hi.y = s.v1.y; + tr->data[tu].lo.x = tr->data[tl].hi.x = s.v1.x; + tr->data[tu].d0 = tl; + tr->data[tu].d1 = 0; + tr->data[tl].u0 = tu; + tr->data[tl].u1 = 0; + + if ((tmp_d = tr->data[tl].d0) > 0 && tr->data[tmp_d].u0 == tu) + tr->data[tmp_d].u0 = tl; + if ((tmp_d = tr->data[tl].d0) > 0 && tr->data[tmp_d].u1 == tu) + tr->data[tmp_d].u1 = tl; + + if ((tmp_d = tr->data[tl].d1) > 0 && tr->data[tmp_d].u0 == tu) + tr->data[tmp_d].u0 = tl; + if ((tmp_d = tr->data[tl].d1) > 0 && tr->data[tmp_d].u1 == tu) + tr->data[tmp_d].u1 = tl; /* Now update the query structure and obtain the sinks for the */ /* two trapezoids */ i1 = newnode(); /* Upper trapezoid sink */ i2 = newnode(); /* Lower trapezoid sink */ - sk = tr[tu].sink; + sk = tr->data[tu].sink; qs[sk].nodetype = T_Y; qs[sk].yval = s.v1; @@ -542,8 +538,8 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) qs[i2].trnum = tl; qs[i2].parent = sk; - tr[tu].sink = i1; - tr[tl].sink = i2; + tr->data[tu].sink = i1; + tr->data[tl].sink = i2; tlast = tu; } else /* v1 already present */ @@ -558,11 +554,11 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) t = tfirst; /* topmost trapezoid */ - while (t > 0 && _greater_than_equal_to(&tr[t].lo, &tr[tlast].lo)) + while (t > 0 && _greater_than_equal_to(&tr->data[t].lo, &tr->data[tlast].lo)) /* traverse from top to bot */ { int t_sav, tn_sav; - sk = tr[t].sink; + sk = tr->data[t].sink; i1 = newnode(); /* left trapezoid sink */ i2 = newnode(); /* right trapezoid sink */ @@ -577,23 +573,23 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) qs[i2].nodetype = T_SINK; /* right trapezoid (allocate new) */ qs[i2].trnum = tn = newtrap(tr); - tr[tn].state = ST_VALID; + tr->data[tn].state = ST_VALID; qs[i2].parent = sk; if (t == tfirst) tfirstr = tn; - if (_equal_to(&tr[t].lo, &tr[tlast].lo)) + if (_equal_to(&tr->data[t].lo, &tr->data[tlast].lo)) tlastr = tn; - tr[tn] = tr[t]; - tr[t].sink = i1; - tr[tn].sink = i2; + tr->data[tn] = tr->data[t]; + tr->data[t].sink = i1; + tr->data[tn].sink = i2; t_sav = t; tn_sav = tn; /* error */ - if (tr[t].d0 <= 0 && tr[t].d1 <= 0) /* case cannot arise */ + if (tr->data[t].d0 <= 0 && tr->data[t].d1 <= 0) /* case cannot arise */ { fprintf(stderr, "add_segment: error\n"); break; @@ -603,69 +599,69 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) /* two resulting trapezoids t and tn as the upper neighbours of */ /* the sole lower trapezoid */ - else if (tr[t].d0 > 0 && tr[t].d1 <= 0) + else if (tr->data[t].d0 > 0 && tr->data[t].d1 <= 0) { /* Only one trapezoid below */ - if (tr[t].u0 > 0 && tr[t].u1 > 0) + if (tr->data[t].u0 > 0 && tr->data[t].u1 > 0) { /* continuation of a chain from abv. */ - if (tr[t].usave > 0) /* three upper neighbours */ + if (tr->data[t].usave > 0) /* three upper neighbours */ { - if (tr[t].uside == S_LEFT) + if (tr->data[t].uside == S_LEFT) { - tr[tn].u0 = tr[t].u1; - tr[t].u1 = -1; - tr[tn].u1 = tr[t].usave; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = -1; + tr->data[tn].u1 = tr->data[t].usave; - tr[tr[t].u0].d0 = t; - tr[tr[tn].u0].d0 = tn; - tr[tr[tn].u1].d0 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; + tr->data[tr->data[tn].u1].d0 = tn; } else /* intersects in the right */ { - tr[tn].u1 = -1; - tr[tn].u0 = tr[t].u1; - tr[t].u1 = tr[t].u0; - tr[t].u0 = tr[t].usave; - - tr[tr[t].u0].d0 = t; - tr[tr[t].u1].d0 = t; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u1 = -1; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = tr->data[t].u0; + tr->data[t].u0 = tr->data[t].usave; + + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u1].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; } - tr[t].usave = tr[tn].usave = 0; + tr->data[t].usave = tr->data[tn].usave = 0; } else /* No usave.... simple case */ { - tr[tn].u0 = tr[t].u1; - tr[t].u1 = tr[tn].u1 = -1; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = tr->data[tn].u1 = -1; + tr->data[tr->data[tn].u0].d0 = tn; } } else { /* fresh seg. or upward cusp */ - int tmp_u = tr[t].u0; + int tmp_u = tr->data[t].u0; int td0, td1; - if ((td0 = tr[tmp_u].d0) > 0 && (td1 = tr[tmp_u].d1) > 0) + if ((td0 = tr->data[tmp_u].d0) > 0 && (td1 = tr->data[tmp_u].d1) > 0) { /* upward cusp */ - if (tr[td0].rseg > 0 && !is_left_of(tr[td0].rseg, seg, &s.v1)) + if (tr->data[td0].rseg > 0 && !is_left_of(tr->data[td0].rseg, seg, &s.v1)) { - tr[t].u0 = tr[t].u1 = tr[tn].u1 = -1; - tr[tr[tn].u0].d1 = tn; + tr->data[t].u0 = tr->data[t].u1 = tr->data[tn].u1 = -1; + tr->data[tr->data[tn].u0].d1 = tn; } else /* cusp going leftwards */ { - tr[tn].u0 = tr[tn].u1 = tr[t].u1 = -1; - tr[tr[t].u0].d0 = t; + tr->data[tn].u0 = tr->data[tn].u1 = tr->data[t].u1 = -1; + tr->data[tr->data[t].u0].d0 = t; } } else /* fresh segment */ { - tr[tr[t].u0].d0 = t; - tr[tr[t].u0].d1 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u0].d1 = tn; } } - if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && - FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot) + if (FP_EQUAL(tr->data[t].lo.y, tr->data[tlast].lo.y) && + FP_EQUAL(tr->data[t].lo.x, tr->data[tlast].lo.x) && tribot) { /* bottom forms a triangle */ if (is_swapped) @@ -676,102 +672,102 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) if (tmptriseg > 0 && is_left_of(tmptriseg, seg, &s.v0)) { /* L-R downward cusp */ - tr[tr[t].d0].u0 = t; - tr[tn].d0 = tr[tn].d1 = -1; + tr->data[tr->data[t].d0].u0 = t; + tr->data[tn].d0 = tr->data[tn].d1 = -1; } else { /* R-L downward cusp */ - tr[tr[tn].d0].u1 = tn; - tr[t].d0 = tr[t].d1 = -1; + tr->data[tr->data[tn].d0].u1 = tn; + tr->data[t].d0 = tr->data[t].d1 = -1; } } else { - if (tr[tr[t].d0].u0 > 0 && tr[tr[t].d0].u1 > 0) + if (tr->data[tr->data[t].d0].u0 > 0 && tr->data[tr->data[t].d0].u1 > 0) { - if (tr[tr[t].d0].u0 == t) /* passes through LHS */ + if (tr->data[tr->data[t].d0].u0 == t) /* passes through LHS */ { - tr[tr[t].d0].usave = tr[tr[t].d0].u1; - tr[tr[t].d0].uside = S_LEFT; + tr->data[tr->data[t].d0].usave = tr->data[tr->data[t].d0].u1; + tr->data[tr->data[t].d0].uside = S_LEFT; } else { - tr[tr[t].d0].usave = tr[tr[t].d0].u0; - tr[tr[t].d0].uside = S_RIGHT; + tr->data[tr->data[t].d0].usave = tr->data[tr->data[t].d0].u0; + tr->data[tr->data[t].d0].uside = S_RIGHT; } } - tr[tr[t].d0].u0 = t; - tr[tr[t].d0].u1 = tn; + tr->data[tr->data[t].d0].u0 = t; + tr->data[tr->data[t].d0].u1 = tn; } - t = tr[t].d0; + t = tr->data[t].d0; } - else if (tr[t].d0 <= 0 && tr[t].d1 > 0) + else if (tr->data[t].d0 <= 0 && tr->data[t].d1 > 0) { /* Only one trapezoid below */ - if (tr[t].u0 > 0 && tr[t].u1 > 0) + if (tr->data[t].u0 > 0 && tr->data[t].u1 > 0) { /* continuation of a chain from abv. */ - if (tr[t].usave > 0) /* three upper neighbours */ + if (tr->data[t].usave > 0) /* three upper neighbours */ { - if (tr[t].uside == S_LEFT) + if (tr->data[t].uside == S_LEFT) { - tr[tn].u0 = tr[t].u1; - tr[t].u1 = -1; - tr[tn].u1 = tr[t].usave; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = -1; + tr->data[tn].u1 = tr->data[t].usave; - tr[tr[t].u0].d0 = t; - tr[tr[tn].u0].d0 = tn; - tr[tr[tn].u1].d0 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; + tr->data[tr->data[tn].u1].d0 = tn; } else /* intersects in the right */ { - tr[tn].u1 = -1; - tr[tn].u0 = tr[t].u1; - tr[t].u1 = tr[t].u0; - tr[t].u0 = tr[t].usave; - - tr[tr[t].u0].d0 = t; - tr[tr[t].u1].d0 = t; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u1 = -1; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = tr->data[t].u0; + tr->data[t].u0 = tr->data[t].usave; + + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u1].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; } - tr[t].usave = tr[tn].usave = 0; + tr->data[t].usave = tr->data[tn].usave = 0; } else /* No usave.... simple case */ { - tr[tn].u0 = tr[t].u1; - tr[t].u1 = tr[tn].u1 = -1; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = tr->data[tn].u1 = -1; + tr->data[tr->data[tn].u0].d0 = tn; } } else { /* fresh seg. or upward cusp */ - int tmp_u = tr[t].u0; + int tmp_u = tr->data[t].u0; int td0, td1; - if ((td0 = tr[tmp_u].d0) > 0 && (td1 = tr[tmp_u].d1) > 0) + if ((td0 = tr->data[tmp_u].d0) > 0 && (td1 = tr->data[tmp_u].d1) > 0) { /* upward cusp */ - if (tr[td0].rseg > 0 && !is_left_of(tr[td0].rseg, seg, &s.v1)) + if (tr->data[td0].rseg > 0 && !is_left_of(tr->data[td0].rseg, seg, &s.v1)) { - tr[t].u0 = tr[t].u1 = tr[tn].u1 = -1; - tr[tr[tn].u0].d1 = tn; + tr->data[t].u0 = tr->data[t].u1 = tr->data[tn].u1 = -1; + tr->data[tr->data[tn].u0].d1 = tn; } else { - tr[tn].u0 = tr[tn].u1 = tr[t].u1 = -1; - tr[tr[t].u0].d0 = t; + tr->data[tn].u0 = tr->data[tn].u1 = tr->data[t].u1 = -1; + tr->data[tr->data[t].u0].d0 = t; } } else /* fresh segment */ { - tr[tr[t].u0].d0 = t; - tr[tr[t].u0].d1 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u0].d1 = tn; } } - if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && - FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot) + if (FP_EQUAL(tr->data[t].lo.y, tr->data[tlast].lo.y) && + FP_EQUAL(tr->data[t].lo.x, tr->data[tlast].lo.x) && tribot) { /* bottom forms a triangle */ if (is_swapped) @@ -782,36 +778,36 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) if (tmptriseg > 0 && is_left_of(tmptriseg, seg, &s.v0)) { /* L-R downward cusp */ - tr[tr[t].d1].u0 = t; - tr[tn].d0 = tr[tn].d1 = -1; + tr->data[tr->data[t].d1].u0 = t; + tr->data[tn].d0 = tr->data[tn].d1 = -1; } else { /* R-L downward cusp */ - tr[tr[tn].d1].u1 = tn; - tr[t].d0 = tr[t].d1 = -1; + tr->data[tr->data[tn].d1].u1 = tn; + tr->data[t].d0 = tr->data[t].d1 = -1; } } else { - if (tr[tr[t].d1].u0 > 0 && tr[tr[t].d1].u1 > 0) + if (tr->data[tr->data[t].d1].u0 > 0 && tr->data[tr->data[t].d1].u1 > 0) { - if (tr[tr[t].d1].u0 == t) /* passes through LHS */ + if (tr->data[tr->data[t].d1].u0 == t) /* passes through LHS */ { - tr[tr[t].d1].usave = tr[tr[t].d1].u1; - tr[tr[t].d1].uside = S_LEFT; + tr->data[tr->data[t].d1].usave = tr->data[tr->data[t].d1].u1; + tr->data[tr->data[t].d1].uside = S_LEFT; } else { - tr[tr[t].d1].usave = tr[tr[t].d1].u0; - tr[tr[t].d1].uside = S_RIGHT; + tr->data[tr->data[t].d1].usave = tr->data[tr->data[t].d1].u0; + tr->data[tr->data[t].d1].uside = S_RIGHT; } } - tr[tr[t].d1].u0 = t; - tr[tr[t].d1].u1 = tn; + tr->data[tr->data[t].d1].u0 = t; + tr->data[tr->data[t].d1].u1 = tn; } - t = tr[t].d1; + t = tr->data[t].d1; } /* two trapezoids below. Find out which one is intersected by */ @@ -824,20 +820,20 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) int tnext, i_d0, i_d1; i_d0 = i_d1 = FALSE; - if (FP_EQUAL(tr[t].lo.y, s.v0.y)) + if (FP_EQUAL(tr->data[t].lo.y, s.v0.y)) { - if (tr[t].lo.x > s.v0.x) + if (tr->data[t].lo.x > s.v0.x) i_d0 = TRUE; else i_d1 = TRUE; } else { - tmppt.y = y0 = tr[t].lo.y; + tmppt.y = y0 = tr->data[t].lo.y; yt = (y0 - s.v0.y)/(s.v1.y - s.v0.y); tmppt.x = s.v0.x + yt * (s.v1.x - s.v0.x); - if (_less_than(&tmppt, &tr[t].lo)) + if (_less_than(&tmppt, &tr->data[t].lo)) i_d0 = TRUE; else i_d1 = TRUE; @@ -846,118 +842,118 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) /* check continuity from the top so that the lower-neighbour */ /* values are properly filled for the upper trapezoid */ - if (tr[t].u0 > 0 && tr[t].u1 > 0) + if (tr->data[t].u0 > 0 && tr->data[t].u1 > 0) { /* continuation of a chain from abv. */ - if (tr[t].usave > 0) /* three upper neighbours */ + if (tr->data[t].usave > 0) /* three upper neighbours */ { - if (tr[t].uside == S_LEFT) + if (tr->data[t].uside == S_LEFT) { - tr[tn].u0 = tr[t].u1; - tr[t].u1 = -1; - tr[tn].u1 = tr[t].usave; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = -1; + tr->data[tn].u1 = tr->data[t].usave; - tr[tr[t].u0].d0 = t; - tr[tr[tn].u0].d0 = tn; - tr[tr[tn].u1].d0 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; + tr->data[tr->data[tn].u1].d0 = tn; } else /* intersects in the right */ { - tr[tn].u1 = -1; - tr[tn].u0 = tr[t].u1; - tr[t].u1 = tr[t].u0; - tr[t].u0 = tr[t].usave; - - tr[tr[t].u0].d0 = t; - tr[tr[t].u1].d0 = t; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u1 = -1; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[t].u1 = tr->data[t].u0; + tr->data[t].u0 = tr->data[t].usave; + + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u1].d0 = t; + tr->data[tr->data[tn].u0].d0 = tn; } - tr[t].usave = tr[tn].usave = 0; + tr->data[t].usave = tr->data[tn].usave = 0; } else /* No usave.... simple case */ { - tr[tn].u0 = tr[t].u1; - tr[tn].u1 = -1; - tr[t].u1 = -1; - tr[tr[tn].u0].d0 = tn; + tr->data[tn].u0 = tr->data[t].u1; + tr->data[tn].u1 = -1; + tr->data[t].u1 = -1; + tr->data[tr->data[tn].u0].d0 = tn; } } else { /* fresh seg. or upward cusp */ - int tmp_u = tr[t].u0; + int tmp_u = tr->data[t].u0; int td0, td1; - if ((td0 = tr[tmp_u].d0) > 0 && (td1 = tr[tmp_u].d1) > 0) + if ((td0 = tr->data[tmp_u].d0) > 0 && (td1 = tr->data[tmp_u].d1) > 0) { /* upward cusp */ - if (tr[td0].rseg > 0 && !is_left_of(tr[td0].rseg, seg, &s.v1)) + if (tr->data[td0].rseg > 0 && !is_left_of(tr->data[td0].rseg, seg, &s.v1)) { - tr[t].u0 = tr[t].u1 = tr[tn].u1 = -1; - tr[tr[tn].u0].d1 = tn; + tr->data[t].u0 = tr->data[t].u1 = tr->data[tn].u1 = -1; + tr->data[tr->data[tn].u0].d1 = tn; } else { - tr[tn].u0 = tr[tn].u1 = tr[t].u1 = -1; - tr[tr[t].u0].d0 = t; + tr->data[tn].u0 = tr->data[tn].u1 = tr->data[t].u1 = -1; + tr->data[tr->data[t].u0].d0 = t; } } else /* fresh segment */ { - tr[tr[t].u0].d0 = t; - tr[tr[t].u0].d1 = tn; + tr->data[tr->data[t].u0].d0 = t; + tr->data[tr->data[t].u0].d1 = tn; } } - if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && - FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot) + if (FP_EQUAL(tr->data[t].lo.y, tr->data[tlast].lo.y) && + FP_EQUAL(tr->data[t].lo.x, tr->data[tlast].lo.x) && tribot) { /* this case arises only at the lowest trapezoid.. i.e. tlast, if the lower endpoint of the segment is already inserted in the structure */ - tr[tr[t].d0].u0 = t; - tr[tr[t].d0].u1 = -1; - tr[tr[t].d1].u0 = tn; - tr[tr[t].d1].u1 = -1; + tr->data[tr->data[t].d0].u0 = t; + tr->data[tr->data[t].d0].u1 = -1; + tr->data[tr->data[t].d1].u0 = tn; + tr->data[tr->data[t].d1].u1 = -1; - tr[tn].d0 = tr[t].d1; - tr[t].d1 = tr[tn].d1 = -1; + tr->data[tn].d0 = tr->data[t].d1; + tr->data[t].d1 = tr->data[tn].d1 = -1; - tnext = tr[t].d1; + tnext = tr->data[t].d1; } else if (i_d0) /* intersecting d0 */ { - tr[tr[t].d0].u0 = t; - tr[tr[t].d0].u1 = tn; - tr[tr[t].d1].u0 = tn; - tr[tr[t].d1].u1 = -1; + tr->data[tr->data[t].d0].u0 = t; + tr->data[tr->data[t].d0].u1 = tn; + tr->data[tr->data[t].d1].u0 = tn; + tr->data[tr->data[t].d1].u1 = -1; /* new code to determine the bottom neighbours of the */ /* newly partitioned trapezoid */ - tr[t].d1 = -1; + tr->data[t].d1 = -1; - tnext = tr[t].d0; + tnext = tr->data[t].d0; } else /* intersecting d1 */ { - tr[tr[t].d0].u0 = t; - tr[tr[t].d0].u1 = -1; - tr[tr[t].d1].u0 = t; - tr[tr[t].d1].u1 = tn; + tr->data[tr->data[t].d0].u0 = t; + tr->data[tr->data[t].d0].u1 = -1; + tr->data[tr->data[t].d1].u0 = t; + tr->data[tr->data[t].d1].u1 = tn; /* new code to determine the bottom neighbours of the */ /* newly partitioned trapezoid */ - tr[tn].d0 = tr[t].d1; - tr[tn].d1 = -1; + tr->data[tn].d0 = tr->data[t].d1; + tr->data[tn].d1 = -1; - tnext = tr[t].d1; + tnext = tr->data[t].d1; } t = tnext; } - tr[t_sav].rseg = tr[tn_sav].lseg = segnum; + tr->data[t_sav].rseg = tr->data[tn_sav].lseg = segnum; } /* end-while */ /* Now combine those trapezoids which share common segments. We can */ @@ -979,17 +975,16 @@ add_segment (int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) * the segment is inserted into the trapezoidation subsequently */ static void -find_new_roots(int segnum, segment_t* seg, trap_t* tr, qnode_t* qs) -{ +find_new_roots(int segnum, segment_t *seg, traps_t *tr, qnode_t *qs) { segment_t *s = &seg[segnum]; if (s->is_inserted) return; s->root0 = locate_endpoint(&s->v0, &s->v1, s->root0, seg, qs); - s->root0 = tr[s->root0].sink; + s->root0 = tr->data[s->root0].sink; s->root1 = locate_endpoint(&s->v1, &s->v0, s->root1, seg, qs); - s->root1 = tr[s->root1].sink; + s->root1 = tr->data[s->root1].sink; } /* Get log*n for given n */ @@ -1017,19 +1012,17 @@ static int math_N(int n, int h) /* Main routine to perform trapezoidation */ int -construct_trapezoids(int nseg, segment_t* seg, int* permute, int ntraps, - trap_t* tr) -{ +construct_trapezoids(int nseg, segment_t *seg, int *permute, traps_t* tr) { int i; int root, h; int segi = 1; qnode_t* qs; - QSIZE = 2*ntraps; - TRSIZE = ntraps; - qs = gv_calloc(2 * ntraps, sizeof(qnode_t)); + QSIZE = 2 * tr->length; + TRSIZE = tr->length; + qs = gv_calloc(2 * tr->length, sizeof(qnode_t)); q_idx = tr_idx = 1; - memset(tr, 0, ntraps*sizeof(trap_t)); + memset(tr->data, 0, tr->length * sizeof(trap_t)); /* Add the first segment and get the query structure and trapezoid */ /* list initialised */