Return if there is no point needs to insert.
Calculate current dimension (cd).
Sort points in cd.
Get Center iterator.
Base case: If node is null, create a new node.
Insert in left.
Insert in right.
326 {
327 constexpr int nPointsWithoutSplitTask = 30000;
328
329 if (points->size() <= nPointsWithoutSplitTask)
330 {
331 const auto in = std::chrono::high_resolution_clock::now();
333 const auto out = std::chrono::high_resolution_clock::now();
334 std::cout << " Cost: " << std::chrono::duration_cast<std::chrono::milliseconds>(out - in).count() << " " << points->size() << std::endl;
335 return;
336 }
337
341 if (points->size() == 0) return;
342
347
351 std::multimap<float, uint32_t> sorted;
352 if (points->size() <= 512)
353 {
354 for (int i = 0; i < points->size(); i++)
355 {
356 sorted.emplace((*points)[i][cd], i);
357 }
358 }
359 else
360 {
361 for (int i = 0; i < 512; i++)
362 {
363 uint32_t index = static_cast<uint32_t>((points->size() - 1) * std::rand() / float(RAND_MAX));
364 sorted.emplace((*points)[index][cd], index);
365 }
366 }
367
371 auto centerit = sorted.begin();
372 for(int i = 0; i < std::floor(sorted.size() * 0.5); i++) ++centerit;
373
377 if (node == nullptr)
378 {
379 node = new Node((*points)[centerit->second]);
381 }
382 else
383 {
384 SPICES_CORE_ERROR("Cannot insert a KDTree Node which is not empty.");
385 }
386
390 threadPool->
SubmitPoolTask([
this, cd, points, node, threadPool, depth](
float centerVal, uint32_t centerIndex) {
391 std::shared_ptr<std::vector<item>> leftPoints = std::make_shared<std::vector<item>>();
392 for (int i = 0; i < points->size(); i++)
393 {
394 if (i == centerIndex) continue;
395 else if ((*points)[i][cd] <= centerVal)
396 {
397 leftPoints->push_back((*points)[i]);
398 }
399 }
401 }, centerit->first, centerit->second);
402
406 threadPool->
SubmitPoolTask([
this, cd, points, node, threadPool, depth](
float centerVal, uint32_t centerIndex) {
407 std::shared_ptr<std::vector<item>> rightPoints = std::make_shared<std::vector<item>>();
408 for (int i = 0; i < points->size(); i++)
409 {
410 if (i == centerIndex) continue;
411 else if ((*points)[i][cd] > centerVal)
412 {
413 rightPoints->push_back((*points)[i]);
414 }
415 }
417 }, centerit->first, centerit->second);
418 }
auto SubmitPoolTask(Func &&func, Args &&... args) -> std::future< decltype(func(std::forward< Args >(args)...))>
Submit a task to task queue, and wait for a idle thread to execute it.
void insert_recursive_async(Node *&node, std::shared_ptr< std::vector< item > > points, Spices::ThreadPool *threadPool, int depth)
Recursive function to insert a point into the kd_tree async.
void insert_recursive(Node *&node, std::shared_ptr< std::vector< item > > points, int depth)
Recursive function to insert a point into the kd_tree.
std::atomic_size_t m_Size
Sizes of this kd tree.