MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ k_nearest()

template<typename PointT >
std::vector< QueryResult > MayaFlux::Kinesis::SpatialIndex< PointT >::k_nearest ( const PointT &  center,
uint32_t  k 
) const

Find the k nearest entities to a point.

Parameters
centerQuery origin.
kMaximum number of results.
Returns
Results sorted by ascending squared distance. May return fewer than k.

Definition at line 270 of file SpatialIndex.cpp.

273{
274#ifdef MAYAFLUX_PLATFORM_MACOS
275 auto [snap, slot] = acquire_snapshot();
276 if (!snap || snap->positions.empty()) {
277 if (snap)
278 release_snapshot(slot);
279 return {};
280 }
281#else
282 auto snap_ptr = m_snapshot.load(std::memory_order_acquire);
283 if (!snap_ptr || snap_ptr->positions.empty()) {
284 return {};
285 }
286 const auto* snap = snap_ptr.get();
287#endif
288
289 k = std::min(k, static_cast<uint32_t>(snap->positions.size()));
290
291 auto cmp = [](const QueryResult& a, const QueryResult& b) {
292 return a.distance_sq < b.distance_sq;
293 };
294 std::priority_queue<QueryResult, std::vector<QueryResult>, decltype(cmp)> heap(cmp);
295
296 for (uint32_t i = 0; i < static_cast<uint32_t>(snap->positions.size()); ++i) {
297 float d_sq = m_distance_fn(center, snap->positions[i]);
298 if (heap.size() < k) {
299 heap.push({ snap->slot_to_id[i], d_sq });
300 } else if (d_sq < heap.top().distance_sq) {
301 heap.pop();
302 heap.push({ snap->slot_to_id[i], d_sq });
303 }
304 }
305
306 std::vector<QueryResult> results;
307 results.reserve(heap.size());
308 while (!heap.empty()) {
309 results.push_back(heap.top());
310 heap.pop();
311 }
312 std::ranges::reverse(results);
313
314#ifdef MAYAFLUX_PLATFORM_MACOS
315 release_snapshot(slot);
316#endif
317
318 return results;
319}
size_t a
size_t b
std::atomic< std::shared_ptr< const SpatialSnapshot< PointT > > > m_snapshot

References a, and b.