Profile picture
Freya Holmér @FreyaHolmer
, 20 tweets, 6 min read Read on Twitter
A thread, on the ever so lovely Bézier curve ✨
Bézier curves are, to me, one of the best examples of mathematical beauty. It's fascinating what such a simple function on some points can achieve. Here's a step-by-step visualization of how a cubic Bézier curve can be constructed. Note each point's position along its own line
If you look closely, you may see we're using Linear interpolation, or, lerp! Lerping the original points, and then between the resulting points, gives rise to curves. Looking at the second set of points - we can see that even they themselves form two *quadratic* Bézier curves
How does it work in code? To get a point in the curve, you simply provide a value between 0 and 1, known as the t-value, to this set of lerps:

a = lerp( p0, p1, t );
b = lerp( p1, p2, t );
c = lerp( p2, p3, t );
d = lerp( a, b, t );
e = lerp( a, b, t );
point = lerp( d, e, t );
While the code above is easy to understand, there are computationally more efficient ways of evaluating this. If you work out the math behind all lerps, and simplify, you end up with four equations that act as weights on each point, which, when visualized, looks like this
Mathematically, we're using Bernstein polynomials here!

point =
p0*(-t³+3t²-3t+1)+
p1*(3t³-6t²+3t)+
p2*(-3t³+3t²)+
p3*(t³)

Or, in code:

omt = 1 - t;
omt2 = omt * omt;
t2 = t * t;

point =
p0 * ( omt2 * omt ) +
p1 * ( 3 * omt2 * t ) +
p2 * ( 3 * omt * t2 ) +
p3 * ( t2 * t );
Give it a try!
acegikmo.com/bezier/
Apologies for the typo in this one! If only we could edit tweets.
Correction: e = lerp( b, c, t );
Addendum!
A quirk when using Bézier curves is that the t-value is actually not the same thing as percentage of distance along the curve. The difference in t-value between each segment here is constant, and the animation is linearly animating t, yet the speed is not constant
This is often a problem for animation. One solution to this, is to build a lookup table that can help you convert percentage along the spline to t, that way you can animate uniformly, like this!
If you want more information on how to do this lookup table, you can check out some slides from a talk of mine! Slides 75-82:
docs.google.com/presentation/d…
Also, many of you have correctly pointed out that in the fourth tweet, it should be:
e = lerp( b, c, t );

Let's pretend I did that typo just to make sure you were paying attention 😶

(Also Twitter let us edit tweets already geez)
Some have asked how to know we should use Bernstein polynomials. The truth is, I only found out they were called that *after* I derived those equations. I arrived at them naturally by doing the math:

v = lerp( a, b, t )

is mathematically

v = (1-t)a + bt
Now let's look at our Bézier evaluation again, this time with lerps expressed as math:

a = (1-t)p₀ + tp₁
b = (1-t)p₁ + tp₂
c = (1-t)p₂ + tp₃
d = (1-t)a + tb
e = (1-t)b + tc
point = (1-t)d + te
Before we can simplify, let's collapse it all into a single equation. First, substitute in a, b and c into d and e:

d = (1-t)((1-t)p₀+tp₁)+t((1-t)p₁+tp₂)
e = (1-t)((1-t)p₁+tp₂)+t((1-t)p₂+tp₃)
point = (1-t)d + te
Then d and e into the point equation, to create this monster:

point = (1-t)((1-t)((1-t)p₀+tp₁)+t((1-t)p₁+tp₂)) + t((1-t)((1-t)p₁+tp₂)+t((1-t)p₂+tp₃))

This is the last we'll see of the lerp-like equations!
We now expand to untangle all the points and t values. What you end up with, is this:

point =
-p₀t³ + 3p₀t² - 3p₀t + p₀ +
3p₁t³ - 6p₁t² + 3p₁t -
3p₂t³ + 3p₂t² +
p₃t³

If you look at each line here, you can see that each belong to a specific point
With that in mind, we can finally simplify it by separating out each point as a lone factor:

pt =
p₀(-t³+3t²-3t+1) +
p₁(3t³-6t²+3t) +
p₂(-3t³+3t²) +
p₃t³

And thus, we now have our basis functions, which happen to be Bernstein polynomials, for our cubic Bézier curve :)
If you have more questions - I just went live! I stream development of a game of mine, where I just so happen to be using Béziers for its level editor! Feel free to tune in, hang out, and chat about curves⁓
twitch.tv/acegikmo
This thread is now also available as a single post over at Medium, with some minor corrections and non-compressed .gifs 💞

medium.com/@Acegikmo/the-…
Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to Freya Holmér
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member and get exclusive features!

Premium member ($30.00/year)

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!