
A Primer on Bézier Curves (2013) - acdanger
https://pomax.github.io/bezierinfo/
======
tobmlt
Wow, every time I see this site I am blown away by how well it is done.

I am going to put a couple of book titles out there in case somebody doesn't
know about them and could benefit:

1.) "The NURBS book" \-- Anybody got this one on their bookshelf? (authors Les
Piegl and Wayne Tiller) I can't recommend it enough, if you are into rolling
your own traditional B-spline lib with expert help!

2.) Then, for a gentle intro to multiresolution (especially because it makes
for a good jumping off point from traditional B-splines) there is "Wavelet's
for Computer Graphics" by Eric Stollnitz, Tony DeRose, and David Salesin. Very
good for a "matrix transform / projection-prolongation picture of splines, and
related entities.

Anyway, these helped me on my (continuing) Spline/CAD journey. Cheers.

------
TheRealPomax
This really shouldn't need the (2013) suffix - it's constantly getting
updated, and the most recent update was from only a few days ago. (it's
probably about 50 pages longer than it was back in 2013, if not more)

~~~
dahart
I didn’t know it was under active development, but I use this reference a lot.
Thank you!

What are you adding these days?

You know what’s on my wish list? A simplified uniform B-spline treatment
specific to cubic & quadratic curves. Everywhere I look online, the B-spline
explanations are crazy long and complicated with recursive summation diagrams
and math about knots and non-uniformity and N-degree evaluation all at once.
An open uniform cubic B-spline, though, is really simple, and that’s probably
all I’d ever use in CG in practice. But it’s difficult to distill from what’s
online right now. Converting a cubic B-spline to Bezier, for example, is a
simple 4x4 matrix, and recently I needed it and went looking... it took a
while to find.

~~~
TheRealPomax
That does sound useful to talk about, could I convince you to hit up the issue
tracker to for that as a section request?

I just added a weirdly missing short section on plain rational beziers (not
b-splines, just single beziers), and I'd like to still add a section on
turning hand drawn paths into polybeziers.

~~~
delhanty
>I just added a weirdly missing short section on plain rational beziers

That's great! Thanks for writing and maintaining this document over the years!

Coincidentally, I was referencing the section on offsetting [0] just last week
and read the following,

>There is a small class of polynomials where the square root is also a
polynomial, but they're utterly useless to us: any polynomial with unweighted
binomial coefficients has a square root that is also a polynomial. ...We can
already create offset curves for points, we call them circles, and they have
much simpler functions than Bézier curves.

and thought, something like: "That's correct because Bézier curves in the
context of this document, SVG, HTML canvas and fonts means polynomial (i.e
non-rational) Bézier curves."

But if you're now considering rational Bézier curves as in-scope for the
document that changes things doesn't it ? E.g Circles represented as rational
Bézier quadratics, and Pythagorean Hodographs [1].

[0]
[https://pomax.github.io/bezierinfo/#offsetting](https://pomax.github.io/bezierinfo/#offsetting)

[1]
[http://demonstrations.wolfram.com/G1HermiteInterpolationWith...](http://demonstrations.wolfram.com/G1HermiteInterpolationWithPythagoreanHodographCubicCurves/)

~~~
TheRealPomax
Rational Beziers are no longer polynomials, though. If the basis value used
for the division was a constant, then it would be, but instead it's a function
of t.

------
bezieio
I open sourced Bezie
([https://github.com/jperler/bezie](https://github.com/jperler/bezie)), a
library I wrote three years ago for MIDI automation curves. It includes some
good examples of how to interpolate cubic and quadratic bezier curves given
drag points on the curves. I used Pomax's bezier write ups as a starting
point, which really helped out a lot (thanks Pomax!). If anyone is interested,
take a look in `bezie/app/utils`, specifically the `getControl` methods that
allow you to derive control points.

~~~
TheRealPomax
Always cool to see what people end up making!

------
petersonh
The bezier.js library associated with this is great

~~~
TheRealPomax
Thanks! I had to update it for the most recent update (it had no concept of
rational bezier curves) so hopefully I can update its API page soon with a
short bit on how to specify curve ratios and have that be available to
everyone, too.

------
jihadjihad
Previous discussion (2017):
[https://news.ycombinator.com/item?id=14191577](https://news.ycombinator.com/item?id=14191577)

~~~
aidenn0
People keep wanting to read stories about bezier curves. It's the law of
spline demand.

~~~
elliottkember
Splines is short for “sparkling lines”, which is the correct term when they
don’t come from the Bézier region of France

~~~
pure-awesome
Beautiful! This joke has a very "XKCD" quality to it.

------
romwell
I enjoyed reading it, but I wouldn't call it a "primer", since I can hardly
think of what else there is to know about Bezier curves! It's a rather
comprehensive exposition.

Here's a primer on Bezier curves if you had to program them in 30 minutes. You
won't need more than this:

1\. Bezier curves are just taking weighted averages, repeatedly. A weighted
average of two points, A and B, is a linear combination _P(t) = (1-t)A + tB_.
As _t_ goes from 0 to 1 with constant speed, _P(t)_ goes from A to B with
constant speed.

A weighted average like this gives you _one_ point out of _two_. Now, say you
have _four_ points, in order: A1, A2, A3, A4. For a number _t_ between 0 and
1, take weighted averages of consecutive points: A1 and A2, A2 and A3, A3 and
A4. That gives you a sequence _three_ points. Repeat this procedure until you
have only one point left. That's your Bezier curve defined by A1..A4 at time
t. This is called a 3rd degree curve, and generalizes to sequences of any
length (you can figure out how!).

2\. The above tells you how to draw this with a computer. Just pick, say, 100
values of _t_ between 0 and 1, and connect the dots with straight lines. That
is, you converted a curve into a poly-line, consisting of straight segments.
This can be used to compute intersections (just see if any one segment
intersects any other), compute tangents (extend any segment to get a tangent
at that point), normals (in 2D: rotate a segment by 90 degrees clockwise).

3\. Most importantly, _why_ you would want to do something like this: Bezier
curves are easy for machines to trace, and for humans to understand. Here are
some properties of a (cubic) Bezier curve given by points A1, A2, A3, A4:

-it starts at A1, and ends at A4

-it is tangent to segments A1A2 and A3A4 at endpoints

-by moving A2 and A3, it is easy to make a C- and S- shaped curve.

Beyond that, things aren't as intuitive. This is why _all_ graphics software
gives you 3rd degree Bezier curves as a tool: it's flexible enough while easy
enough.

In practice, Bezier curves came to replace the French Curve[1]. The irony is
that there is little French about the French curve (nobody even knows why
they're called that!), but Bezier curves are French through and trough: the
two key people behind them, Paul de Casteljau and Pierre Bezier, have spent
their entire lives in France, and came up with the curves for manufacturing at
Citroen and Renault. Arguably, Bezier curves are the true French curves.

4\. Bonus. In Photoshop/Illustrator/etc: the UI for Bezier curves is this:
click and drag to define A1 and A2 (A1 is is where you click, A2 is where you
release). Consecutive click-drag-releases define three points: e.g. A3 on
mouse down, A4 on mouse up, and A5 such that A4 is the midpoint of A3 and A5.
The curve you get is a union of cubic Beziers defined by A1..A4, A4..A7,
A7..A10, etc.

The curve is smooth because the UI forces the tangents to be aligned (unless
you do a single click without dragging: this makes 2 tangents of length 0,
i.e. a vertex).

When drawing curves using this UI, you really are drawing _tangents_ to the
curve you want to get: draw _— to get an S, roughly.

That's it folks! For way, way more - read the article :) (Which is an
interactive book, at this point).

[1][https://en.wikipedia.org/wiki/French_curve](https://en.wikipedia.org/wiki/French_curve)

~~~
sweeneyrod
> 2\. The above tells you how to draw this with a computer. Just pick, say,
> 100 values of t between 0 and 1, and connect the dots with straight lines.

This is the obvious algorithm, but it has the problem that curvature is not
uniform with respect to t - sometimes a straight line is a good approximation
to a segment but sometimes it isn't. So instead you can draw a curve with a
function that draws a straight line when that's good enough, and splits the
curve in two then recurses on each half otherwise.

~~~
romwell
Good point! It's hard to make a call as to what to do include in a 5-minute
overview, but your point fits in one sentence, and is easy to understand.
Thanks!

------
jpz
What a great contribution.

------
baroffoos
Back in highschool I wrote a script using sagemath that could draw bezier
curves when given the points and handles. It was really cool how simple the
math behind it was.

------
Yajirobe
The expression of a Bezier curve involves t^i (in the summation). Both t and i
acquire values of 0 at some point, so you get a 0^0 in the summation, which is
undefined.

~~~
TheRealPomax
But also understood to be 1 here.

------
trilinearnz
Very readable. A fantastic contribution.

~~~
TheRealPomax
Thanks!

