Compute radius threshold graph.
Connects all point pairs within radius distance. Undirected graph: if (i,j) exists, edge appears once.
308{
309 const auto n =
static_cast<size_t>(
points.cols());
310 if (n < 2) {
311 return {};
312 }
313
315 const auto dim =
static_cast<size_t>(
points.rows());
316 const double* base =
points.data();
317
318 std::vector<size_t> offsets(n + 1, 0);
319
320 std::for_each(std::execution::par_unseq,
321 std::views::iota(size_t { 0 }, n).begin(),
322 std::views::iota(size_t { 0 }, n).end(),
323 [&](size_t i) {
324 const double* pi = base + i * dim;
326 for (size_t j = i + 1; j < n; ++j) {
327 if (dist_sq(pi, base + j * dim, dim) <= radius_sq) {
329 }
330 }
331 offsets[i + 1] =
count;
332 });
333
334 for (size_t i = 0; i < n; ++i) {
335 offsets[i + 1] += offsets[i];
336 }
337
339
340 std::for_each(std::execution::par_unseq,
341 std::views::iota(size_t { 0 }, n).begin(),
342 std::views::iota(size_t { 0 }, n).end(),
343 [&](size_t i) {
344 const double* pi = base + i * dim;
345 size_t at = offsets[i];
346 for (size_t j = i + 1; j < n; ++j) {
347 if (dist_sq(pi, base + j * dim, dim) <= radius_sq) {
348 edges[
at++] = { i, j };
349 }
350 }
351 });
352
353 MF_DEBUG(Journal::Component::Kinesis, Journal::Context::Runtime,
354 "radius_threshold_graph: {} points, radius={:.3f}, generated {} edges",
356
357 return edges;
358}
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
std::vector< std::pair< size_t, size_t > > EdgeList