Lemma
math, backwards
the hook · a few handles, a smooth path

How does a computer turn a few points into a smooth curve?

A designer drags four handles. A movie character gets a smooth cheek, a car gets a perfect hood, a letter gets its curve. The handles are not on the curve; they pull at it like magnets. Move one handle and only the part of the curve nearby changes — the rest sits still. One operation, applied recursively, is doing all of this. That operation is linear interpolation between two points.

Drag any handle in the widget below. Slide t across the bottom and watch the construction collapse layer by layer onto a single point — that point traces the curve.

Widget — Control points
P0P1P2P3B(t)
B(0.50) = (260, 105)
Drag any of P₀ … P₃. The dashed gray polygon is the control polygon; the green curve is the Bezier. Slide t from 0 to 1 and watch the orange / brown layers collapse one by one onto the green point. The curve is the trace of that final point as t sweeps the unit interval. Three lerps, each fed the result of the last — that's the entire algorithm.
the arc
1

Why not just connect the dots?

Imagine asking a computer for “a smooth curve passing through these five points.” A first attempt: fit a single polynomial. It works for two or three points; for five or more it oscillates wildly between them (the Runge phenomenon). Splines fix this by stitching local pieces together — but each piece still has to be defined. Bezier’s idea is different: don’t ask for a curve through the points; ask for one shaped by them. The points become handles, not anchors.

2

The two-point case — lerp

Between two points P0P₀ and P1P₁, the linear interpolation is lerp(P0,P1,t)=(1t)P0+tP1lerp(P₀, P₁, t) = (1−t)·P₀ + t·P₁. At t=0t = 0 you sit on P0P₀, at t=1t = 1 on P1P₁, and in between you trace the straight line. This is so simple it looks like nothing. But it is the only tool Bezier curves need.

# A point is a 2-tuple. Lerp is one line.
def lerp(a, b, t):
    return (a[0] + (b[0] - a[0]) * t,
            a[1] + (b[1] - a[1]) * t)

lerp((0, 0), (4, 2), 0.0)    # → (0, 0)
lerp((0, 0), (4, 2), 0.5)    # → (2, 1)
lerp((0, 0), (4, 2), 1.0)    # → (4, 2)
3

Recursive lerp — De Casteljau

With four P0,P1,P2,P3P₀, P₁, P₂, P₃, do this. Lerp every adjacent pair at tt to get three new points. Lerp those pairs to get two. Lerp those to get one. That last point is B(t)B(t), the curve at parameter tt. Each “layer” reduces the count by one; with n+1n+1 controls, you stop after nn layers. This is , and it is exactly equivalent to the polynomial form B(t)=(1t)3P0+3(1t)2tP1+3(1t)t2P2+t3P3B(t) = (1−t)³P₀ + 3(1−t)²t·P₁ + 3(1−t)t²·P₂ + t³P₃ — same numbers, kinder bookkeeping.

In the widget, each layer is drawn in its own color: the dashed gray polygon connects the original controls, orange the level-1 lerps, brown the level-2 lerps, and the final green dot is B(t)B(t). Sweep tt across the slider — the construction collapses, the green dot moves, and its trace is the curve. The curve is not drawn by a separate formula; it is the locus of recursion.

# De Casteljau: lerp every adjacent pair, then again, until 1 point remains.
def bezier(controls, t):
    pts = list(controls)
    while len(pts) > 1:
        pts = [lerp(pts[i], pts[i+1], t) for i in range(len(pts) - 1)]
    return pts[0]

# Cubic Bezier — four control points
P = [(0, 0), (1, 2), (3, 2), (4, 0)]
bezier(P, 0.0)   # → (0, 0)            (= P[0], starts at first)
bezier(P, 1.0)   # → (4, 0)            (= P[-1], ends at last)
bezier(P, 0.5)   # → (2.0, 1.5)         (midpoint by recursion)
4

What you can read off the picture

Four facts fall out without proof, just from staring at the construction.

  • Endpoints. At t=0t = 0 every lerp returns the left point, so B(0)=P0B(0) = P₀. Symmetrically B(1)=P3B(1) = P₃. The curve passes through the first and last control points.
  • Tangents at endpoints. The level-1 lerps near t=0t = 0 sit on segments P0P1P₀P₁; the curve emerges along that direction. So the curve leaves P0P₀ heading toward P1P₁, and arrives at P3P₃ along P2P3P₂P₃. Designers use this to “make two curves meet smoothly”: align their end-handles.
  • Convex hull. Every layer of lerps is a convex combination of the previous layer; the final point is a convex combination of the controls. So the curve lives inside the polygon’s convex hull and never escapes — useful for collision bounds and clipping.
  • The control polygon is not the curve. It bounds the curve, points along it, can be moved to drag the curve — but the curve sits inside the polygon, smoothed away from its corners.
# Bernstein form — algebraically equivalent to De Casteljau.
def bezier_bernstein(P, t):
    s = 1 - t
    bx = (s**3 * P[0][0] + 3*s*s*t * P[1][0]
        + 3*s*t*t * P[2][0] + t**3 * P[3][0])
    by = (s**3 * P[0][1] + 3*s*s*t * P[1][1]
        + 3*s*t*t * P[2][1] + t**3 * P[3][1])
    return (bx, by)

bezier_bernstein(P, 0.5)  # → (2.0, 1.5)   same answer, different bookkeeping
#
# B'(0) = 3(P[1] - P[0])  →  tangent at start points along P0→P1
# B'(1) = 3(P[3] - P[2])  →  tangent at end points along P2→P3
# A designer reads "the curve leans into the next handle" off these two facts.
5

Why every graphics stack ships this

The properties above are exactly what a tool needs. Local control — moving one handle changes only the nearby curve. Affine invariance — transform the controls, and the curve transforms the same way (rotate, scale, translate without re-evaluating the formula). Numerical stability — De Casteljau is just lerps, no high-degree polynomial cancellation. Composable — splice many cubic Beziers end-to-end with matching tangents and you get B-splines, the workhorse of CAD and animation.

Concretely: TrueType fonts use quadratic Beziers; PostScript and most modern fonts use cubic; SVG path data is a Bezier syntax with shorthand; Figma, Illustrator, Inkscape — all the same recursion at the bottom; Pixar’s smooth animation curves and the “ease-in-out” timing function in CSS are cubic Beziers picked by hand. One algorithm, four handles, an entire industry of curves.

The deeper bridge: Bezier curves consume the parametric-curves module. The image of the curve is the smooth path; the parametrization is tB(t)t ↦ B(t). Designers usually only see the image; the parametrization is what the renderer steps through to draw it.

now break it

Bezier’s “smooth” is a local claim, not a global one. A cubic Bezier whose control polygon makes a sharp loop will produce a self-intersecting curve — still smooth in the differential sense (B’(t) is continuous), but visually pathological. Try the widget with P0=(60,80),P1=(440,240),P2=(60,240),P3=(440,80)P₀ = (60, 80), P₁ = (440, 240), P₂ = (60, 240), P₃ = (440, 80): a self-crossing Z. Designers’ “smooth” and differential geometry’s “smooth” diverge here, and the four-handle abstraction does nothing to warn you.

Bezier is lerp, recursively. One operation between two points, applied to adjacent pairs, then to the new pairs, then again. Move a handle and the lerps follow; the curve follows the lerps.

exercises · 손으로 풀기
1lerp by handno calculator

Compute lerp((0,0),(4,2),0.25)lerp((0, 0), (4, 2), 0.25). Then lerp((0,0),(4,2),0.75)lerp((0, 0), (4, 2), 0.75). Sketch both points between the endpoints.

2midpoint of a cubicno calculator

For the cubic Bezier with controls P=[(0,0),(1,2),(3,2),(4,0)]P = [(0, 0), (1, 2), (3, 2), (4, 0)], compute B(0.5)B(0.5) by De Casteljau. Show every layer.

3tangents at endpoints

Why does the cubic Bezier curve start in the direction of P1P0P₁ − P₀ and end in the direction of P3P2P₃ − P₂? Argue geometrically from De Casteljau, then confirm by computing B(0)B'(0) from the polynomial form.

4polygon vs curve

The control polygon and the Bezier curve have the same first and last point and roughly the same shape. List three ways they differ. Use the widget to construct an example where the differences are obvious.

why this isn't taught this way

Computer-graphics texts usually present Bezier curves through their Bernstein basis formula — B(t)=Σbi,n(t)PiB(t) = Σ b_i,n(t) · P_i — a polynomial sum the reader has no reason to trust. Lemma starts at the other end: lerp, the one operation a designer already knows. Three lerps, recursively, derive the Bernstein form. Industry uses the formula; understanding starts at the recursion. The Bernstein basis is a consequence, not a starting point.

glossary · used on this page · 3
lerp·lerp
Linear interpolation between two values: `lerp(a, b, t) = (1 − t) · a + t · b`. At `t = 0` you get `a`, at `t = 1` you get `b`, in between you trace a straight line. Works on numbers, points, colors, transformations — anything that supports addition and scaling. The single primitive on which Bezier curves, animation tweening, gradient shading, and most computer-graphics interpolation are built.
control point·제어점
One of the handles that defines a Bezier curve. The curve starts at the first control point, ends at the last, and bends toward the inner ones without touching them. Move a control point and only the part of the curve nearest it changes — that _local control_ is the property a designer relies on. The polygon connecting consecutive control points is called the control polygon; it bounds the curve (Bezier curves lie inside the convex hull of their controls) but is never the curve itself.
De Casteljau's algorithm·드 카스텔조 알고리즘
A recursive way to evaluate a Bezier curve at a parameter `t`. Given `n+1` control points, lerp every adjacent pair at `t` to get `n` new points; lerp those to get `n−1`; repeat until one point remains — that point is `B(t)`. Numerically stable, geometrically transparent, no Bernstein-coefficient bookkeeping, and the intermediate "layers" double as the construction lines a designer can see in any vector tool. Mathematically equivalent to the Bernstein-polynomial form, but kinder to hand.