Polyanya - Compromise-free Pathfinding on a Navigation Mesh
Implementation of Polyanya in Rust! Polyanya is a any-angle path planning algorithm.
A WASM demo made with Bevy is available here.
Usage
use Vec2;
use *;
The code above will build the following mesh, with polygons marked in green, and vertices in red:

Original Work
Check the cpp implementation.
index;micro;successor_calls;generated;pushed;popped;pruned_post_pop;length;gridcost
0;4960.92;6974;4368;4313;3823;21;1123.222637572437;1199.73
This crate seems to generate a few more nodes, but tends to be faster than the cpp implementation. There are a few known cases to still improve it:
- collinear optimisation, when a search node root and interval are all on a same line
- triangle optimisation, when searching in a triangle polygon
- when an intersection is very close to a vertex, it sometimes generates an extra slim search node
- searching start and end nodes is costlier
Compiling this crate with feature stats will output almost the same level of information as the default cpp implementation output.
index;micros;successor_calls;generated;pushed;popped;pruned_post_pop;length
0;2990.083;6983;7748;4314;3828;21;1123.2228
The verbose feature will give the same output as setting verbose to 1.
pushing: root=(993, 290); left=(989, 303); right=(1001, 288); f=1020.21, g=0.00
pushing: root=(993, 290); left=(984, 301); right=(988, 303); f=1016.98, g=0.00
pushing: root=(993, 290); left=(982, 300); right=(984, 301); f=1016.06, g=0.00
pushing: root=(993, 290); left=(994, 285); right=(981, 299); f=1014.84, g=0.00
popped off: root=(993, 290); left=(994, 285); right=(981, 299); f=1014.84, g=0.00
intermediate: root=(993, 290); left=(988, 282); right=(981, 299); f=1014.84, g=0.00
pushing: root=(993, 290); left=(977, 299); right=(980, 299); f=1015.14, g=0.00
pushing: root=(993, 290); left=(984, 280); right=(976, 297); f=1014.84, g=0.00
popped off: root=(993, 290); left=(984, 280); right=(976, 297); f=1014.84, g=0.00
pushing: root=(993, 290); left=(973, 296); right=(976, 297); f=1014.84, g=0.00
pushing: root=(993, 290); left=(970, 295); right=(973, 296); f=1014.86, g=0.00
pushing: root=(993, 290); left=(967, 294); right=(970, 295); f=1015.01, g=0.00
pushing: root=(993, 290); left=(965, 293); right=(967, 294); f=1015.28, g=0.00
pushing: root=(993, 290); left=(977, 276); right=(965, 293); f=1015.58, g=0.00
pushing: root=(993, 290); left=(983, 279); right=(979, 277); f=1023.95, g=0.00
popped off: root=(993, 290); left=(973, 296); right=(976, 297); f=1014.84, g=0.00
popped off: root=(993, 290); left=(970, 295); right=(973, 296); f=1014.86, g=0.00
popped off: root=(993, 290); left=(967, 294); right=(970, 295); f=1015.01, g=0.00
popped off: root=(993, 290); left=(977, 299); right=(980, 299); f=1015.14, g=0.00
popped off: root=(993, 290); left=(965, 293); right=(967, 294); f=1015.28, g=0.00
popped off: root=(993, 290); left=(977, 276); right=(965, 293); f=1015.58, g=0.00
pushing: root=(993, 290); left=(963, 292); right=(965, 293); f=1015.58, g=0.00
pushing: root=(993, 290); left=(961, 291); right=(963, 292); f=1015.94, g=0.00
pushing: root=(993, 290); left=(971, 273); right=(959, 289); f=1017.13, g=0.00
...
The mesh files used in tests are coming from the cpp implementation and are available under MIT license.