25 fprintf (stderr, "lib/pathplan/%s:%d: %s\n", __FILE__, __LINE__, (msg))
27#define POINTSIZE sizeof (Ppoint_t)
34#define POINTNLINKSIZE sizeof (pointnlink_t)
35#define POINTNLINKPSIZE sizeof (pointnlink_t *)
85 size_t trii, trij, ftrii, ltrii;
92 if (polyp->
pn > 0 && pnls ==
NULL) {
97 if (polyp->
pn > 0 && pnlps ==
NULL) {
98 prerror(
"cannot realloc pnlps");
108 prerror(
"cannot realloc dq.pnls");
117 for (pi = 0, minx = HUGE_VAL, minpi =
SIZE_MAX; pi < polyp->
pn; pi++) {
118 if (minx > polyp->
ps[pi].
x)
119 minx = polyp->
ps[pi].
x, minpi = pi;
122 const Ppoint_t p1 = polyp->
ps[minpi == 0 ? polyp->
pn - 1 : minpi - 1];
124 if ((p1.
x == p2.
x && p2.
x == p3.
x && p3.
y > p2.
y) ||
126 for (pi = polyp->
pn - 1; pi !=
SIZE_MAX; pi--) {
127 if (pi < polyp->pn - 1
128 && polyp->
ps[pi].
x == polyp->
ps[pi + 1].
x
129 && polyp->
ps[pi].
y == polyp->
ps[pi + 1].
y)
131 pnls[pnll].
pp = &polyp->
ps[pi];
132 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
133 pnlps[pnll] = &pnls[pnll];
137 for (pi = 0; pi < polyp->
pn; pi++) {
138 if (pi > 0 && polyp->
ps[pi].
x == polyp->
ps[pi - 1].
x &&
139 polyp->
ps[pi].
y == polyp->
ps[pi - 1].
y)
141 pnls[pnll].
pp = &polyp->
ps[pi];
142 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
143 pnlps[pnll] = &pnls[pnll];
148#if defined(DEBUG) && DEBUG >= 1
149 fprintf(stderr,
"points\n%" PRISIZE_T "\n", pnll);
150 for (
size_t pnli = 0; pnli < pnll; pnli++)
151 fprintf(stderr,
"%f %f\n", pnls[pnli].pp->x, pnls[pnli].
pp->
y);
162#if defined(DEBUG) && DEBUG >= 2
164 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
165 for (ei = 0; ei < 3; ei++)
166 fprintf(stderr,
"%f %f\n",
LIST_GET(&tris, trii).e[ei].pnl0p->pp->x,
167 LIST_GET(&tris, trii).e[ei].pnl0p->pp->y);
171 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
172 for (trij = trii + 1; trij <
LIST_SIZE(&tris); trij++)
176 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
180 prerror(
"source point not in any triangle");
187 for (trii = 0; trii <
LIST_SIZE(&tris); trii++)
191 prerror(
"destination point not in any triangle");
201 prerror(
"cannot find triangle path");
209 ops[0] = eps[0],
ops[1] = eps[1];
215 if (ftrii == ltrii) {
222 ops[0] = eps[0],
ops[1] = eps[1];
238 for (ei = 0; ei < 3; ei++)
248 pnlp = trip->
e[(ei + 1) % 3].pnl1p;
268 if (splitindex > dq.
apex)
269 dq.
apex = splitindex;
276 if (splitindex < dq.
apex)
277 dq.
apex = splitindex;
281 for (ei = 0; ei < 3; ei++)
288#if defined(DEBUG) && DEBUG >= 1
289 fprintf(stderr,
"polypath");
290 for (pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
291 fprintf(stderr,
" %f %f", pnlp->
pp->
x, pnlp->
pp->
y);
292 fprintf(stderr,
"\n");
297 for (i = 0, pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
305 for (i = i - 1, pnlp = &epnls[1]; pnlp; i--, pnlp = pnlp->
link)
318 for (
size_t pnli = 0; pnli < point_count; pnli++)
320 const size_t pnlip1 = (pnli + 1) % point_count;
321 const size_t pnlip2 = (pnli + 2) % point_count;
326 for (pnli = pnlip1; pnli < point_count - 1; pnli++)
331 prerror(
"triangulation failed");
350 prerror(
"cannot realloc tris");
362 for (ei = 0; ei < 3; ei++) {
363 for (ej = 0; ej < 3; ej++) {
381 LIST_AT(&tris, trii)->mark = 1;
384 for (ei = 0; ei < 3; ei++)
388 LIST_AT(&tris, trii)->mark = 0;
415 for (
size_t index = dq->
fpnlpi; index < dq->
apex; index++)
418 for (
size_t index = dq->
lpnlpi; index > dq->
apex; index--)
427 for (ei = 0, sum = 0; ei < 3; ei++)
431 return sum == 3 || sum == 0;
438 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 int triangulate(pointnlink_t **points, size_t point_count)
static bool marktripath(size_t trii, size_t trij)
static void connecttris(size_t tri1, size_t tri2)
static int pointintri(size_t trii, Ppoint_t *pp)
static void splitdq(deque_t *dq, int side, size_t index)
static void add2dq(deque_t *dq, int side, pointnlink_t *pnlp)
int Pshortestpath(Ppoly_t *polyp, Ppoint_t eps[2], Ppolyline_t *output)
static int growops(size_t newopn)
static int loadtriangle(pointnlink_t *pnlap, pointnlink_t *pnlbp, pointnlink_t *pnlcp)
struct pointnlink_t * link
size_t right_index
index into tris of the triangle to the right
bool isdiagonal(size_t i, size_t ip2, void *pointp, size_t pointn, indexer_t indexer)
is (i, i + 2) a diagonal?
int ccw(Ppoint_t p1, Ppoint_t p2, Ppoint_t p3)
are the given points counter-clockwise, clockwise, or co-linear?
static Ppoint_t point_indexer(void *base, size_t index)