Join the discussion

Write your take first — we'll ask for email only when you're ready to publish.

  • Hacker News
  • I find bezier curbs sexy, well-rounded, smart, and attractive. They are awesome and this is, by extension, all of those things, too! We need more bezier curbs in this world.
  • Illustrations in the article are indeed precious teaching material
  • Is it bad that I don't understand this after reading it? I'm not even sure why "lie" he's referring to about bezier curves.
  • The author was having a little fun calling it a “lie”, it’s more like a popular simplification. The question is how to join Bézier curves smoothly, and it’s fairly common for people to join them by matching the velocity, which means if you join two cubic segments (for example) with control points [a,b,c,d] and [d,e,f,g] where you’re joining at point d, then setting d-c == e-d, which puts c,d,e in a line with d as the midpoint, will connect the two curves smoothly. Lots of Bézier curve editing software will have a mode that enforces symmetric control points around the join point. The problem, or “lie”, is that this symmetric strategy doesn’t match the 2nd derivative, so there can be an abrupt change in curvature at point d. You can have a smoother join by adding constraints like curvature or 2nd or 3rd derivative matching, and that’s what the article goes into - one way of achieving smoother matches.

    This WP entry mentions several other alternatives to smooth joins besides matching curvature:

    https://en.wikipedia.org/wiki/Composite_B%C3%A9zier_curve#Sm...

  • The "lie" is that some Bézier-spline drawing programs let you restrict on-curve points to a "symmetric" configuration where the control points are at an equal distance on opposite sides of the on-curve point, but this doesn't necessarily make the curve itself more symmetric or more smooth. The proposed alternative is to control the bend radius instead, and ensure that the curve bends the same on both sides.
  • The thing is, the problematic curves often violate the rules put forward as best practices:

    - place nodes at extrema (top/bottom, left/right)

    - place nodes at points of inflection (middle of an _S_ curve)

    - where possible/appropriate observe the "rule of 30" and place off-curve nodes not quote one-third of the way towards the other on-curve node

    If one expected (or enforced) those rules, does the problem/math become easier?

  • Most of those rules are copes, really.

    Placing points at X/Y extremes is by itself useless because beziers are rotation invariant. i.e. If that's the best place for the control points, then by the same argument if you rotated the curve by 45° the points would need to be on diagonal extremes. It's only useful with typography where many letters are oval. IIRC this rule originated because buggy rendering code assumed the curve would never extend beyond the XY bounding box of the control points.

    Placing nodes at inflection points is actually a bad idea because there are very few configurations where curvature remains continuous. It's better to construct S bends with the inflection point in the middle, because then you always get a smooth transition.

    Picking a specific spacing between control points makes it more likely that equal tangents represent approximately the same curvature on both sides, but it's not guaranteed either.

  • This is very fun and well done, great interactive illustrations, and I love the deep dive into curvature.

    I have to wonder - if you want smooth joins, why not use uniform B-splines instead of Bézier curves? With B-splines you don’t have to set constraints or compute curvature, it’s built in. What are the reasons to prefer Bézier?

    There’s an old 1985 tech report by Tony DeRose (formerly of Pixar Research) that categorized the different ways to smoothly join curves - "Geometric Continuity: A Parametrization Independent Measure of Continuity for Computer Aided Geometric Design.”

    That paper has a simple constraint formula for matching curvature between cubic Béziers, one that has a couple degrees of freedom. It’s the “G2 (curvature continuity)” formula mentioned on Wikipedia here: https://en.wikipedia.org/wiki/Composite_B%C3%A9zier_curve#Sm.... It’d be interesting to know whether that somehow works out to be mathematically equivalent to this post’s technique or not.

  • As the post says, beziers are everywhere so we are stuck with them. It's worth trying to improve them for that reason alone.

    Additionally B-splines (like Catmull-Rom) have the issue that moving one point affects a larger area of the spline than an equivalent bezier. The local control of beziers makes them more desirable for precise illustration.

    As for the formula you cited, it tells you where to put the control point for continuity in function of two scalars, but those scalars don't directly map to intuitive controls. It also doesn't help when moving a curve point while preserving curvature on both sides because it only tells you one side in function of the other. I.e. continuity of curvature is a weaker constraint than having the desired curvature.

    I initially experimented with something similar but found that numerical drift would steadily accumulate during interactive editing. The post shows this with the last example before curvature handles: rotating the tangents there preserves curvature continuity but the curve tends to blow up for certain angles, because the tangent is a poor proxy for indicating desired curvature.

  • As someone who has spent a lot of my life editing bezier curves, this is really fantastic.

    The one sticking point is instability in the middle of s curves which seems difficult. We're getting better control for every fully convex or non-convex path in exchange for chaos at the boundary between the two. I wonder if incorporating some other error term of the curvature in those regions might help, perhaps guaranteeing that the curvature derivatives are close to continuous whenever the curvatures themselves get too small?

    One other thought is that you could use a saturating function of the tangent circle radius so that 0 curvature points don't have to have their control points go to infinity, perhaps making the saturation point a function of the distance to the nearby nodes to keep the scale reasonable.

  • >"The linear interpolations (aka lerps) can be summarized into a single compact formula, e.g. for 4 control points (A,B,C,D):

    γ(t)=A⋅(1−t)^3+B⋅3(1−t)^2⋅t+C⋅3(1−t)t^2+D⋅t^3

    The rule is simple: descending powers of (1−t), ascending powers of t, with coefficients taken from the n'th row of Pascal's triangle.

    I've never seen the connection between the equation for Bezier Curves (more specifically the linear equations of curves with N control points aka "binding points" / "points of stability" / "fixed points" / "immovable points", etc.) and Pascal's Triangle before!

    Brilliant!

    Great article, too!

  • This comes from the binomial expansion of (X+y)^n, where X^k y^(n-k) has coefficient (n choose k). This is since you "choose" X in K of the (X+y)'s (in the Bezier case it's kind of writing (t+(1-t))^n, the abcd are to not make it equal to 1).

    The choice function is also exactly the same as the pascal triangle!

  • Quick update:

    When I said:

    "(more specifically the linear equations of curves with N control points aka "binding points" / "points of stability" / "fixed points" / "immovable points", etc.)" -- there's a terminology mix-up here -- the control points (A, B, C, D) are (obviously) variable / flexible in nature, but the values from Pascal's Triangle are (obviously!) bound/stable/fixed to their respective row!

    So that's what I meant to say...

    So my apologies for having messed-up the terminology there!

    (You know what I meant! :-) )

    Anyway, some very interesting responses and connections! Thanks to everyone who responded!

  • If you like that, then try this.

    Take a row of pascal's triangle, add a zero in front (shift it to the right by one place), and divide it by the row below it.

        0 1  4  6 4 1 /
        1 5 10 10 5 1
        = ...
    
    From this you can prove that a linear bezier line (of any degree) must have equally spaced control points.
  • What an amazing resource.

    I’ve been building a vector editor that by default draws shapes with smooth curvature and shows the comb. [1] In addition to the four point types mentioned in the article, you get a new “curve” point type. I’ve also been making a font editor with the same drawing capability. [2]

    Both are free static web apps that use local storage and have import/export capability for SVG files (and OTF files for the font editor).

    [1] https://svg.a10z.co/editor

    [2] https://svg.a10z.co/font

  • I shouldn’t tell you this, cause I’m also working on a font editor, but I’d consider looking into Raph Levien’s Hyperbezier work
  • Well that’s wild because I had a disagreement with beziers recently and did a similar thing! [1] albeit with more madness and less polish. Driven by the a/s/d/f keys with find edges snap to reference images and curve fitting to construction geometry.

    Feel I should also call out Freyr’s videos for anyone who has missed them - continuity of splines [2] and the beauty of Bézier curves [3]

    [1] https://gadgetoid.github.io/asdf

    [2] https://youtu.be/jvPPXbo87ds

    [3] https://youtu.be/aVwxzDHniEw

  • As another comment mentioned, Raph Levien has a few words to say on the topic of improving Bezier curves.

    Simplifying Bézier paths (2023) https://raphlinus.github.io/curves/2023/04/18/bezpath-simpli...

    Parallel curves of cubic Béziers (2022) https://raphlinus.github.io/curves/2022/09/09/parallel-bezie...

    Fitting cubic Bézier curves (2021) https://raphlinus.github.io/curves/2021/03/11/bezier-fitting...

  • And also an amazing page on Béziers https://pomax.github.io/bezierinfo/