20 void clear() { _grid.clear(); }
22 void update_grids(std::vector<VIPRA::f3d>
const& oldPositions,
23 std::vector<VIPRA::f3d>
const& newPositions)
26 for ( VIPRA::idx currIdx = 0; currIdx < newPositions.size(); ++currIdx ) {
27 auto& oldGrid = get_grid(oldPositions[currIdx]);
28 auto& newGrid = get_grid(newPositions[currIdx]);
30 if ( &oldGrid == &newGrid )
continue;
32 oldGrid.erase(std::remove(oldGrid.begin(), oldGrid.end(), currIdx), oldGrid.end());
33 newGrid.push_back(currIdx);
37 void for_each_neighbor(
VIPRA::f3d const& pos,
auto&& func)
const
42 for (
int i = -1; i <= 1; ++i ) {
43 for (
int j = -1; j <= 1; ++j ) {
44 if ( out_of_bounds(pos.x + i * _cellSize, pos.y + j * _cellSize) )
continue;
46 auto const& neighbor =
47 get_grid(
VIPRA::f3d{pos.x + i * _cellSize, pos.y + j * _cellSize});
49 for (
auto value : neighbor ) {
56 void initialize(VIPRA::f_pnt cellSize, VIPRA::f_pnt width, VIPRA::f_pnt height,
57 std::vector<VIPRA::f3d>
const& positions,
58 std::vector<data_t>
const& data)
60 assert(cellSize != 0);
65 set_grids(width, height);
66 initialize_grids(positions, data);
70 std::vector<std::vector<data_t>> _grid;
73 VIPRA::f_pnt _cellSize{};
75 void set_grids(VIPRA::f_pnt width, VIPRA::f_pnt height)
77 _rows =
static_cast<size_t>(std::ceil(height / _cellSize));
78 _cols =
static_cast<size_t>(std::ceil(width / _cellSize));
79 _grid.resize(_rows * _cols);
82 void initialize_grids(std::vector<VIPRA::f3d>
const& positions,
83 std::vector<data_t>
const& data)
85 if ( positions.size() != data.size() )
86 throw std::logic_error(
87 "Spatial Map initialized with differing counts of data and "
91 for (
auto& grid : _grid ) {
92 grid = std::vector<data_t>();
96 for ( VIPRA::idx currIdx = 0; currIdx < positions.size(); ++currIdx ) {
97 auto& grid = get_grid(positions[currIdx]);
98 grid.push_back(data[currIdx]);
108 [[nodiscard]] VIPRA_INLINE
auto get_grid(
VIPRA::f3d pos) -> std::vector<VIPRA::idx>&
110 assert(! out_of_bounds(pos));
112 auto gridX =
static_cast<size_t>(pos.x / _cellSize);
113 auto gridY =
static_cast<size_t>(pos.y / _cellSize);
115 return _grid[gridX + gridY * _cols];
124 [[nodiscard]] VIPRA_INLINE
auto get_grid(
VIPRA::f3d pos)
const
125 -> std::vector<VIPRA::idx>
const&
127 assert(! out_of_bounds(pos));
129 return _grid[
static_cast<size_t>(pos.x / _cellSize) +
130 static_cast<size_t>(pos.y / _cellSize) * _cols];
141 [[nodiscard]] VIPRA_INLINE
auto out_of_bounds(VIPRA::f_pnt gridX,
142 VIPRA::f_pnt gridY)
const ->
bool
144 return gridX < 0 || gridX >= _cols * _cellSize || gridY < 0 ||
145 gridY >= _rows * _cellSize;
156 [[nodiscard]] VIPRA_INLINE
auto out_of_bounds(
VIPRA::f3d pos)
const ->
bool
158 return out_of_bounds(pos.x, pos.y);