Pangram verdict · v3.3
We believe that this entire text is human-written.
AI likelihood · overall
HumanArticle text · 1,624 words · 1 segments analyzed
August 16, 2026 Improving on a timeless recipe The bezier curve is a staple of CAD and computer graphics. Like Bic pens, the design is decades old and they're everywhere. You'll often find them as the default or only choice in various illustration and animation tools. Conceived by Paul de Casteljau in 1959, and refined by Pierre Bézier in the 1960s at Renault, the enduring appeal of the bezier curve lies in its simplicity. While more sophisticated curves have been invented, and new ones continue to be proposed, these are limited to specific domains, like high-precision CAD or road design. In general use, the bezier stubbornly refuses to be dethroned, despite its shortcomings. Hence bezier curves are a piece of legacy tech we appear to be stuck with. As a software engineer, my question then is: can we make beziers better without invalidating all the tech built on and with them? The answer is yes. Lerp-a-derp Drawing a bezier curve is a surprisingly simple and linear process: Tip: All the diagrams in this post are fully interactive. Given a series of control points, we connect them with lines. We then run along those lines simultaneously, to produce new points, which can be connected again. This process is repeated until we are left with a single point, which lies on the curve. This construction makes beziers far more regular than they might first appear. The linear interpolations (aka lerps) can be summarized into a single compact formula, e.g. for 4 control points $ \left(A, B, C, D\right) $: The rule is simple: descending powers of $\left(1 - t\right)$, ascending powers of $t$, with coefficients taken from the n'th row of Pascal's triangle: For curves in 2D and 3D, the formula is applied to the individual X, Y or Z coordinates. While beziers can be constructed for any number of control points, the common practice is to only use cubic beziers with 4 control points. This is because the curve is only guaranteed to cross through the first and last control point, which makes higher degree beziers more difficult to shape. Larger curves are instead constructed by joining together multiple cubic bezier segments, with the tangents lined up to create a segmented curve that appears smooth: This is the cubic bezier spline, as commonly understood. The precision "pen tool" in most drawing apps then consists of drawing and editing the control points, rather than drawing curves directly. A Lie Told Everywhere Pen tools typically have a few different modes for the control points: Intuitively these represent various degrees of smoothness. Symmetric tangents are offered as the smoothest option, with some qualities of smoothness being lost as you relax the constraints. In reality this is completely wrong, and this is easy to demonstrate. Bezier curves can be split exactly, by reading off the new control points from the interpolation diagram: The left and right segments are 100% identical to the original curve, and always join up perfectly at the seam. Yet the tangents in the middle will be asymmetric except for one split near the middle. This can be confirmed using a curvature comb which represents the (inverse) radius of curvature at every point: The curvature comb remains continuous, with no jumps. This means that whether or not adjacent tangents are of equal length, i.e. symmetric, is completely irrelevant. Attempting to draw smooth and intuitive bezier curves this way is a fool's errand. A simple way to improve this is to treat the tangents as relative rather than absolute. e.g. We can make them proportional to the distance between the start and end of each segment: This spline is easier to edit, because as you move each curve point around, the adjacent segments naturally flex to get out of the way. There are far fewer cusps created this way. Editing the tangents remains the same. However if we plot curvature again, we can tell this isn't a great solution: Scaling tangents proportionally doesn't guarantee that curvature is preserved as you edit, nor does curvature remain continuous from one segment to the next. This also shows that offering users a curvature comb visualization as a "helpful tool" is really quite mean: adjusting the curvature on one end will also affect the other side, requiring repeated adjustments back and forth until it's close enough. Handle Carefully A much more effective strategy is to work with curvature directly. While this is a difficult problem in general, it turns out there are some surprising relationships here, which we can observe directly: Consider the curvature at the start of segment $A-B-C-D$. This is affected only by the positions of $A$, $B$ and $C$. Point $D$ can be moved freely if it's detached from $C$. Furthermore, because the tangent $A-B$ is horizontal, only the vertical position of $C$ matters. This is a result of the underlying linear interpolations, which end up cancelling out a lot of terms in the formulas. The curvature at $A$ is therefor only affected by the length of $A-B$, and the perpendicular distance from $C$ to $A-B$. The same applies to $D$ on the other side with $C-D$ and $B$. This isn't very useful by itself though. When we move a curve point ($A$ or $D$), typically the adjacent control point ($B$ or $C$) is moved as well to preserve the tangent. And when we turn a symmetric or asymmetric tangent, the adjacent tangent in the next segment is turned by the same angle, altering the curvature on that side. Still, this shows that preserving curvature is not by itself a crazy idea and can be done simply by scaling the tangents appropriately. The rules would be simple: When we move a curve point, we have to preserve the start and end curvature in the adjacent segments When we move a tangent, we have to preserve the curvature on the opposite end of the current segment, as well as on both sides of the adjacent segment This ought to produce an editing experience where the curve actually respects your intent. Except not quite: Moving curve points works great, but when turning a tangent, the length of that tangent is itself a poor representation of the user's intent. Small changes can cause huge shifts in curvature, which can cause the curve to jump around and explode unexpectedly as it tries to find a matching solution. Hence it's better to work with curvature handles instead, where the length corresponds directly to curvature: Unlike the curvature comb, the length of the handles is the non-inverted radius of curvature, which is the more natural choice. These handles are very stable and can be converted just-in-time to classic bezier control points, without needing to round-trip back and forth between the two representations. Helpfully, this also avoids numerical drift. Goldilocks To actually pull this off, we need to solve for the lengths $l_0$ and $l_1$ of the tangents, given the desired curvatures $k_0$ and $k_1$, the start/end points $A$ and $D$, and the unit-length tangents at the start/end. Given a curve $\gamma\left(t\right)$, we can express the unit tangent vector $\mathbf{T}\left(t\right)$ as the normalized derivative: This can be used to find the curvature vector $\mathbf{K}\left(t\right)$ via two vector cross products using the first and second derivative: The cross products ensure that $\mathbf{K}\left(t\right)$ is perpendicular to $\mathbf{T}\left(t\right)$, i.e. they extract the normal vector component of the middle term. Now we can solve for $\mathbf{K}\left(0\right) = k_0$ and $\mathbf{K}\left(1\right) = k_1$. After working through the math, we end up with a quadratic system of equations in $l_0$ and $l_1$: Where: This captures a few things: The sign of the curvature $k_i$ defines whether the curve turns clockwise or counterclockwise. When moving curve points around, the curve may be forced to flip, hence the $±$ is necessary, and both signs can change independently. The coupling between $l_0$ and $l_1$ is influenced only by $b$. If $b = 0$, then the two equations are independent and the problem is trivial to solve. This corresponds to the situation where the two tangents are parallel. The constant term $c_i$ is influenced only by the perpendicular distance $D - A$ (or $A - D$) to the tangent $\mathbf{T_i}$. This matches the earlier finding that only perpendicular distance affects curvature. Hence, the problem is reduced to finding the intersection of two double-parabolas, one horizontal and one vertical: The two sides of each double-parabola represent bending clockwise or counterclockwise. We have to solve 4 times, one for each sign combination $\left(+,+\right)$, $\left(+,-\right)$, $\left(-,+\right)$, $\left(-,-\right)$. To solve this system, we can rewrite either of the equations to isolate $l_1$ or $l_0$: Pick one, and square it to plug it into the other original equation as the $l_1^2$ or $l_0^2$ term. This produces a quartic equation in the other variable (resp. $l_0$ or $l_1$), which can be solved directly using the quartic formula. We can then compute the other $l_i$, either: Not all solutions of the quartic will be actual solutions to the system however, because of the squaring. So we have to double check that the original equations hold before accepting a solution for $\left(l_0, l_1\right)$. We also want to reject solutions where $l_0 < 0$ or $l_1 < 0$, because these represent situations where the tangents have been flipped by 180º. In most cases, there will only be one valid solution, and this works pretty well: For corner-type points, one or both $k_i$'s are infinite. This is straightforward to solve as the matching $l_i$ is zero and the other can be computed directly. Grouper and Snapper Unfortunately if there are multiple solutions, these each represent a different curve: Having the curve jump around as you edit it would be a very bad editing experience, but there is no obvious way to pick the right one.