8#include "goals/astar/douglas_peucker.hpp"
9#include "goals/astar/pathing_graph.hpp"
10#include "vipra/geometry/f3d.hpp"
11#include "vipra/types/float.hpp"
12#include "vipra/types/idx.hpp"
14#include "vipra/macros/performance.hpp"
21 VIPRA::f_pnt distanceFromStart;
22 VIPRA::f_pnt distanceWithHeuristic;
24 VIPRA_INLINE
auto operator==(
Node const& other)
const noexcept ->
bool
26 return self == other.self;
29 VIPRA_INLINE
auto operator<(
Node const& other)
const noexcept ->
bool
31 return distanceWithHeuristic > other.distanceWithHeuristic;
35[[nodiscard]]
inline auto astar(
37 VIPRA::f_pnt smoothingEpsilon)
noexcept -> std::optional<std::vector<VIPRA::f3d>>
39 auto const startPos = graph.pos(start);
40 auto const endGridPos = graph.pos(end);
42 std::vector<Node> nodes(graph.node_count());
43 std::vector<Node> openQueue;
44 std::vector<bool> openSet(graph.node_count());
45 std::vector<bool> closedSet(graph.node_count());
47 nodes[start] =
Node{start, start, 0, startPos.distance_to(endGridPos)};
50 openSet[start] =
true;
51 openQueue.push_back(nodes[start]);
53 while ( ! openQueue.empty() ) {
54 curr = openQueue.front();
56 if ( curr.self == end )
break;
58 std::pop_heap(openQueue.begin(), openQueue.end());
61 openSet[curr.self] =
false;
62 closedSet[curr.self] =
true;
64 for ( VIPRA::idx
const neighborIdx : graph.neighbors(curr.self) ) {
65 if ( neighborIdx == std::numeric_limits<VIPRA::idx>::max() )
continue;
66 if ( closedSet[neighborIdx] )
continue;
68 auto const& currPos = graph.pos(curr.self);
69 auto const& neighborPos = graph.pos(neighborIdx);
71 neighborIdx, curr.self,
72 nodes[curr.self].distanceFromStart + currPos.distance_to(neighborPos),
73 nodes[curr.self].distanceFromStart + currPos.distance_to(neighborPos) +
74 neighborPos.distance_to(endGridPos)};
76 if ( ! openSet[neighborIdx] ) {
77 nodes[neighborIdx] = neighbor;
78 openSet[neighborIdx] =
true;
79 openQueue.push_back(neighbor);
80 std::push_heap(openQueue.begin(), openQueue.end());
84 if ( neighbor.distanceFromStart < nodes[neighborIdx].distanceFromStart ) {
85 nodes[neighborIdx] = neighbor;
90 if ( curr.self != end ) {
95 std::vector<VIPRA::f3d> path;
98 path.push_back(endPos);
99 curr = nodes[curr.parent];
103 curr = nodes[curr.parent];
105 if ( curr.parent == start )
break;
107 auto currDif = graph.pos(curr.self) - graph.pos(curr.parent);
108 if ( currDif != dif ) {
109 path.push_back(graph.pos(curr.parent));
114 return VIPRA::douglas_peucker_algo(path, smoothingEpsilon);
Definition pathing_graph.hpp:19
Definition astar_algo.hpp:18