thibauts / b-spline

B-spline interpolation
MIT License
299 stars 48 forks source link

Arc-length parameterization #3

Open jeremyabel opened 8 years ago

jeremyabel commented 8 years ago

It'd be great if there was a built-in option to reparameterize the spline based on arc length, so that it has continuous velocity. See this page for an explanation.

I've implemented this, I'd be happy to submit a pull request, if you think it'd be useful.

Oh and just wanted to say thanks for this; it's by far the easiest and nicest-looking path smoothing solution out there, at least for the sorts of things I do!

thibauts commented 8 years ago

You're welcome ! I'd love to know what you use it for !

I'm not sure I see how you're able to reparametrize from inside the interpolator, given it computes one point per call, but I'd love to see the code. Maybe this would fit better in another module that depends on this one, I'm not sure, but post the PR if you have it ready or post your impl in a gist and we'll talk about it !

jeremyabel commented 8 years ago

sorry for the weird spacing, here's a gist: https://gist.github.com/jeremyabel/ce6040ea999218c6517c44eb658aff9a

So basically the issue is that in the raw b-spline, the distance covered on the spline between t = 0.1 and t = 0.2 might not be the same as the distance covered between 0.2 and 0.3. So if you imagine a car moving on the spline at some constant rate per frame, then the car will slow down on tight curves and speed up on straighter portions. In my application, the b-spline is being used as an animation path, so having control over the rate of change of the speed of whatever you're animating along the path is critical.

The solution to this is to reparameterize the spline in terms of it's arc length. So you'd say "I want to be 50% of the way along this spline" as opposed to saying "I want to be at t = 0.5 along this spline".

thibauts commented 8 years ago

I get it. I got "speed control" implemented using pseudo-knots in another module (https://github.com/thibauts/cubic-hermite-spline). You wouldn't get constant speed though, if that's what you're looking for.

Looking at your code I think it would fit better in another module that layers on this one. This module doesn't precompute anything, each point being evaluated upon call with a specific t.

In a perfect world I (or somone else) would have implemented Nth-order derivatives using the blossoms approach (a twist on De Boor's algorithm) and you could do something like integrate it's absolute value to get a direct time / arclength map, but I'm not even sure it would lead to better or faster results.

Anyway, what could be nice would be 2 modules :

These are only broad suggestions based on my own habits but I think this would maximize reuse and separation of concerns.

journaux commented 1 year ago

+1 :)