Like most designers, I work with Bézier curves all the time. When asked about their merits compared to pixel images, I confidently say something about how they’re defined mathematically instead of being stored as grids of colored squares. The benefits:
If a particularly inquisitive friend asks how exactly that works, I might give a simplified example. Thinking back to grade-school math, imagine graphing the function y=x over an x-range of 0 to 10 and a y-range of 0 to 10. We of course end up with and upward-and-to-the-right diagonal line. If we suddenly want to scale that line up 10×, no problem—we just graph the same function over an x-range of 0 to 100 and a y-range of 0 to 100. Knowing the defining function lets us interpolate infinitely many points on the curve, basically giving us infinite resolution.
On the other hand, if we just took a screenshot of the 10-by-10 line, dropped it into Photoshop, and scaled it up 10×, we would see a jagged staircase effect. In this case, the only data we have are pixels, and enlargement can make these individual pixels visible to the naked eye.
But this explanation always seemed disconnected from the glowing points omnipresent in vector editing software. It’s easy to vaguely understand that the a vector will hug these points, but the underlying math has always been a mystery to me.
This is a deep-dive on how Bézier curves are actually constructed and stored.
Let’s start with the simplest non-linear Bézier curve: a quadratic Bézier. The order of a Bézier is defined by the number of points that define it (specifically, it’s the number of control points minus one). Quadratic Bézier curves have three defining points:
We can consider two different kinds of control points:
The backbone of Bézier curves is surprisingly unsexy linear interpolation. For quadratic Béziers, we can start by plotting the line segments that connect:
P1) to Control Point 1 (P2)P2) to Anchor Point 2 (P3)Note that, in some cases, the order of these points is important.
Now, we need to introduce a new concept: intermediate points that travel along each of the two interpolated line segments:
I1 starts at P1 at t=0 and stops at P2 at t=1I2 starts at P2 at t=0 and stops at P3 at t=1I1 and I2 move at constant rates so that, at t=0.5, they’re both at the midpoint of their respective line segment.
Now, at any given time, we can draw a line segment connecting I1 and I2:
As with I1 and I2, we need to imagine a point that travels across this line segment from t=0 to t=1. We’ll call it Bézier Point 1 (B1) since it ultimately defines our final curve. The length of the line segment B1 follows changes, so—unlike I1 and I2—B1 doesn’t move at a constant rate. Nonetheless, it always specifies the portion of the line segment’s length that B1 has traversed. For example, at t=0.3, B1 has traversed exactly 30% of the way between I1 at t=0.3 and I2 at t=0.3. The path traced by B1 is the Bézier curve unique to our three initial points.
Higher-order Bézier curves work the same way but need extra rounds of interpolation. For example, cubic Béziers (which are often used for motion curves in CSS animations) can be defined by four points:
P1 (anchor point)P2 (control point)P3 (control point)P4 (anchor point)Now, the scatterplot is starting to resemble the typical anchor points with handles we see in vector editing software. We start by connecting the points—in order—with three line segments:
P1 to P2P2 to P3P3 to P4Then, intermediate points I1, I2, and I3, which move along their respective line segments constantly from t=0 to t=1, basically act the same way a quadratic Bézier’s P1, P2, and P3 do. The math always boils down to layers of linear interpolation.