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

◆ path_fraction()

std::function< float(glm::vec2)> MayaFlux::Kinesis::path_fraction ( std::span< const glm::vec2 >  points,
const std::function< glm::vec2()> &  live_offset = {} 
)
inline

Normalized arc-length position of the closest point on a polyline.

Inverse to stroke_slider, which places the handle at a fraction of the path's total arc length. Finds the nearest point across all segments and returns its cumulative length divided by the total, so the handle follows the cursor along the path regardless of how far off the path it strays.

Cumulative lengths are computed once and captured; the returned callable allocates nothing per invocation beyond an optional live_offset() call.

Parameters
pointsOrdered polyline vertices in NDC. Copied into the closure.
live_offsetOptional. Current translation of the drawn path - shifts the cursor into the path's own frame rather than re-translating every point per call.
Returns
Callable producing a value in [0, 1]. Returns 0 for paths with fewer than two points or zero total length.

Definition at line 176 of file Projection.hpp.

176 {})
177{
178 std::vector<glm::vec2> pts(points.begin(), points.end());
179 std::vector<float> cumulative(pts.size(), 0.F);
180
181 for (size_t i = 1; i < pts.size(); ++i)
182 cumulative[i] = cumulative[i - 1] + glm::length(pts[i] - pts[i - 1]);
183
184 const float total = pts.empty() ? 0.F : cumulative.back();
185
186 return [pts = std::move(pts), cumulative = std::move(cumulative), total, live_offset](
187 glm::vec2 p) -> float {
188 if (pts.size() < 2 || total <= 0.F)
189 return 0.F;
190
191 const glm::vec2 shift = live_offset ? live_offset() : glm::vec2(0.F);
192 const glm::vec2 q = p - shift;
193
194 float best_d2 = std::numeric_limits<float>::max();
195 float best_s = 0.F;
196
197 for (size_t i = 0; i + 1 < pts.size(); ++i) {
198 const glm::vec2 a = pts[i];
199 const glm::vec2 ab = pts[i + 1] - a;
200 const float len2 = glm::dot(ab, ab);
201
202 const float t = len2 > 1e-12F
203 ? glm::clamp(glm::dot(q - a, ab) / len2, 0.F, 1.F)
204 : 0.F;
205
206 const glm::vec2 diff = q - (a + t * ab);
207 const float d2 = glm::dot(diff, diff);
208
209 if (d2 < best_d2) {
210 best_d2 = d2;
211 best_s = cumulative[i] + t * std::sqrt(len2);
212 }
213 }
214
215 return std::clamp(best_s / total, 0.F, 1.F);
216 };
217}
std::vector< glm::vec2 > * points
uint32_t total
size_t a
double q

Referenced by MayaFlux::Portal::Forma::Geometry::stroke_slider().

+ Here is the caller graph for this function: