8 #ifndef OPENLIBRARY_A_START_ROUTER_HPP
9 #define OPENLIBRARY_A_START_ROUTER_HPP
16 #define DEBUG_DISABLE_OUTPUT
17 #include <common/debug.hpp>
29 template<
class T,
class U,
bool>
32 static void insert(T &,
const U &) {}
35 template<
class T,
class U>
38 static void insert(T &container,
const U &element)
40 container.push_front(element);
44 template<
class T,
class U>
45 struct _H<T, U, false>
47 static void insert(T &container,
const U &element)
49 container.push_back(element);
83 typedef unsigned int FlagsT;
85 template<
class Po
intT,
class OpenSetT,
class ClosedSetT, FlagsT flags = 0>
89 AStar(): m_openSet(), m_closedSet() {}
103 template<
class PathT,
class CoordinateT>
104 PathT
route(CoordinateT startPoint, CoordinateT endPoint)
107 std::swap(startPoint, endPoint);
109 PointT firstPoint(startPoint.x, startPoint.y);
110 PointT lastPoint(endPoint.x, endPoint.y);
113 init(&firstPoint, &lastPoint);
116 const bool status = findPath(&lastPoint);
120 path = reconstruct_path<PathT>(&lastPoint);
122 return std::move(path);
126 typedef decltype(PointT::f_score) FScoreT;
127 typedef decltype(PointT::g_score) GScoreT;
130 ClosedSetT m_closedSet;
132 virtual
void init(PointT *startPoint, PointT *endPoint)
134 startPoint->f_score = heuristic_cost_estimate(startPoint, endPoint);
138 m_openSet.insert(startPoint);
142 virtual bool findPath(PointT *endPoint)
146 while (m_openSet.isEmpty() ==
false)
148 ol_debug(DebugLevel::Debug) <<
"\nopen set: " << m_openSet;
149 ol_debug(DebugLevel::Debug) <<
"closed set: " << m_closedSet;
150 PointT *currentPoint = m_openSet.getBest();
152 ol_debug(DebugLevel::Debug) <<
"current point: " << *currentPoint;
154 if ( *currentPoint == *endPoint )
156 ol_debug(DebugLevel::Debug) <<
"\t== end point";
157 endPoint->origin = currentPoint->origin;
158 endPoint->f_score = currentPoint->f_score;
159 endPoint->g_score = currentPoint->g_score;
164 m_closedSet.insert(currentPoint);
166 const std::vector<PointT *> neighbours = get_neighbours(currentPoint);
167 ol_debug(DebugLevel::Debug) <<
"\tneighbours: " << neighbours;
169 for (PointT *neighbour: neighbours)
172 ol_debug(DebugLevel::Debug) <<
"\tprocessing neigbhbour " << *neighbour;
175 if (m_closedSet.exists(neighbour))
176 ol_debug(DebugLevel::Debug) <<
"\t\tin closed set";
179 const GScoreT neighbour_g_score = currentPoint->g_score + distance(currentPoint, neighbour);
181 static PointT dummy(0 ,0);
182 PointT *existing = &dummy;
185 if (m_openSet.exists(neighbour, existing) ==
false || neighbour_g_score < existing->g_score)
187 if (existing != &dummy)
189 ol_debug(DebugLevel::Debug) <<
"\t\tbetter than point already existing in open set. Updating";
190 existing->origin = neighbour->origin;
191 existing->g_score = neighbour_g_score;
194 existing->f_score = heuristic_cost_estimate(existing, endPoint);
198 ol_debug(DebugLevel::Debug) <<
"\t\tnot in open set. Adding";
199 neighbour->g_score = neighbour_g_score;
200 neighbour->f_score = heuristic_cost_estimate(neighbour, endPoint);
204 m_openSet.insert(neighbour);
209 ol_debug(DebugLevel::Debug) <<
"\t\talready in open set";
220 virtual FScoreT heuristic_cost_estimate(
const PointT *p1,
const PointT *p2)
const = 0;
221 virtual std::vector<PointT *> get_neighbours(PointT *p) = 0;
223 template<
class PathT>
224 PathT reconstruct_path(PointT *last)
226 assert(last->origin !=
nullptr);
232 _H<PathT, PointT, Container<PathT>::prependable>::insert(result, *p), p = p->origin;
234 return std::move(result);
237 long double distance(
const PointT *p1,
const PointT *p2)
const
239 const auto pow2 = [](
long double x) ->
long double {
return x * x; };
240 const long double dist = sqrt( pow2(p1->x - p2->x) + pow2(p1->y - p2->y) );
PathT route(CoordinateT startPoint, CoordinateT endPoint)
function for finding path
Definition: base.hpp:104
Definition: traits.hpp:24