Pomax / BezierInfo-2

The development repo for the Primer on Bézier curves, https://pomax.github.io/bezierinfo
https://pomax.github.io/bezierinfo
Other
2.35k stars 290 forks source link

Section 36 describes a hermite curve, not a catmull-rom #364

Open FreyaHolmer opened 2 years ago

FreyaHolmer commented 2 years ago

Hey! Since I've been absolutely knee-deep in splines for months now, uh,, just wanted to give a heads up that

A Catmull-Rom curve is defined by a start point, a tangent that for that starting point, an end point, and a tangent for that end point, plus a characteristic matrix that we can multiple by the point vector to get on-curve coordinates.

This is the definition of the cubic hermite, not the catmull-rom, and the characteristic matrix you include is the char matrix for the hermite curve.

The catmull-rom definitions are a little inconsistent across the internet, but the most generally accepted version is the barry-goldman scheme for the non-uniform catmull-rom, and the alpha-parameterization for generating knots. But most importantly, the catmull-rom is always interpolating, and you never specify derivatives explicitly.

Now, it's of course true that you can make a catmull-rom curve using hermite curves, but, this goes for all cubic splines. you can make a bezier curve with a B-spline segment, or a B-spline segment with catmull-rom, and so on! because what makes a spline unique is not the curve itself, but how that curve is generated, given the input points.

The curve you describe that has a tension parameter is usually (but not always) called the cardinal spline, though exactly how this tension parameter is applied is very inconsistent - I've found three separate definitions of how tension should be factored in, and they all seem pretty confident, because nothing is consistent and everything is garbage!! I've personally resorted to not calling it tension, and rather a value that represents tangent scale, that is multiplied by the point difference of its neighbors. It's true that when you generate tangents based on neighbors, and the scale is exactly 1/2, then the curves it will generate is equivalent to the uniform catmull-rom curve

tldr: the catmull-rom you've included is a cubic hermite curve, and the thing with the tension parameter is a cardinal spline segment! (as far as I can tell, again, a lot of places mix up the cardinal/catmull-rom/hermite forms, and who knows maybe I'm wrong)

Pomax commented 2 years ago

Cheers, I'll have to dig into that a big more too it sounds like!

Pomax commented 2 years ago

Near as I can figure, looking at the original paper and subsequent publications this is just the poster child of "everyone, including me, has no idea what these things actually are".

The original Catmull and Rom paper just sets out which criteria interpolation functions needs to meet in order to yield a nice kind of spline, with the only constraints being that there must be continuity and differentiability across piece endpoints, but the original paper is really about a class of curves and shows examples using both B-spline and plain Bezier blending functions, but any blending function that meets the criteria would be just as valid.

So that's not all that useful.

The Barry/Goldkman paper takes this idea and shows how to evaluate a subclass of the Catmull-Rom splines, based on a Lagrange polynomial with a B-spline blending function (and now I'm curious why we're not calling those Barry-Goldman curves), but without degree restriction: the paper shows evaluating the de Boor algorithm for the cubic case, as well as some example graphics that use cubics, but the paper is about how to recursively evaluate the entire subclass.

So that's still not all that useful O_o

(Even if it's definitely more useful than the vastness of the entire Catmull-Rom space)

What I think I'm going to do here is rewrite these sections to first talk about Hermite curves, with the to-and-from conversions, follow that up to explain that we we can mess with the matrix to add in "a" tension factor (because as you mention, how that gets treated is at the very least a younger sibling to our poster child, and equally photogenic), as well as move these sections down in the ToC so that they precede the B-Spline section.

And then figure out where the appropriate place is to mention that some programming languages come with "Catmull-Rom" pathing operators/instructions/API functions, but that while those are super useful, your mileage my vary. By a lot.

FreyaHolmer commented 2 years ago

The original general definition of the catmull-rom has been almost entirely subsumed by the barry/goldman definition now as far as I've gathered, catmull-rom, colloquially, is now the specific type that barry/goldman is talking about, the C1 continuous interpolating spline, whether uniform or non-uniform. At the very least this is what people mean in 99% of cases when it comes to computing these things.

As for "bezier curves are a form of hermite curve", I think this is a bit of a misleading statement, because you can express all cubic splines as all other cubic splines, as in, you can define bezier curves using B-splines, you can define catmull-rom curves using beziers, they're completely and entirely interchangeable when it comes to a single curve/segment of the spline, because all they really are, are cubics. Their real differences only really show once you start looking at multi-segment splines, rather than individual curves.

Generally saying "X is a form of Y" has been less and less true the more I've dug into this topic, because they are used for different use cases, and they have different constraints, even though you can define one in the form of another in a way that creates the same shape, but what makes a spline unique isn't its shape, but rather by its input data, and how it relates to the generated curves, and the properties of this curve

Sorry for rambling, haha, feel free to hit me up on twitter at some point if you want to hop on voice chat instead of typing a lot

Pomax commented 2 years ago

no, that's fair, but that's also literally why it's part of the primer (as opposed to being someone else's problem =D), it's super useful to call out and give an equivalence between Beziers, and "not beziers, but still the same kind of curve, and much more useful in context XYZ". So in this case "X is a type of Y" would literally be to highlight how you could create something that you could use Beziers for, but is much easier not to, even if you can convert each segment to a Bezier curve if you really wanted to (you don't. But you might. But you shouldn't! =D)