9#include <unordered_map>
68template<u
int8_t Dim,
typename Component>
72 using Point = std::array<Component, Dim>;
81 for (uint8_t d = 0; d < Dim; ++d)
85 size_t size()
const {
return n; }
89 for (uint8_t d = 0; d < Dim; ++d)
96 for (uint8_t d = 0; d < Dim; ++d)
97 point[d] =
begin(d)[i];
103 for (uint8_t d = 0; d < Dim; ++d)
104 begin(d)[i] = point[d];
109 const Component *
begin(uint8_t d)
const {
return coords.get() + d *
n; }
110 const Component *
end(uint8_t d)
const {
return begin(d) +
n; }
134 for (uint8_t d = 0; d < Dim; ++d) {
135 for (
Idx i = 0; i < n; ++i) {
155 const auto mid =
begin + left_n;
158 for (
auto it =
begin; it != mid; ++it)
166 for (uint8_t d = 0; d < Dim; ++d) {
176 *(right_ptr++) = *it;
182 for (
auto it =
begin; it != mid; ++it)
183 markers[*it] =
false;
185 return SplitResult{std::move(left), std::move(right), *mid};
197template<u
int8_t Dim,
class Component>
207 points.setPoint(0, point);
214 for (uint8_t d = 0; d < Dim; ++d) {
215 const auto coord =
points.begin(d);
217 return coord[i] < coord[j];
226 const auto n =
points.size();
228 for (uint8_t d = 0; d < Dim; ++d) {
231 const auto coord =
points.begin(d);
232 auto a_ptr = a.
indices.begin(d);
233 auto b_ptr = b.
indices.begin(d);
234 auto dst_ptr =
indices.begin(d);
236 const auto i = *a_ptr;
237 const auto j = *b_ptr + a.
size();
238 if (coord[i] <= coord[j]) {
246 while (a_ptr != a.
indices.end(d))
247 *(dst_ptr++) = *(a_ptr++);
248 while (b_ptr != b.
indices.end(d))
249 *(dst_ptr++) = a.
size() + *(b_ptr++);
264template<u
int8_t Dim,
class Component,
class Id>
268 using Point = std::array<Component, Dim>;
281 ,
ids(std::make_unique<Id[]>(1))
282 ,
tree(std::make_unique<
Idx[]>(1))
290 KdTree(
size_t n, Id
const *
ids, std::array<Component const *, Dim> pts)
292 ,
ids(std::make_unique<Id[]>(n))
293 ,
tree(std::make_unique<
Idx[]>(n))
296 std::copy(
ids,
ids + n, this->ids.get());
304 tree = std::make_unique<Idx[]>(
cap());
305 ids = std::make_unique<Id[]>(
cap());
306 std::copy(a.
ids.get(), a.
ids.get() + a.
cap(),
ids.get());
330 void foreach(F cb)
const
332 for (
Idx i = 0; i <
cap(); ++i) {
334 cb(i,
items.points.getPoint(i),
ids[i]);
348 const auto next_axis = (axis + 1) % Dim;
349 if (!
split.left.empty())
350 init(2 * root + 1, next_axis,
split.left);
351 if (!
split.right.empty())
352 init(2 * root + 2, next_axis,
split.right);
363 const auto ptid =
tree[root];
364 const auto coord =
items.points.begin(
split)[ptid];
365 const auto leftChild = 2*root + 1;
366 const auto rightChild = 2*root + 2;
367 const auto nextSplit = (
split + 1) % Dim;
368 if (min[
split] > coord) {
369 rangeQuery(rightChild, nextSplit, min, max, cb);
370 }
else if (max[
split] < coord) {
371 rangeQuery(leftChild, nextSplit, min, max, cb);
373 rangeQuery(rightChild, nextSplit, min, max, cb);
374 rangeQuery(leftChild, nextSplit, min, max, cb);
377 const auto point =
items.points.getPoint(ptid);
378 for (uint8_t d = 0; d < Dim; ++d)
379 if (point[d] < min[d] || point[d] > max[d])
381 cb(point,
ids[ptid]);
385 std::unique_ptr<Id[]>
ids;
390template<u
int8_t Dim,
class Component,
class Id>
398 void insert(
const std::array<Component, Dim> &point, Id
id)
400 Tree tree(point,
id);
401 for (uint8_t tree_idx = 0;; ++tree_idx) {
402 if (tree_idx ==
trees.size()) {
403 trees.push_back(std::move(tree));
408 if (
trees[tree_idx].cap() == 0) {
409 trees[tree_idx] = std::move(tree);
424 const auto &entry = node.mapped();
425 trees.at(entry.tree_idx).remove(entry.in_tree);
442 for (
const auto &tree :
trees)
443 tree.rangeQuery(min, max, cb);
455 trees[tree_idx].foreach([&](
Idx in_tree_idx,
auto _, Id
id) {
471 const auto live_ids = std::make_unique<Id[]>(
n_entries);
474 for (
const auto &tree :
trees) {
475 tree.foreach([&](
Idx _,
auto point, Id
id) {
486 auto id_ptr = live_ids.get();
487 std::array<Component const *, Dim> point_ptrs;
489 for (uint8_t d = 0; d < Dim; ++d)
490 point_ptrs[d] = live_points.
begin(d);
491 for (uint8_t tree_idx = 0; tree_idx <
trees.size() - 1; ++tree_idx, n *= 2) {
495 if (
trees[tree_idx+1].cap() > 0) {
496 tree = std::move(
Tree(n, id_ptr, point_ptrs));
498 for (uint8_t d = 0; d < Dim; ++d)
501 trees[tree_idx] = std::move(tree);
Definition k_d_tree.h:392
void updateDelEntries(uint8_t tree_idx)
Definition k_d_tree.h:453
void rangeQuery(const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:439
std::vector< Tree > trees
Definition k_d_tree.h:508
void remove(Id id)
Definition k_d_tree.h:419
std::unordered_map< Id, DelEntry > del_entries
Definition k_d_tree.h:513
size_t n_entries
Definition k_d_tree.h:514
typename Tree::Point Point
Definition k_d_tree.h:396
KdTree< Dim, Component, Id > Tree
Definition k_d_tree.h:393
size_t size() const
Definition k_d_tree.h:446
void update(const Point &newPos, Id id)
Definition k_d_tree.h:432
size_t deleted
Definition k_d_tree.h:515
void insert(const std::array< Component, Dim > &point, Id id)
Definition k_d_tree.h:398
void shrink_to_half()
Definition k_d_tree.h:461
Definition k_d_tree.h:266
void remove(Idx internalIdx)
Definition k_d_tree.h:323
void init(Idx root, uint8_t axis, const SortedIndices< Dim > &sorted)
Definition k_d_tree.h:343
KdTree(const KdTree &a, const KdTree &b)
Merge two trees. Both trees are assumed to have a power of two size.
Definition k_d_tree.h:301
std::array< Component, Dim > Point
Definition k_d_tree.h:268
std::unique_ptr< Idx[]> tree
Definition k_d_tree.h:386
void rangeQuery(const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:317
KdTree()
Empty tree.
Definition k_d_tree.h:271
KdTree(const Point &point, const Id &id)
Build a tree containing just a single point.
Definition k_d_tree.h:279
std::unique_ptr< Id[]> ids
Definition k_d_tree.h:385
size_t cap() const
Capacity, not size, since some items may be marked as deleted.
Definition k_d_tree.h:340
KdTree(size_t n, Id const *ids, std::array< Component const *, Dim > pts)
Build a tree.
Definition k_d_tree.h:290
std::vector< bool > deleted
Definition k_d_tree.h:387
SortedPoints< Dim, Component > items
Definition k_d_tree.h:384
void rangeQuery(size_t root, uint8_t split, const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:357
size_t n
Definition k_d_tree.h:113
Points()
Empty.
Definition k_d_tree.h:74
Point getPoint(Idx i) const
Definition k_d_tree.h:93
Component * end(uint8_t d)
Definition k_d_tree.h:108
std::unique_ptr< Component[]> coords
Definition k_d_tree.h:114
std::array< Component, Dim > Point
Definition k_d_tree.h:72
Component * begin(uint8_t d)
Definition k_d_tree.h:107
Points(size_t n)
Allocating constructor; leaves coords uninitialized!
Definition k_d_tree.h:76
void setPoint(Idx i, const Point &point)
Definition k_d_tree.h:101
void assign(Idx start, const Points &from)
Definition k_d_tree.h:87
size_t size() const
Definition k_d_tree.h:85
Points(size_t n, const std::array< Component const *, Dim > &coords)
Copying constructor.
Definition k_d_tree.h:78
const Component * end(uint8_t d) const
Definition k_d_tree.h:110
const Component * begin(uint8_t d) const
Definition k_d_tree.h:109
Definition k_d_tree.h:119
static SortedIndices newUninitialized(size_t n)
uninitialized indices
Definition k_d_tree.h:125
Idx * end(uint8_t d)
Definition k_d_tree.h:189
Points< Dim, Idx > indices
Definition k_d_tree.h:194
SortedIndices(Points< Dim, Idx > &&indices)
Definition k_d_tree.h:193
Idx * begin(uint8_t d)
Definition k_d_tree.h:188
bool empty() const
Definition k_d_tree.h:142
const Idx * end(uint8_t d) const
Definition k_d_tree.h:191
const Idx * begin(uint8_t d) const
Definition k_d_tree.h:190
size_t size() const
Definition k_d_tree.h:141
SortedIndices()
empty
Definition k_d_tree.h:122
SplitResult split(uint8_t axis, std::vector< bool > &markers) const
Definition k_d_tree.h:151
SortedIndices(size_t n)
Identity permutation on all axes.
Definition k_d_tree.h:131
Definition k_d_tree.h:199
size_t size() const
Definition k_d_tree.h:253
SortedPoints(size_t n, const std::array< Component const *, Dim > ptrs)
Sort points.
Definition k_d_tree.h:211
Points< Dim, Component > points
Definition k_d_tree.h:260
SortedPoints()
Definition k_d_tree.h:201
SortedPoints(const SortedPoints &a, const SortedPoints &b)
Merge two sets of sorted points.
Definition k_d_tree.h:223
SortedIndices< Dim > indices
Definition k_d_tree.h:261
SortedPoints(const std::array< Component, Dim > &point)
Single point.
Definition k_d_tree.h:204
#define sanity_check(expr)
Definition debug.h:74
#define _(String)
Definition gettext.h:28
uint16_t Idx
Definition k_d_tree.h:61
std::vector< std::basic_string< T > > split(std::basic_string_view< T > s, T delim, T escape=static_cast< T >('\\'))
Splits a string into its component parts separated by the character delimiter.
Definition string.h:681
Definition k_d_tree.h:509
Idx in_tree
Definition k_d_tree.h:511
uint8_t tree_idx
Definition k_d_tree.h:510
Definition k_d_tree.h:144
SortedIndices right
Definition k_d_tree.h:145
SortedIndices left
Definition k_d_tree.h:145
Idx pivot
Definition k_d_tree.h:146