26 VIPRA::f_pnt distance{std::numeric_limits<VIPRA::f_pnt>::max()};
29 void intialize(
auto const& map, VIPRA::f_pnt gridSize)
39 [[nodiscard]]
auto get_grid(
VIPRA::f3d pos)
const -> GridPoint
const&
44 [[nodiscard]]
auto get_x_count() const ->
size_t {
return _xCount; }
45 [[nodiscard]]
auto get_y_count() const ->
size_t {
return _xCount; }
47 [[nodiscard]]
auto begin() -> std::vector<GridPoint>::iterator {
return _grid.begin(); }
48 [[nodiscard]]
auto end() -> std::vector<GridPoint>::iterator {
return _grid.end(); }
50 void flood_fill(VIPRA::f3d start,
auto const& map)
52 const VIPRA::f3d dimensions = map.get_dimensions();
53 std::queue<VIPRA::f3d> next;
54 VIPRA::f_pnt dist = 0;
56 get_grid(start).distance = 0;
57 next.push(grid_center(start));
59 while ( ! next.empty() ) {
60 VIPRA::f3d currPos = next.front();
63 if ( map.collision(Geometry::Circle{grid_center(currPos), _gridSize}) )
continue;
65 add_neighbors(currPos, start, next, 0);
69 void flood_fill(VIPRA::f3d start,
auto const& map, DensityGrid
const& densityGrid)
71 const VIPRA::f3d dimensions = map.get_dimensions();
72 std::queue<VIPRA::f3d> next;
73 VIPRA::f_pnt dist = 0;
75 get_grid(start).distance = 0;
76 next.push(grid_center(start));
78 while ( ! next.empty() ) {
79 VIPRA::f3d currPos = next.front();
82 if ( map.collision(Geometry::Circle{grid_center(currPos), _gridSize}) )
continue;
84 VIPRA::idx densityGridIndex = densityGrid.get_closest_grid_idx(currPos);
85 int pedCount = densityGrid.get_ped_count_at_idx(densityGridIndex);
86 add_neighbors(currPos, start, next, pedCount);
98 auto gridX =
static_cast<VIPRA::idx
>(std::floor(pos.x / _gridSize));
99 auto gridY =
static_cast<VIPRA::idx
>(std::floor(pos.y / _gridSize));
101 auto const idx = get_index(gridX, gridY, _xCount);
103 if ( out_of_bounds(gridX, gridY) ) {
105 throw std::runtime_error(
"Grid index is out of bounds");
113 auto gridX =
static_cast<VIPRA::idx
>(std::floor(pos.x / _gridSize));
114 auto gridY =
static_cast<VIPRA::idx
>(std::floor(pos.y / _gridSize));
116 return VIPRA::f3d{_gridSize *
static_cast<VIPRA::f_pnt
>(gridX),
117 _gridSize *
static_cast<VIPRA::f_pnt
>(gridY)};
121 VIPRA::size _xCount{};
122 VIPRA::size _yCount{};
123 VIPRA::f_pnt _gridSize{};
125 std::vector<GridPoint> _grid;
132 void set_grid_counts(
auto const& map)
134 const VIPRA::f3d dimensions = map.get_dimensions();
136 assert(dimensions.x > 0 && dimensions.y > 0);
137 assert(_gridSize > 0);
139 _xCount =
static_cast<VIPRA::idx
>(std::ceil(dimensions.x / _gridSize) + 1);
140 _yCount =
static_cast<VIPRA::idx
>(std::ceil(dimensions.y / _gridSize) + 1);
151 [[nodiscard]]
static auto get_index(VIPRA::size gridX, VIPRA::size gridY,
152 VIPRA::size xCount)
noexcept -> VIPRA::idx
154 return gridX + (gridY * xCount);
162 void construct_grid(
auto const& map)
164 set_grid_counts(map);
166 assert(_xCount > 0 && _yCount > 0);
168 _grid = std::vector<GridPoint>(_xCount * _yCount);
171 [[nodiscard]] VIPRA_INLINE
auto out_of_bounds(VIPRA::f_pnt gridX,
172 VIPRA::f_pnt gridY)
const ->
bool
174 return gridX < 0 || gridX >=
static_cast<VIPRA::f_pnt
>(_xCount) * _gridSize ||
175 gridY < 0 || gridY >=
static_cast<VIPRA::f_pnt
>(_yCount) * _gridSize;
178 [[nodiscard]] VIPRA_INLINE
auto out_of_bounds(
size_t gridX,
size_t gridY)
const ->
bool
180 return gridX < 0 || gridX >= _xCount || gridY < 0 || gridY >= _yCount;
183 void add_neighbors(VIPRA::f3d curr, VIPRA::f3d end, std::queue<VIPRA::f3d>& queue,
186 std::array<std::pair<int, int>, 8>
const directions{
187 {{-1, 1}, {0, 1}, {1, 1}, {-1, 0}, {1, 0}, {-1, -1}, {0, -1}, {1, -1}}};
189 auto& currGrid = get_grid(curr);
191 for (
auto [i, j] : directions ) {
192 if ( i == 0 && i == j )
continue;
194 VIPRA::f3d nextPos = VIPRA::f3d{curr.x + i * _gridSize, curr.y + j * _gridSize};
196 if ( out_of_bounds(nextPos.x, nextPos.y) )
continue;
198 auto& grid = get_grid(nextPos);
200 VIPRA::f_pnt dist = currGrid.distance + curr.distance_to_sqrd(nextPos) + weight;
202 if ( grid.distance <= dist )
continue;
204 grid.direction = (curr - nextPos).unit();
206 grid.distance = dist;
208 queue.emplace(nextPos);
214 Grid(
const Grid&) =
default;
215 Grid(Grid&&) noexcept = default;
216 auto operator=(const Grid&) -> Grid& = default;
217 auto operator=(Grid&&) noexcept -> Grid& = default;