A Primer on Bézier Curves
pomax.github.io
pomax.github.io
Bartosz Ciechanowski's one from last year is my favourite, a little less math heavy and goes on to explain other curves and surfaces: https://ciechanow.ski/curves-and-surfaces/
Found this via a contest by Grant Sanderson, and it absolutely blew me away(and most people I forwarded it to)
That is, no matter how much art you know or math you know it is awkward to draw things with Bézier curves and it's a bit of a tragedy that NURBS and other curve families that are more intuitive to work with haven't caught on.
https://inversethought.com/jordi/xsplines/
I find them super-intuitive to use. The fact that at each node you can make it close, sharp, or interpolating is quite helpful. They're also not hard to implement. You can read my js code to see how I did it.
They're implemented in Xfig and just about nowhere else. I wish they were elsewhere. I've been thinking about getting them into GNU IMP. Maybe some day I'll sit down and try to write patches for it.
The first implementations of digital fonts (before the DTP time with Adobe/Apple/Microsoft) were also using other types of curves, but Béziers won, I think because they are much more efficient to calculate, which was particularly important in the 90s (as the next step after bitmap fonts).
For all the complaints that people have about PDF files my favorite is that PDF doesn't have a primitive to draw circles (generally conics) so a 'circle' in a PDF file is always some combination of Bézier curves.
One application I like for Béziers is easing curves for animations, dimming lights, etc. Unlike the 2-d drawing case I feel like I can always get the effect I want without a fight.
I feel like it’s even more tragic that Uniform B-splines aren’t more common, especially quadratic and cubic versions. Git rid of knots, and talk specifically about degree 2 or 3, and you don’t need a PhD in math to follow the explanation. You can explain it without the sums of sums of recursive basis functions while juggling several different indices, no need to discuss knot insertion and removal. Uniform B-splines segments have a 1:1 mapping to Bézier curves, and understanding them before diving into non-uniform curves would be so helpful and actually cover two thirds of what people need and what happens in practice.
The big problem with NURBS is that the only information you can find on them dives into unwieldy math notation and discussion about knots, there’s almost nothing out there that’s simple and quick to follow, or tailored specifically to constrained cases, people writing drawing apps and games. The material all seems to be abstract and arbitrary degree and arbitrary complex uses. I feel like NURBS is a case where it becomes clear that the notation gets in the way of understanding, it truly feels like there should be a simpler notation because the concepts are easier to grok than the math.
I guess? I think most designers are so used to using the pen tools and problem solving with them that they start to become intuitive after a while. There's a bit of a learning curve (pun intended), but I think once you understand how they are implemented in Adobe products, for instance, they become pretty simple.
This Bezier game is excellent practice: https://bezier.method.ac/
To always get “fair” curves using Bézier segments requires an extreme amount of effort, and either a very good eye and a lot of experience or some additional tooling that highlights where the lumps are.
Sorry for repeating my comment, but you really should check out the the interactive examples of the closed bezier curves (which could also be open). They were designed to be intuitive as the control points are on curve.
The project is is in its infancy, yet the interactive examples are working. https://rockingship.github.io/ccbc/README.html
Ha! Of course every graphics API makes it easy, but there is much going on under the hood. (Um, do GPU's have hoods?) See "Bresenham's algorithm": https://en.wikipedia.org/wiki/Bresenham's_line_algorithm
Yeah the API counts as a hood, I would say modern GPUs and CPUs have multiple hoods… multiple API layers… hoods under hoods. It’s hoods all the way down. :P
An interesting generalization of Bresenham is the DDA https://en.wikipedia.org/wiki/Digital_differential_analyzer_...
The basic "draw a line" is the incredibly simple "single lerp to get the next on-line pixel coordinate" (which for naive drawing, may be the same coordinate, of course).
Quadratic Bezier is just trajectory of a point with initial velocity and constant acceleration.
Cubic Bezier is just trajectory of a point with initial velocity and acceleration, and constant change of acceleration.
Direction to control points are just initial/final velocity.
(A function with constant nth derivative is a polynomial.)
He's got hundreds of videos, from elementary school subjects up to research seminars, and they usually provide interesting perspectives even for familiar subjects, since he always tries to avoid using infinite sets, irrational numbers, limits, etc. (which he "doesn't believe in")
The project is heavily under construction, however the interactive examples are functional. The examples are intended for desktop, but should work with touchscreens.
This has been posted to HN 19+ times, here are some of the more useful threads:
https://news.ycombinator.com/item?id=14191577
https://news.ycombinator.com/item?id=20751074
https://news.ycombinator.com/item?id=11402656
https://news.ycombinator.com/item?id=12503851
https://news.ycombinator.com/item?id=8804691
https://news.ycombinator.com/item?id=30100427
Do I collect points when mouse is down and build a curve with those points? Do I get some other path information and rasterize?
I'm trying to write my own drawing program (for fun) but given my lack of background in this I feel myself floundering.
The B-spline is just a math name for a connected sequence of curve segments, setup so that the segments join nicely and so that there is a continuous “parameter” along the entire curve.
For a sketch interface, I personally prefer the quadratic B-spline to the cubic (but you can use any degree you want). The background for curves in general isn’t easy to pick up and understand quickly, but you might check out the “Chaikin” subdivision which is super simple math and equivalent to a quadratic curve.
At the very least you'll need a UI for placing the anchors and handles, but how the UI works is really subjective. Your next step is to take those anchors and desired resolution and generate a list of vertices. After that it's just an exercise in rasterization.
https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/
OP's primer looks very good too though. I look forward to going throught it properly.
Includes hands-on examples to help understand the math behind bezier curves.
This is not shaming in any way, it’s indexing good stuff, making it easy for people to find more information. It’s helpful to know that the posts are repeated, and is not expected that someone would know this - after all, most people here are relatively new and probably always will be (assuming the user base is growing). On occasion it also helps avoid repeat debates. I personally use the links often and I appreciate it when people collect them.
Edit to clarify, you can convert Catmull-Rom strands to Bezier strands, but you cannot generally go the other way from Bezier to Catmull-Rom and still preserve connected segments.
https://github.com/solvespace/solvespace/blob/master/src/srf...
I'll be having a read of this to see if we can improve on some of these. In particular I've wanting to add curve-curve intersection as in section 29:
https://pomax.github.io/bezierinfo/#curveintersection
I had already considered that exact approach, but there are cases (in CAD anyway) where portions of 2 curves may exactly overlap. In that case we'd want to identify the overlapping region and split the 2 curves into 3. These special cases might seem like corner cases and they are, but they come up in practice more than I'd like.
Of course at a point we'll get close enough to consider there to be some intersection, but do we get "close enough" for a single point? for a portion of each of the curves? Does the result change with the scale of the circles? Does it scale when the relative radius between the circles changes? Making those kinds of judgement calls within the algorithms is really a challenge, but makes a huge difference when building a geometry library and for usability (for other developers, and end users). Knowing your use cases may be helpful in determining what's the right approach for these situations.
OMG different curves and surfaces becoming tangent at a point is a huge pain. It's tempting to say that it tends to happen at the ends and can be checked for as a special case, or an algorithm tweaked based on that assumption, but then someone will find a perfectly reasonable construction that results in tangency at some arbitrary place and the problem returns.