Resample path vertices for arc-length parameterization.
Uses piecewise linear arc length estimation. Output vertices have constant spacing along curve.
394{
395 if (path_vertices.size() < 2 || num_samples < 2) {
396 return path_vertices;
397 }
398
399 std::vector<float> arc_lengths;
400 arc_lengths.reserve(path_vertices.size());
401 arc_lengths.push_back(0.0F);
402
403 float total_length = 0.0F;
404 for (size_t i = 1; i < path_vertices.size(); ++i) {
405 float segment_length = glm::distance(
408 total_length += segment_length;
409 arc_lengths.push_back(total_length);
410 }
411
412 if (total_length < 1e-6F) {
413 return path_vertices;
414 }
415
416 std::vector<Nodes::LineVertex> resampled;
417 resampled.reserve(num_samples);
418
419 for (size_t i = 0; i < num_samples; ++i) {
420 float target_length = (static_cast<float>(i) / static_cast<float>(num_samples - 1)) * total_length;
421
422 auto it = std::ranges::lower_bound(arc_lengths, target_length);
423 size_t idx = std::distance(arc_lengths.begin(), it);
424
425 if (idx == 0) {
426 resampled.push_back(path_vertices[0]);
427 } else if (idx >= path_vertices.size()) {
428 resampled.push_back(path_vertices.back());
429 } else {
430 float s0 = arc_lengths[idx - 1];
431 float s1 = arc_lengths[idx];
432 float t = (target_length - s0) / (s1 - s0);
433
434 glm::vec3 p0 = path_vertices[idx - 1].position;
435 glm::vec3 p1 = path_vertices[idx].position;
436 glm::vec3
position = glm::mix(p0, p1, t);
437
438 glm::vec3 c0 = path_vertices[idx - 1].color;
439 glm::vec3 c1 = path_vertices[idx].color;
440 glm::vec3
color = glm::mix(c0, c1, t);
441
442 resampled.push_back({ .position =
position,
444 .thickness = 1.0F });
445 }
446 }
447
448 return resampled;
449}
std::optional< glm::vec3 > color