mirror of
https://bjh21.me.uk/bedstead/.git
synced 2026-07-09 21:43:06 -04:00
Further cleanup of skeleton paths.
The cleanup itself is good, but emit_paths() will need enhancement. At the moment, it assumes that all paths are closed, so it doesn't matter where on a path it starts emitting it. With an open path, though, it's important to emit it starting at one end, so there will have to be a mechanism for distinguishing open from closed paths and behaving accordingly.
This commit is contained in:
parent
563205261f
commit
c56e10dc09
53
bedstead.c
53
bedstead.c
@ -1898,10 +1898,34 @@ dochar(char const data[YSIZE], unsigned flags)
|
||||
emit_path();
|
||||
}
|
||||
|
||||
static void
|
||||
reverse_path(point *a)
|
||||
{
|
||||
point *tmp;
|
||||
|
||||
while (a->prev != NULL)
|
||||
a = a->prev;
|
||||
while (a != NULL) {
|
||||
tmp = a->next;
|
||||
a->next = a->prev;
|
||||
a->prev = tmp;
|
||||
a = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Join together two points each at the end of a path */
|
||||
static void
|
||||
join_ends(point *a, point *b)
|
||||
{
|
||||
point *tmp;
|
||||
|
||||
if (a->prev == NULL && b->next == NULL) {
|
||||
tmp = a; a = b; b = tmp;
|
||||
}
|
||||
if (a->prev == NULL)
|
||||
reverse_path(a);
|
||||
if (b->next == NULL)
|
||||
reverse_path(b);
|
||||
assert(a->next == NULL);
|
||||
assert(a->prev != NULL);
|
||||
assert(b->prev == NULL);
|
||||
@ -1910,7 +1934,7 @@ join_ends(point *a, point *b)
|
||||
a->next = b;
|
||||
b->prev = a;
|
||||
fix_identical(a); /* Will delete a */
|
||||
fix_collinear(b); /* Will delete b */
|
||||
fix_collinear(b); /* Might delete b */
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1919,23 +1943,44 @@ point_endp(point *p)
|
||||
return p->next == NULL || p->prev == NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
point_deadp(point *p)
|
||||
{
|
||||
return p->next == NULL && p->prev == NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clean_skeleton()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* Pass 1: join collinear connected segments */
|
||||
for (i = 0; i < nextpoint; i++) {
|
||||
if (points[i].prev == NULL && points[i].next == NULL)
|
||||
if (point_deadp(&points[i]))
|
||||
continue;
|
||||
for (j = 0; j < nextpoint; j++) {
|
||||
if (points[j].prev == NULL && points[j].next == NULL)
|
||||
if (point_deadp(&points[j]))
|
||||
continue;
|
||||
if (vec_eqp(points[i].v, points[j].v) &&
|
||||
points[i].next == NULL && points[j].prev == NULL &&
|
||||
vec_inline3(points[i].prev->v, points[i].v,
|
||||
points[j].next->v))
|
||||
join_ends(&points[i], &points[j]);
|
||||
if (points[i].prev == NULL && points[i].next == NULL)
|
||||
if (point_deadp(&points[i]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Pass 2: join any connected segments */
|
||||
for (i = 0; i < nextpoint; i++) {
|
||||
if (point_deadp(&points[i]))
|
||||
continue;
|
||||
for (j = i+1; j < nextpoint; j++) {
|
||||
if (point_deadp(&points[j]))
|
||||
continue;
|
||||
if (vec_eqp(points[i].v, points[j].v) &&
|
||||
point_endp(&points[i]) && point_endp(&points[j]))
|
||||
join_ends(&points[i], &points[j]);
|
||||
if (point_deadp(&points[i]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user