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 *)
52 size_t pnlpn, fpnlpi, lpnlpi,
apex;
88 size_t trii, trij, ftrii, ltrii;
95 if (polyp->
pn > 0 && pnls ==
NULL) {
100 if (polyp->
pn > 0 && pnlps ==
NULL) {
101 prerror(
"cannot realloc pnlps");
106 triangles_clear(&
tris);
111 prerror(
"cannot realloc dq.pnls");
120 for (pi = 0, minx = HUGE_VAL, minpi =
SIZE_MAX; pi < polyp->
pn; pi++) {
121 if (minx > polyp->
ps[pi].
x)
122 minx = polyp->
ps[pi].
x, minpi = pi;
124 p2 = polyp->
ps[minpi];
125 p1 = polyp->
ps[minpi == 0 ? polyp->
pn - 1 : minpi - 1];
126 p3 = polyp->
ps[(minpi == polyp->
pn - 1) ? 0 : minpi + 1];
127 if ((p1.
x == p2.
x && p2.
x == p3.
x && p3.
y > p2.
y) ||
129 for (pi = polyp->
pn - 1; polyp->
pn > 0 && pi !=
SIZE_MAX; pi--) {
130 if (pi < polyp->pn - 1
131 && polyp->
ps[pi].
x == polyp->
ps[pi + 1].
x
132 && polyp->
ps[pi].
y == polyp->
ps[pi + 1].
y)
134 pnls[pnll].
pp = &polyp->
ps[pi];
135 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
136 pnlps[pnll] = &pnls[pnll];
140 for (pi = 0; pi < polyp->
pn; pi++) {
141 if (pi > 0 && polyp->
ps[pi].
x == polyp->
ps[pi - 1].
x &&
142 polyp->
ps[pi].
y == polyp->
ps[pi - 1].
y)
144 pnls[pnll].
pp = &polyp->
ps[pi];
145 pnls[pnll].
link = &pnls[pnll % polyp->
pn];
146 pnlps[pnll] = &pnls[pnll];
151#if defined(DEBUG) && DEBUG >= 1
152 fprintf(stderr,
"points\n%" PRISIZE_T "\n", pnll);
153 for (
size_t pnli = 0; pnli < pnll; pnli++)
154 fprintf(stderr,
"%f %f\n", pnls[pnli].pp->x, pnls[pnli].
pp->
y);
165#if defined(DEBUG) && DEBUG >= 2
166 fprintf(stderr,
"triangles\n%" PRISIZE_T "\n", triangles_size(&
tris));
167 for (trii = 0; trii < triangles_size(&
tris); trii++)
168 for (ei = 0; ei < 3; ei++)
169 fprintf(stderr,
"%f %f\n", triangles_get(&
tris, trii).e[ei].pnl0p->pp->x,
170 triangles_get(&
tris, trii).e[ei].pnl0p->pp->y);
174 for (trii = 0; trii < triangles_size(&
tris); trii++)
175 for (trij = trii + 1; trij < triangles_size(&
tris); trij++)
179 for (trii = 0; trii < triangles_size(&
tris); trii++)
182 if (trii == triangles_size(&
tris)) {
183 prerror(
"source point not in any triangle");
190 for (trii = 0; trii < triangles_size(&
tris); trii++)
193 if (trii == triangles_size(&
tris)) {
194 prerror(
"destination point not in any triangle");
204 prerror(
"cannot find triangle path");
212 ops[0] = eps[0],
ops[1] = eps[1];
218 if (ftrii == ltrii) {
225 ops[0] = eps[0],
ops[1] = eps[1];
237 trip = triangles_at(&
tris, trii);
241 for (ei = 0; ei < 3; ei++)
251 pnlp = trip->
e[(ei + 1) % 3].pnl1p;
271 if (splitindex > dq.
apex)
272 dq.
apex = splitindex;
279 if (splitindex < dq.
apex)
280 dq.
apex = splitindex;
284 for (ei = 0; ei < 3; ei++)
291#if defined(DEBUG) && DEBUG >= 1
292 fprintf(stderr,
"polypath");
293 for (pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
294 fprintf(stderr,
" %f %f", pnlp->
pp->
x, pnlp->
pp->
y);
295 fprintf(stderr,
"\n");
300 for (i = 0, pnlp = &epnls[1]; pnlp; pnlp = pnlp->
link)
308 for (i = i - 1, pnlp = &epnls[1]; pnlp; i--, pnlp = pnlp->
link)
321 for (
size_t pnli = 0; pnli < point_count; pnli++)
323 const size_t pnlip1 = (pnli + 1) % point_count;
324 const size_t pnlip2 = (pnli + 2) % point_count;
329 for (pnli = pnlip1; pnli < point_count - 1; pnli++)
334 prerror(
"triangulation failed");
352 if (triangles_try_append(&
tris, trip) != 0) {
353 prerror(
"cannot realloc tris");
365 for (ei = 0; ei < 3; ei++) {
366 for (ej = 0; ej < 3; ej++) {
367 tri1p = triangles_at(&
tris, tri1);
368 tri2p = triangles_at(&
tris, tri2);
382 if (triangles_get(&
tris, trii).
mark)
384 triangles_at(&
tris, trii)->mark = 1;
387 for (ei = 0; ei < 3; ei++)
388 if (triangles_get(&
tris, trii).e[ei].right_index !=
SIZE_MAX &&
391 triangles_at(&
tris, trii)->mark = 0;
418 for (
size_t index = dq->
fpnlpi; index < dq->
apex; index++)
421 for (
size_t index = dq->
lpnlpi; index > dq->
apex; index--)
430 for (ei = 0, sum = 0; ei < 3; ei++)
431 if (
ccw(*triangles_get(&
tris, trii).e[ei].pnl0p->pp,
432 *triangles_get(&
tris, trii).e[ei].pnl1p->pp, *pp) !=
ISCW)
434 return sum == 3 || sum == 0;
441 if (new_ops ==
NULL) {
static void mark(const stk_t *stk, Agnode_t *n)
set a mark on n
#define DEFINE_LIST(name, type)
#define PRISIZE_T
PRIu64 alike for printing size_t
static bool marktripath(size_t, size_t)
static Ppoint_t point_indexer(void *base, size_t index)
static void connecttris(size_t, size_t)
int Pshortestpath(Ppoly_t *polyp, Ppoint_t eps[2], Ppolyline_t *output)
static void splitdq(deque_t *dq, int, size_t)
static int triangulate(pointnlink_t **, size_t)
static int pointintri(size_t, Ppoint_t *)
static void add2dq(deque_t *dq, int, pointnlink_t *)
static int growops(size_t)
static size_t finddqsplit(const deque_t *dq, pointnlink_t *)
static int loadtriangle(pointnlink_t *, pointnlink_t *, pointnlink_t *)
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?