19namespace environment::field::aggregation
23[[nodiscard]]
double MedianLongerSide(std::span<const Box> boxes);
59 TiledGrid(
double xMin,
double xMax,
double yMin,
double yMax,
double cellSize);
62 [[nodiscard]]
bool HasExtent()
const {
return m_nx > 0; }
65 [[nodiscard]]
double CellSize()
const {
return m_cellSize; }
68 [[nodiscard]] std::size_t
CellCount()
const {
return static_cast<std::size_t
>(m_nx) *
static_cast<std::size_t
>(m_ny); }
71 [[nodiscard]] std::size_t
TileCount()
const {
return m_tiles.size(); }
76 std::size_t shared = 0;
77 for (std::size_t t = 0; t < std::min(m_tiles.size(), other.m_tiles.size()); ++t) {
78 shared += m_tiles[t] !=
nullptr && m_tiles[t] == other.m_tiles[t] ? 1 : 0;
86 return static_cast<std::size_t
>(std::count_if(m_tiles.begin(), m_tiles.end(), [](
const auto& tile) { return tile != nullptr; }));
90 [[nodiscard]] std::size_t
OverflowCount()
const {
return m_overflow ? m_overflow->size() : 0; }
95 return box.xMin >= m_extent.xMin && box.xMax <= m_extent.xMax && box.yMin >= m_extent.yMin && box.yMax <= m_extent.yMax;
103 [[nodiscard]]
TiledGrid With(std::span<const Item> removed, std::span<const Item> added)
const;
113 template<
class Visitor>
117 const int ix0 = CellX(query.xMin);
118 const int ix1 = CellX(query.xMax);
119 const int iy0 = CellY(query.yMin);
120 const int iy1 = CellY(query.yMax);
121 for (
int iy = iy0; iy <= iy1; ++iy) {
122 for (
int ix = ix0; ix <= ix1; ++ix) {
123 const Tile* tile = m_tiles[TileIndex(ix, iy)].get();
124 if (tile ==
nullptr) {
127 const std::size_t local = LocalCell(ix, iy);
128 for (std::uint32_t k = tile->start[local]; k < tile->start[local + 1]; ++k) {
129 const Entry& e = tile->entries[k];
131 if (std::max(e.ix0, ix0) != ix || std::max(e.iy0, iy0) != iy) {
134 if (Overlaps(e.box, query)) {
142 for (
const Entry& e : *m_overflow) {
143 if (Overlaps(e.box, query)) {
156 std::uint32_t
id = 0;
157 std::int32_t ix0 = 0;
158 std::int32_t iy0 = 0;
165 std::array<std::uint32_t, kTileCells + 1> start {};
166 std::vector<Entry> entries;
172 std::size_t tile = 0;
173 std::uint32_t local = 0;
177 [[nodiscard]]
int CellX(
double x)
const {
return CellIndex(x, m_originX, m_nx); }
178 [[nodiscard]]
int CellY(
double y)
const {
return CellIndex(y, m_originY, m_ny); }
179 [[nodiscard]]
int CellIndex(
double v,
double origin,
int count)
const
181 const double cell = std::floor((v - origin) * m_inverseCell);
182 return static_cast<int>(std::clamp(cell, 0.0,
static_cast<double>(count - 1)));
184 [[nodiscard]] std::size_t TileIndex(
int ix,
int iy)
const
186 return static_cast<std::size_t
>(iy /
kTileSide) *
static_cast<std::size_t
>(m_tilesX) +
static_cast<std::size_t
>(ix /
kTileSide);
188 [[nodiscard]]
static std::size_t LocalCell(
int ix,
int iy)
194 void Place(
const Item& item, std::vector<Placed>& out)
const;
196 double m_cellSize = 1.0;
197 double m_inverseCell = 1.0;
198 double m_originX = 0.0;
199 double m_originY = 0.0;
204 std::vector<std::shared_ptr<const Tile>> m_tiles;
205 std::shared_ptr<const std::vector<Entry>> m_overflow;
Definition TiledGrid.h:36
bool Inside(const Box &box) const
True when the box is inside the extent (so it goes into the cells, not the overflow list).
Definition TiledGrid.h:93
TiledGrid With(std::span< const Item > removed, std::span< const Item > added) const
std::size_t CellCount() const
The number of cells.
Definition TiledGrid.h:68
static constexpr int kTileCells
Cells per tile.
Definition TiledGrid.h:41
TiledGrid()=default
An empty grid with no extent; With() must not be called on it.
double CellSize() const
The cell edge in use [m].
Definition TiledGrid.h:65
bool HasExtent() const
True when the grid has an extent (was made with the extent constructor).
Definition TiledGrid.h:62
std::size_t OverflowCount() const
The number of boxes in the overflow list.
Definition TiledGrid.h:90
std::size_t TileCount() const
The number of tiles (with or without entries).
Definition TiledGrid.h:71
void ForEachCandidate(const Box &query, Visitor &&visit) const
Definition TiledGrid.h:114
static constexpr int kTileSide
Cells per tile side.
Definition TiledGrid.h:39
TiledGrid(double xMin, double xMax, double yMin, double yMax, double cellSize)
std::size_t FilledTileCount() const
The number of tiles with entries.
Definition TiledGrid.h:84
std::size_t SharedTileCount(const TiledGrid &other) const
Test hook: the number of tiles with entries that this grid shares (same object) with other.
Definition TiledGrid.h:74
void Candidates(const Box &query, std::vector< std::uint32_t > &out) const
Appends the ids of the boxes that overlap the query box to out (cleared first).
TiledGrid Cleared() const
A grid with the same geometry and no boxes.
An axis-aligned box, NED [m]. Closed: a box that only touches another one overlaps it.
Definition HashGrid.h:21
One box with its id (slot), for With().
Definition TiledGrid.h:45