9#include <unordered_map>
67template<u
int8_t Dim,
typename Component>
71 using Point = std::array<Component, Dim>;
80 for (uint8_t d = 0; d < Dim; ++d)
84 size_t size()
const {
return n; }
88 for (uint8_t d = 0; d < Dim; ++d)
95 for (uint8_t d = 0; d < Dim; ++d)
96 point[d] =
begin(d)[i];
102 for (uint8_t d = 0; d < Dim; ++d)
103 begin(d)[i] = point[d];
108 const Component *
begin(uint8_t d)
const {
return coords.get() + d *
n; }
109 const Component *
end(uint8_t d)
const {
return begin(d) +
n; }
133 for (uint8_t d = 0; d < Dim; ++d) {
134 for (
Idx i = 0; i < n; ++i) {
154 const auto mid =
begin + left_n;
157 for (
auto it =
begin; it != mid; ++it)
165 for (uint8_t d = 0; d < Dim; ++d) {
175 *(right_ptr++) = *it;
181 for (
auto it =
begin; it != mid; ++it)
182 markers[*it] =
false;
184 return SplitResult{std::move(left), std::move(right), *mid};
196template<u
int8_t Dim,
class Component>
206 points.setPoint(0, point);
213 for (uint8_t d = 0; d < Dim; ++d) {
214 const auto coord =
points.begin(d);
216 return coord[i] < coord[j];
225 const auto n =
points.size();
227 for (uint8_t d = 0; d < Dim; ++d) {
230 const auto coord =
points.begin(d);
231 auto a_ptr = a.
indices.begin(d);
232 auto b_ptr = b.
indices.begin(d);
233 auto dst_ptr =
indices.begin(d);
235 const auto i = *a_ptr;
236 const auto j = *b_ptr + a.
size();
237 if (coord[i] <= coord[j]) {
245 while (a_ptr != a.
indices.end(d))
246 *(dst_ptr++) = *(a_ptr++);
247 while (b_ptr != b.
indices.end(d))
248 *(dst_ptr++) = a.
size() + *(b_ptr++);
263template<u
int8_t Dim,
class Component,
class Id>
267 using Point = std::array<Component, Dim>;
280 ,
ids(std::make_unique<Id[]>(1))
281 ,
tree(std::make_unique<
Idx[]>(1))
289 KdTree(
size_t n, Id
const *
ids, std::array<Component const *, Dim> pts)
291 ,
ids(std::make_unique<Id[]>(n))
292 ,
tree(std::make_unique<
Idx[]>(n))
295 std::copy(
ids,
ids + n, this->ids.get());
303 tree = std::make_unique<Idx[]>(
cap());
304 ids = std::make_unique<Id[]>(
cap());
305 std::copy(a.
ids.get(), a.
ids.get() + a.
cap(),
ids.get());
329 void foreach(F cb)
const
331 for (
Idx i = 0; i <
cap(); ++i) {
333 cb(i,
items.points.getPoint(i),
ids[i]);
347 const auto next_axis = (axis + 1) % Dim;
348 if (!
split.left.empty())
349 init(2 * root + 1, next_axis,
split.left);
350 if (!
split.right.empty())
351 init(2 * root + 2, next_axis,
split.right);
362 const auto ptid =
tree[root];
363 const auto coord =
items.points.begin(
split)[ptid];
364 const auto leftChild = 2*root + 1;
365 const auto rightChild = 2*root + 2;
366 const auto nextSplit = (
split + 1) % Dim;
367 if (min[
split] > coord) {
368 rangeQuery(rightChild, nextSplit, min, max, cb);
369 }
else if (max[
split] < coord) {
370 rangeQuery(leftChild, nextSplit, min, max, cb);
372 rangeQuery(rightChild, nextSplit, min, max, cb);
373 rangeQuery(leftChild, nextSplit, min, max, cb);
376 const auto point =
items.points.getPoint(ptid);
377 for (uint8_t d = 0; d < Dim; ++d)
378 if (point[d] < min[d] || point[d] > max[d])
380 cb(point,
ids[ptid]);
384 std::unique_ptr<Id[]>
ids;
389template<u
int8_t Dim,
class Component,
class Id>
397 void insert(
const std::array<Component, Dim> &point, Id
id)
399 Tree tree(point,
id);
400 for (uint8_t tree_idx = 0;; ++tree_idx) {
401 if (tree_idx ==
trees.size()) {
402 trees.push_back(std::move(tree));
407 if (
trees[tree_idx].cap() == 0) {
408 trees[tree_idx] = std::move(tree);
422 trees.at(it->second.tree_idx).remove(it->second.in_tree);
439 for (
const auto &tree :
trees)
440 tree.rangeQuery(min, max, cb);
452 trees[tree_idx].foreach([&](
Idx in_tree_idx,
auto _, Id
id) {
468 const auto live_ids = std::make_unique<Id[]>(
n_entries);
471 for (
const auto &tree :
trees) {
472 tree.foreach([&](
Idx _,
auto point, Id
id) {
483 auto id_ptr = live_ids.get();
484 std::array<Component const *, Dim> point_ptrs;
486 for (uint8_t d = 0; d < Dim; ++d)
487 point_ptrs[d] = live_points.
begin(d);
488 for (uint8_t tree_idx = 0; tree_idx <
trees.size() - 1; ++tree_idx, n *= 2) {
492 if (
trees[tree_idx+1].cap() > 0) {
493 tree = std::move(
Tree(n, id_ptr, point_ptrs));
495 for (uint8_t d = 0; d < Dim; ++d)
498 trees[tree_idx] = std::move(tree);
Definition k_d_tree.h:391
void updateDelEntries(uint8_t tree_idx)
Definition k_d_tree.h:450
void rangeQuery(const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:436
std::vector< Tree > trees
Definition k_d_tree.h:505
void remove(Id id)
Definition k_d_tree.h:418
std::unordered_map< Id, DelEntry > del_entries
Definition k_d_tree.h:510
size_t n_entries
Definition k_d_tree.h:511
typename Tree::Point Point
Definition k_d_tree.h:395
KdTree< Dim, Component, Id > Tree
Definition k_d_tree.h:392
size_t size() const
Definition k_d_tree.h:443
void update(const Point &newPos, Id id)
Definition k_d_tree.h:429
size_t deleted
Definition k_d_tree.h:512
void insert(const std::array< Component, Dim > &point, Id id)
Definition k_d_tree.h:397
void shrink_to_half()
Definition k_d_tree.h:458
Definition k_d_tree.h:265
void remove(Idx internalIdx)
Definition k_d_tree.h:322
void init(Idx root, uint8_t axis, const SortedIndices< Dim > &sorted)
Definition k_d_tree.h:342
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:300
std::array< Component, Dim > Point
Definition k_d_tree.h:267
std::unique_ptr< Idx[]> tree
Definition k_d_tree.h:385
void rangeQuery(const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:316
KdTree()
Empty tree.
Definition k_d_tree.h:270
KdTree(const Point &point, const Id &id)
Build a tree containing just a single point.
Definition k_d_tree.h:278
std::unique_ptr< Id[]> ids
Definition k_d_tree.h:384
size_t cap() const
Capacity, not size, since some items may be marked as deleted.
Definition k_d_tree.h:339
KdTree(size_t n, Id const *ids, std::array< Component const *, Dim > pts)
Build a tree.
Definition k_d_tree.h:289
std::vector< bool > deleted
Definition k_d_tree.h:386
SortedPoints< Dim, Component > items
Definition k_d_tree.h:383
void rangeQuery(size_t root, uint8_t split, const Point &min, const Point &max, const F &cb) const
Definition k_d_tree.h:356
size_t n
Definition k_d_tree.h:112
Points()
Empty.
Definition k_d_tree.h:73
Point getPoint(Idx i) const
Definition k_d_tree.h:92
Component * end(uint8_t d)
Definition k_d_tree.h:107
std::unique_ptr< Component[]> coords
Definition k_d_tree.h:113
std::array< Component, Dim > Point
Definition k_d_tree.h:71
Component * begin(uint8_t d)
Definition k_d_tree.h:106
Points(size_t n)
Allocating constructor; leaves coords uninitialized!
Definition k_d_tree.h:75
void setPoint(Idx i, const Point &point)
Definition k_d_tree.h:100
void assign(Idx start, const Points &from)
Definition k_d_tree.h:86
size_t size() const
Definition k_d_tree.h:84
Points(size_t n, const std::array< Component const *, Dim > &coords)
Copying constructor.
Definition k_d_tree.h:77
const Component * end(uint8_t d) const
Definition k_d_tree.h:109
const Component * begin(uint8_t d) const
Definition k_d_tree.h:108
Definition k_d_tree.h:118
static SortedIndices newUninitialized(size_t n)
uninitialized indices
Definition k_d_tree.h:124
Idx * end(uint8_t d)
Definition k_d_tree.h:188
Points< Dim, Idx > indices
Definition k_d_tree.h:193
SortedIndices(Points< Dim, Idx > &&indices)
Definition k_d_tree.h:192
Idx * begin(uint8_t d)
Definition k_d_tree.h:187
bool empty() const
Definition k_d_tree.h:141
const Idx * end(uint8_t d) const
Definition k_d_tree.h:190
const Idx * begin(uint8_t d) const
Definition k_d_tree.h:189
size_t size() const
Definition k_d_tree.h:140
SortedIndices()
empty
Definition k_d_tree.h:121
SplitResult split(uint8_t axis, std::vector< bool > &markers) const
Splits the sorted indices in the middle along the specified axis, partitioning them into left (<=),...
Definition k_d_tree.h:150
SortedIndices(size_t n)
Identity permutation on all axes.
Definition k_d_tree.h:130
Definition k_d_tree.h:198
size_t size() const
Definition k_d_tree.h:252
SortedPoints(size_t n, const std::array< Component const *, Dim > ptrs)
Sort points.
Definition k_d_tree.h:210
Points< Dim, Component > points
Definition k_d_tree.h:259
SortedPoints()
Definition k_d_tree.h:200
SortedPoints(const SortedPoints &a, const SortedPoints &b)
Merge two sets of sorted points.
Definition k_d_tree.h:222
SortedIndices< Dim > indices
Definition k_d_tree.h:260
SortedPoints(const std::array< Component, Dim > &point)
Single point.
Definition k_d_tree.h:203
#define _(String)
Definition gettext.h:28
uint16_t Idx
Definition k_d_tree.h:60
std::vector< std::basic_string< T > > split(const std::basic_string< T > &s, T delim)
Definition string.h:646
Definition k_d_tree.h:506
Idx in_tree
Definition k_d_tree.h:508
uint8_t tree_idx
Definition k_d_tree.h:507
Definition k_d_tree.h:143
SortedIndices right
Definition k_d_tree.h:144
SortedIndices left
Definition k_d_tree.h:144
Idx pivot
Definition k_d_tree.h:145