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