16namespace environment::field::aggregation
31[[nodiscard]]
inline float RoundDown(
double v)
33 const float f =
static_cast<float>(v);
34 return static_cast<double>(f) > v ? std::nextafter(f, -std::numeric_limits<float>::infinity()) : f;
38[[nodiscard]]
inline float RoundUp(
double v)
40 const float f =
static_cast<float>(v);
41 return static_cast<double>(f) < v ? std::nextafter(f, std::numeric_limits<float>::infinity()) : f;
45[[nodiscard]]
inline bool Overlaps(
const Box& a,
const Box& b)
47 return a.xMax >= b.xMin && a.xMin <= b.xMax && a.yMax >= b.yMin && a.yMin <= b.yMax && a.zMax >= b.zMin && a.zMin <= b.zMax;
73 HashGrid(std::span<const Box> boxes,
double cellSize);
76 [[nodiscard]]
double CellSize()
const {
return m_cellSize; }
79 [[nodiscard]] std::size_t
CellCount()
const {
return static_cast<std::size_t
>(m_nx) *
static_cast<std::size_t
>(m_ny); }
85 template <
class Visitor>
88 if (m_entries.empty()) {
91 const int ix0 = CellX(query.xMin);
92 const int ix1 = CellX(query.xMax);
93 const int iy0 = CellY(query.yMin);
94 const int iy1 = CellY(query.yMax);
95 for (
int iy = iy0; iy <= iy1; ++iy) {
96 for (
int ix = ix0; ix <= ix1; ++ix) {
97 const std::size_t cell =
static_cast<std::size_t
>(iy) *
static_cast<std::size_t
>(m_nx) +
static_cast<std::size_t
>(ix);
98 for (std::uint32_t k = m_cellStart[cell]; k < m_cellStart[cell + 1]; ++k) {
99 const Entry& e = m_entries[k];
101 if (std::max(e.ix0, ix0) != ix || std::max(e.iy0, iy0) != iy) {
104 if (Overlaps(e.box, query)) {
118 std::uint32_t
id = 0;
119 std::int32_t ix0 = 0;
120 std::int32_t iy0 = 0;
124 [[nodiscard]]
int CellX(
double x)
const {
return CellIndex(x, m_originX, m_nx); }
125 [[nodiscard]]
int CellY(
double y)
const {
return CellIndex(y, m_originY, m_ny); }
126 [[nodiscard]]
int CellIndex(
double v,
double origin,
int count)
const
128 const double cell = std::floor((v - origin) * m_inverseCell);
129 return static_cast<int>(std::clamp(cell, 0.0,
static_cast<double>(count - 1)));
132 double m_cellSize = 1.0;
133 double m_inverseCell = 1.0;
134 double m_originX = 0.0;
135 double m_originY = 0.0;
138 std::vector<std::uint32_t> m_cellStart;
139 std::vector<Entry> m_entries;
HashGrid(std::span< const Box > boxes, double cellSize)
HashGrid()=default
An empty grid; every query reports nothing.
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).
void ForEachCandidate(const Box &query, Visitor &&visit) const
Definition HashGrid.h:86
double CellSize() const
The cell edge in use [m].
Definition HashGrid.h:76
static constexpr std::size_t kMaxCells
The largest number of cells; a larger domain gets larger cells.
Definition HashGrid.h:62
std::size_t CellCount() const
The number of cells.
Definition HashGrid.h:79
An axis-aligned box, NED [m]. Closed: a box that only touches another one overlaps it.
Definition HashGrid.h:21