27 fprintf(stderr, "lib/pathplan/%s:%d: %s\n", __FILE__, __LINE__, (msg))
29#define POINTSIZE sizeof(Ppoint_t)
36#define POINTNLINKSIZE sizeof(pointnlink_t)
37#define POINTNLINKPSIZE sizeof(pointnlink_t *)
63static void connecttris(triangles_t *tris,
size_t,
size_t);
64static bool marktripath(triangles_t *tris,
size_t,
size_t);
87 size_t trii, trij, ftrii, ltrii;
94 if (polyp->
pn > 0 && pnls ==
NULL) {
99 if (polyp->
pn > 0 && pnlps ==
NULL) {
100 prerror(
"cannot realloc pnlps");
105 triangles_t tris = {0};
110 prerror(
"cannot realloc dq.pnls");
119 for (pi = 0, minx = HUGE_VAL, minpi =
SIZE_MAX; pi < polyp->
pn; pi++) {
120 if (minx > polyp->
ps[pi].
x)
121 minx = polyp->
ps[pi].
x, minpi = pi;
124 const Ppoint_t p1 = polyp->
ps[minpi == 0 ? polyp->
pn - 1 : minpi - 1];
126 if ((p1.
x == p2.
x && p2.
x == p3.
x && p3.
y > p2.
y) ||
128 for (pi = polyp->
pn - 1; pi !=
SIZE_MAX; pi--) {
129 if (pi < polyp->pn - 1 && polyp->
ps[pi].
x == polyp->
ps[pi + 1].
x &&
130 polyp->
ps[pi].
y == polyp->
ps[pi + 1].
y)
132 pnls[pnll].
pp = &polyp->
ps[pi];
133 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
134 pnlps[pnll] = &pnls[pnll];
138 for (pi = 0; pi < polyp->
pn; pi++) {
139 if (pi > 0 && polyp->
ps[pi].
x == polyp->
ps[pi - 1].
x &&
140 polyp->
ps[pi].
y == polyp->
ps[pi - 1].
y)
142 pnls[pnll].
pp = &polyp->
ps[pi];
143 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
144 pnlps[pnll] = &pnls[pnll];
149#if defined(DEBUG) && DEBUG >= 1
150 fprintf(stderr,
"points\n%" PRISIZE_T "\n", pnll);
151 for (
size_t pnli = 0; pnli < pnll; pnli++)
152 fprintf(stderr,
"%f %f\n", pnls[pnli].pp->x, pnls[pnli].
pp->
y);
164#if defined(DEBUG) && DEBUG >= 2
166 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
167 for (ei = 0; ei < 3; ei++)
168 fprintf(stderr,
"%f %f\n",
LIST_GET(&tris, trii).e[ei].pnl0p->pp->x,
169 LIST_GET(&tris, trii).e[ei].pnl0p->pp->y);
173 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
174 for (trij = trii + 1; trij <
LIST_SIZE(&tris); trij++)
178 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
182 prerror(
"source point not in any triangle");
190 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
194 prerror(
"destination point not in any triangle");
205 prerror(
"cannot find triangle path");
214 ops[0] = eps[0],
ops[1] = eps[1];
220 if (ftrii == ltrii) {
228 ops[0] = eps[0],
ops[1] = eps[1];
244 for (ei = 0; ei < 3; ei++)
255 pnlp = trip->
e[(ei + 1) % 3].pnl1p;
274 if (splitindex > dq.
apex)
275 dq.
apex = splitindex;
282 if (splitindex < dq.
apex)
283 dq.
apex = splitindex;
287 for (ei = 0; ei < 3; ei++)
295#if defined(DEBUG) && DEBUG >= 1
296 fprintf(stderr,
"polypath");
297 for (pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
298 fprintf(stderr,
" %f %f", pnlp->
pp->
x, pnlp->
pp->
y);
299 fprintf(stderr,
"\n");
305 for (i = 0, pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
313 for (i = i - 1, pnlp = &epnls[1]; pnlp; i--, pnlp = pnlp->
link)
324 size_t point_count) {
325 if (point_count > 3) {
326 for (
size_t pnli = 0; pnli < point_count; pnli++) {
327 const size_t pnlip1 = (pnli + 1) % point_count;
328 const size_t pnlip2 = (pnli + 2) % point_count;
333 for (pnli = pnlip1; pnli < point_count - 1; pnli++)
338 prerror(
"triangulation failed");
358 prerror(
"cannot realloc tris");
366static void connecttris(triangles_t *tris,
size_t tri1,
size_t tri2) {
370 for (ei = 0; ei < 3; ei++) {
371 for (ej = 0; ej < 3; ej++) {
384static bool marktripath(triangles_t *tris,
size_t trii,
size_t trij) {
385 assert(tris !=
NULL);
393 for (ei = 0; ei < 3; ei++)
424 for (
size_t index = dq->
fpnlpi; index < dq->
apex; index++)
428 for (
size_t index = dq->
lpnlpi; index > dq->
apex; index--)
438 for (ei = 0, sum = 0; ei < 3; ei++)
442 return sum == 3 || sum == 0;
449 if (new_ops ==
NULL) {
static void mark(const stk_t *stk, Agnode_t *n)
set a mark on n
type-generic dynamically expanding list
#define LIST_AT(list, index)
#define LIST_GET(list, index)
#define LIST_TRY_APPEND(list, item)
static size_t finddqsplit(const deque_t *dq, pointnlink_t *pnlp)
static void splitdq(deque_t *dq, int side, size_t index)
static void add2dq(deque_t *dq, int side, pointnlink_t *pnlp)
static int pointintri(const triangles_t tris, size_t trii, Ppoint_t *pp)
int Pshortestpath(Ppoly_t *polyp, Ppoint_t eps[2], Ppolyline_t *output)
static bool marktripath(triangles_t *tris, size_t trii, size_t trij)
static int loadtriangle(triangles_t *tris, pointnlink_t *pnlap, pointnlink_t *pnlbp, pointnlink_t *pnlcp)
static int triangulate(triangles_t *tris, pointnlink_t **points, size_t point_count)
static int growops(size_t newopn)
static void connecttris(triangles_t *tris, size_t tri1, size_t tri2)
struct pointnlink_t * link
size_t right_index
index into tris of the triangle to the right
int ccw(Ppoint_t p1, Ppoint_t p2, Ppoint_t p3)
are the given points counter-clockwise, clockwise, or co-linear?
bool isdiagonal(size_t i, void *pointp, size_t pointn, indexer_t indexer)
is (i, i + 2) a diagonal?
static Ppoint_t point_indexer(void *base, size_t index)