7
/* utility fn for cut_tile */
8
static void ERmovesegs(ERview_t *D, Tile_t *old, Tile_t *new, Dir_t side)
14
seglist = old->segs[side];
15
for (i = 0; (seg = seglist->list[i]); i++) {
16
if (seg->b[0] == old) seg->b[0] = new;
17
else if (seg->b[1] == old) seg->b[1] = new;
19
ERseglist_append(D,new->segs[side],seg);
20
seglist->list[i] = NIL(Seg_t*);
22
old->segs[side]->size = 0;
25
/* utility fn for cut_tile */
26
static void ERsortsegs(ERview_t *D, Tile_t *old, Tile_t *b0, Tile_t *b1, Dir_t side)
29
Seglist_t *seglist,*s0,*s1;
33
seglist = old->segs[side];
34
s0 = b0->segs[side]; s1 = b1->segs[side];
35
if ((side == north) || (side == south)) c = 0; else c = 1;
36
for (i = 0; (seg = seglist->list[i]); i++) {
37
if (seg->p[1].c[c] <= b0->UR.c[c]) {ERseglist_append(D,s0,seg); nb=b0;}
38
else if (seg->p[0].c[c] >= b1->LL.c[c]) {ERseglist_append(D,s1,seg);nb=b1;}
40
assert(NONDECREASING(seg->p[0].c[c],b0->UR.c[c],seg->p[1].c[c]));
41
if (seg->b[0] != old) ob = seg->b[0]; else ob = seg->b[1];
42
ERseglist_delete(ob->segs[opposite(side)],seg);
43
/*install_new_seg(seg->p[0],b0->UR,seg->kind,b0,side,ob);
44
ERinstall_new_seg(D,b1->LL,seg->p[1],seg->kind,b1,side,ob);*/
46
ERinstall_new_seg(D,seg->p[0],ERcombine(seg->p[0],b0->UR,(ilbool)c),
47
seg->kind,b0,side,ob);
48
ERinstall_new_seg(D,ERcombine(seg->p[1],b1->LL,(ilbool)c),seg->p[1],
49
seg->kind,b1,side,ob);
54
if (seg->b[0] == old) seg->b[0] = nb;
57
seglist->list[i] = NIL(Seg_t*);
63
/* slice a box in two. destroys old box. sub-boxes are installed
64
* in the diagram with the new segment lists. try to re-use old segs.
66
void ERcut_tile(ERview_t *D, Tile_t *b, ilbool horizontal, Pt_t p)
73
p0 = ERmkpoint(x(b->LL),y(p));
74
p1 = ERmkpoint(x(b->UR),y(p));
78
p0 = ERmkpoint(x(p),y(b->LL));
79
p1 = ERmkpoint(x(p),y(b->UR));
82
b0 = ERtile(D,b->LL,p1);
83
b1 = ERtile(D,p0,b->UR);
84
ERinstall_new_seg(D,p0, p1, s_plain, b0, lowside, b1);
85
ERmovesegs(D,b,b0,opposite(lowside));
86
ERmovesegs(D,b,b1,lowside);
87
ERsortsegs(D,b,b0,b1,(lowside+1)%NSIDES);
88
ERsortsegs(D,b,b0,b1,(lowside+3)%NSIDES);
89
ERtileset_delete(D->config,b);
90
ERtileset_append(D,D->config,b0);
91
ERtileset_append(D,D->config,b1);
95
static ilbool tile_in_set(Tile_t *b, Tileset_t *set)
100
for (i = 0; (cb = set->list[i]); i++)
101
if (cb == b) return TRUE;
105
static ilbool seg_in_list(Seg_t *seg, Seglist_t *set)
110
for (i = 0; (cseg = set->list[i]); i++)
111
if (cseg == seg) return TRUE;
116
static void erchecksegs(ERview_t *d)
122
for (i = 0; (b = d->config->list[i]); i++) {
123
for (side = 0; side < NSIDES; side++) {
124
for (j = 0; (seg = b->segs[side]->list[j]); j++) {
125
if (seg->b[0] == b) {
126
assert(seg->b[1] != b);
127
assert(tile_in_set(seg->b[1],d->config));
128
assert(seg_in_list(seg,seg->b[1]->segs[opposite(side)]));
130
else if (seg->b[1] == b) {
131
assert(seg->b[0] != b);
132
assert(tile_in_set(seg->b[0],d->config));
133
assert(seg_in_list(seg,seg->b[0]->segs[opposite(side)]));
141
/* split the configuration by a given line segment */
142
void ERsplit_config(ERview_t *D, Pt_t p, Pt_t q)
144
Tile_t *this_b, *last_b, *prev_b, *next_b;
147
if (pt_eq(p,q)) return;
149
if (y(p) == y(q)) {c = 0; d = 1;} else {c = 1; d = 0;}
150
if (p.c[c] > q.c[c]) {Pt_t tmp; tmp = p; p = q; q = tmp;}
152
this_b = ERlocate(D,p);
153
last_b = ERlocate(D,q);
156
next_b = ERneighbor(this_b, q);
157
/* need nondegenerate intersection */
158
if ((p.c[c] < this_b->UR.c[c]) && (q.c[c] > this_b->LL.c[c])) {
159
if ((this_b->LL.c[d] < p.c[d]) && (p.c[d] < this_b->UR.c[d]))
160
ERcut_tile(D, this_b, (ilbool)d, p);
165
} while ((prev_b != last_b) && (prev_b != this_b));