[HN Gopher] New Bezier curves for vector graphics
___________________________________________________________________
New Bezier curves for vector graphics
Author : ad8e
Score : 125 points
Date : 2023-09-10 15:56 UTC (7 hours ago)
(HTM) web link (ad8e.pages.dev)
(TXT) w3m dump (ad8e.pages.dev)
| bobbylarrybobby wrote:
| Are Bezier curves with handles "worth it"? I've always found the
| easiest method for drawing curves to be, simply, "give me the
| (cubic) spline curve that goes through these points". You place
| your points and continuity conditions determine the cubic, as
| described in https://mathworld.wolfram.com/CubicSpline.html .
| Kenji wrote:
| [dead]
| crazygringo wrote:
| That's exactly what I've always been curious about!
|
| It seems vastly more intuitive to place points rather than
| adjust handles. (And set directions for endpoints if the curve
| is open.)
|
| And obviously a practical tool will provide the capability to
| join separate cubic splines at sharp angles.
|
| Does anyone know of a GUI drawing tool based on this? I've
| always wanted to experiment with it. Because I've always wanted
| to either confirm that it's a great idea that we should all be
| using instead of beziers, or else discover if there's an
| immediately obvious reason once you try it out that it's a
| terrible idea.
| egypturnash wrote:
| "I don't know of a reasonable way to guess the right location."
|
| 1. Drag curve handles out to 1/3 of the length of the curve
| segment they control.
|
| 2. Eschew s-curves between two control points.
|
| 3. Don't turn more than about 90o between two control points.
|
| I learnt this about a year into what is now a 23-year career as
| an Illustrator artist. It has served me well. You will note that
| the first interactive example on this page is asking you to
| violate rule 2.
|
| "Beziers can't represent circles. If you try to approximate one
| by hand, it'll look lopsided."
|
| If you try to draw a circle by hand, it'll look lopsided too. Any
| pro traditional artist will have a compass and a few circle
| templates in their kit. In Illustrator there's an ellipse tool
| one keypress away. I've been drawing at a pro level for about
| thirty years and while I can probably pick up a pencil and draw a
| better circle in a couple quick arm motions than you can in a
| bunch of little sketchy attempts, they're still nowhere near
| perfect, and they don't _need_ to be.
|
| I also draw about 90% of my paths with the Pencil tool, which
| just abstracts worrying all of this way. Unless you are doing
| very geometric work, or require the absolute minimum possible
| number of points, I feel that using the Pen tool to draw
| everything is about as sensible as writing a program entirely in
| assembly language. And if I _do_ need to work under a tight point
| count constraint, then I will _still_ draw it with the Pencil,
| then pull out Astute 's Smart Point Removal tool, which does a
| _great_ job of optimizing the heck out of my paths, much better
| than Adobe 's tools for this.
| raphlinus wrote:
| I can perhaps refine (1) and provide some insight in support of
| (2).
|
| It does make intuitive sense for handles to be 1/3 of the
| length of the curve, as that makes the "speed" close to
| constant, but this is not the smoothest possible choice in
| general. In particular, it's not the best approximation to a
| circular arc, which by most reasonable definitions is the
| smoothest possible curve. I did the math[1] and found that
| there's a parabola around each endpoint that _does_ result in
| an accurate arc approximation, and in fact may be easier to
| apply as it doesn 't move around as the length of the curve
| changes. Rather, each of the parabolas can be applied
| independently.
|
| Evidence in favor of this is O(n^5) accuracy scaling to
| approximate Euler spirals (which are also a good candidate for
| "smoothest possible curve" depending on the way you define
| that). I suspect, but haven't yet demonstrated, that there's
| some variational sense in which this choice is optimum, or at
| least to a first order approximation.
|
| You can think of cubic Beziers as forming a four-dimensional
| parameter space (the parameters can be accounted as the lengths
| and angles of the control handles; in this scheme, the
| positions of the endpoints are not counted). By applying a rule
| such as 1/3 arc length, or falling on a parabola, that reduces
| it to a two-dimensional space (same dimensionality as quadratic
| Beziers, Euler spirals, and sections of rectangular elastica).
| I think two dimensions is too few, as it doesn't give you the
| ability to easily form superellipse shapes, a particular
| strength of cubic Beziers and quite handy for font design, as
| superellipse is extremely common in fonts. I think there may be
| some value in exploring a three-dimensional parameter space
| (which, among other things, is the count for general elastica)
| and have some ideas.
|
| As for (2), the problem is that for s-shaped curves, cubic
| Beziers tend to put curvature maxima _near_ but not exactly
| _on_ endpoints. Since the curvature maximum is visually
| salient, you do better subdividing your curves so you can place
| them at joins. Other curve families, notably those based on
| elastica and Euler spirals, don 't have this problem.
|
| [1]: https://raphlinus.github.io/curves/2021/02/19/parallel-
| curve...
| karaterobot wrote:
| I think what you've done is mastered an unintuitive (or even
| counterintuitive) system. That's well and good, but it doesn't
| mean the system shouldn't be improved. It would make life no
| worse for you, and better for people with less experience, less
| time to experiment.
| cush wrote:
| I don't think they're implying it takes 21 years to learn.
| I'm inexperienced and learned how to accurately follow paths
| with bezier curves using the same technique after watching a
| 10 minute Burt Munroy tutorial.
| egypturnash wrote:
| Correct. I have certainly learnt a _ton_ more about how to
| manipulate vector art in the intervening years, and the set
| of tools I have available has expanded a lot - Adobe 's
| added a lot of tools to Illustrator, and so has the
| Illustrator plugin ecosystem. But those three simple rules
| did a _lot_ to make my Illustrator practice a lot faster.
| spoiler wrote:
| > I feel that using the Pen tool to draw everything is about as
| sensible as writing a program entirely in assembly language.
|
| As someone who's only ever used the pen tool, I feel mildly
| attacked!
|
| Jokes aside, I think I agree with you if you have a tablet. I
| used to draw with a mouse back then, so I'd basically sketch on
| paper, take a picture or scan it, then use my mouse to pen over
| it. Sometimes I'd skip the sketching/importing steps, depending
| on what I'd work on.
|
| Later when I could afford a tablet, I mostly left
| Illustrator/Inkskape behind in favour of just using Krita for
| most things. However, if I'm making a vector illustration
| today, I still use the pen tool... and the mouse, even if I
| have the tablet. If I were to work on something complex enough,
| I'd probably sketch it in Krita though, and then use the
| good'ol pen and mouse...
|
| I'm by no means a professional artist, just do this as a hobby
| though. So, if my workflows outlined here have mortified you;
| apologies for that.
| egypturnash wrote:
| The workflow you outline is where I started! It's not one I'd
| want to use any more, now that I can casually make
| Illustrator automatically do a _lot_ of work for me, then
| come back in and refine a few places manually. But it was a
| good place to begin.
|
| https://egypt.urnash.com/illustratorbook/
| delta_p_delta_x wrote:
| > Beziers can't represent circles. If you try to approximate one
| by hand, it'll look lopsided.
|
| Many graphics algorithms (vector operations: scale, translate,
| rotate; raster operations like rasterisation and interpolation)
| specialise for straight lines (and hence also triangles), Bezier
| curves, circles, etc separately, rather than forcing everything
| to be a Bezier curve.
| slimsag wrote:
| "Beziers can't represent circles" is not exactly wrong, but is
| not really the full picture.
|
| Often you don't need to _represent_ a circle. TrueType fonts
| (quadratics) and OpenType fonts (cubics) can't mathmatically
| _represent_ a circle, either, but does that mean no font has
| circles in it? Sometimes an approximation is pretty damn good.
|
| Also conics (rational quadratic Beziers), which Microsoft has a
| surprisingly good article on[0], can represent circles.
|
| [0] https://learn.microsoft.com/en-us/xamarin/xamarin-
| forms/user...
| cormullion wrote:
| Fortunately fonts usually don't contain perfect circles
| anyway, because the designer will optically correct any
| circles so that they don't appear to bulge. Kabel is the
| closest font I found with circular formas; LineTo's Circular
| is also quite close but slightly taller than wider.
| mkl wrote:
| Fonts are supposed to contain perfect circles; try
| searching for "circle" in a Unicode character map. They
| only don't in practice because quadratic and cubic Bezier
| splines can't do them.
| TheRealPomax wrote:
| And they don't have to. The approximation of a circle
| with a bunch of cubic curves is _so accurate_ [1] that
| you 'd need to print a huge circle and then sit there
| with a measuring tape to be able to even tell it's not a
| perfect circle. Which is why "you can't draw a circle
| with Bezier curves" is only a mathematical "problem",
| it's not an _actual_ problem.
|
| [1] https://pomax.github.io/bezierinfo/#circles_cubic
| ad8e wrote:
| It's a UI problem, not a mathematical problem. No set of
| curves can represent everything exactly, but they all can
| get close. The goal is just to make it easy to get close.
|
| The computer can produce a near-perfect circle with
| Beziers for each 1/4 arc, and near-perfect circles are
| usually good enough. It's just inconvenient. It's also
| hard to manipulate the generated circle; the user might
| have a clear image of his head of the changed circle he
| wants, but pushing the control points to get there is not
| easy.
|
| The mathematical "axioms" in the article are only
| attempting to provide a clean interface, so that the user
| can easily translate what is in his head to what the
| program creates. The circle axiom says, "The user often
| wants a circle, and also expects a circle, so let's
| produce the expected circle." There's no other
| mathematical purity involved.
| bobajeff wrote:
| The guy from the mach engine has also talked about issues dealing
| with Bezier curves and came up with a interesting set a
| primitives: Triangles, quadratic curves and semi-circles.
|
| Mostly this is make it easier to do vector graphics on a gpu,
| which is why I'm interested in it, but I think it might be easier
| to understand.
| tantalor wrote:
| "New"?
| Nycto wrote:
| Obligatory links for anyone that is interested in learning more
| about Bezier curves:
|
| https://pomax.github.io/bezierinfo/
|
| https://pomax.github.io/bezierjs/
|
| https://github.com/Pomax/bezierjs
| AlphaCerium wrote:
| Might I also add: https://youtu.be/aVwxzDHniEw?feature=shared
| Which works through them from first principles with beautiful
| animations.
| dang wrote:
| This is a nice post but not a valid Show HN - please see
| https://news.ycombinator.com/showhn.html.
|
| I've taken "Show HN" out of the title now.
| CrimsonCape wrote:
| Do you have any publicly available code on github?
| ad8e wrote:
| The source code is visible with Ctrl+U, I didn't minimize
| anything. The g9 use is pretty neat. It definitely deserves the
| shout-out I gave it.
|
| I just now uploaded a worse C++ desktop version with saving and
| loading: https://github.com/ad8e/local-curves This desktop
| version is 5 years old. I think the web version is better. This
| github repo is only interesting if you want to copy code from
| it; it's not practical as a drawing tool.
| CrimsonCape wrote:
| Ok thanks. I will possibly try to port to SkiaSharp in the
| future to learn how your code works.
| TheRealPomax wrote:
| It looks like the conclusion is "let's use rational Bezier curves
| instead of plain Bezier curves", in which case: you can, you just
| have more parameters to tweak now. Also calling this "new" is a
| bit disingenous given that rational Beziers have been around half
| a century now. They're useful, but if you only look at Bezier
| curves from the tooling side of things, you're going to miss the
| reason why we use them so much. And the biggest mistake in design
| software is having tools that actually let you work with the
| datatypes that your final product is going to end up using. Need
| a circle? Draw a circle based on a center point and a radius.
| Good tooling won't surface that fact that it's going to end up
| being a Bezier curve, it just lets you design with the primitives
| you need, and will take care of the conversion as needed when you
| export it to whatever format your deliverable needs to be.
|
| Making people draw Bezier curves just because "the file format
| uses those" is by far the bigger problem here.
| javajosh wrote:
| beautifully made. However I think one's intuition for where the
| control points go and what they do are very clear if you've ever
| taken calculus. The line segments control the direction and
| magnitude of the tangent to the curve at that position. If you
| understand that, then it makes the motivating problem go away,
| and all the challenge problems are easy to solve.
| pavlov wrote:
| Interactive curves are primarily meant to be used by designers.
| They are a tool. When the tool is not intuitive, it's not
| really a solution to say "designers should just take calculus
| and it makes the problem go away."
| ad8e wrote:
| It's not as easy to visualize the tangent magnitude as you are
| suggesting, because the time parametrization makes the
| calculation fail - the curve doesn't travel forward at a
| constant rate. This is best seen with the second example: If
| the left handle is fully extended and the right handle is 0,
| the Bezier curve looks almost exactly the same as when the
| handles are reversed. Here's a picture:
| https://i.imgur.com/WkanN1G.png
|
| The handle varies from 0 to full-strength, but the magnitude of
| the tangent vector stays constant. This means the handle
| doesn't decide the magnitude. Tracing the path in your head to
| visualize the changing tangent vectors would mean visualizing a
| competition between t^2, (1-t)^2t, and (1-t)^3, which I find
| difficult, even with some calculus knowledge.
| [deleted]
| unconed wrote:
| This isn't true, and is obvious when you try to split a bezier
| without distorting its shape.
|
| As a bezier is just repeated interpolations, the tangents and
| their lengths can be derived from the intermediate
| interpolations [1]. This means that if you split a bezier near
| an existing control point, the new point will have wildly
| unbalanced tangents on both sides, and yet, connect into the
| exact same cubic curve.
|
| So both your intuition and your confidence in it are... wrong.
|
| [1] https://i.stack.imgur.com/I9wKC.png
| raphlinus wrote:
| The goals look quite similar to my hyperbezier explorations.
| There's an online demo of the first draft[1], and a Zulip thread
| on some progress toward a second draft[2]. The tl;dr is that I
| think I have the mathematics of the curve family, but I haven't
| finished the mapping between control points and the parameters of
| the curve family.
|
| Both drafts have (exact) Euler spirals inside their parameter
| space, and thus circular arcs as well. I think that's a good
| criterion for a Bezier successor.
|
| It's on the back burner for now, but I hope to get back to it,
| and am open to collaboration.
|
| [1]: https://www.cmyr.net/blog/hyperbezier.html
|
| [2]:
| https://xi.zulipchat.com/#narrow/stream/260979-kurbo/topic/H...
| butz wrote:
| Just trying to align curves to targets was fun. Someone should
| build a whole game on this idea.
| slimsag wrote:
| https://bezier.method.ac/
| slimsag wrote:
| Cool to see others working on this problem. I hope more people
| do.
|
| Funnily I've seen a lot of programmers and math folks who express
| how truly, genuinely beautiful Beziers and the math behind them
| are. But I've never met an artist or graphic designer who didn't
| express some deep frustration at Bezier controls and how hard
| they are to work with.
|
| There are even games[0] which make a mockery out of how hard
| Bezier controls are to use, where the game is purely using the
| controls.
|
| Controls are just one side of the problem, in my view; the other
| side is that cubics are terrible for GPUs, they don't understand
| them - and I believe many of the best 2D graphics libraries today
| are not even fully GPU accelerated, e.g. Skia. There are folks
| working on compute shader-based approaches, where we try to shoe-
| horn this CPU-focused algorithm into GPUs and pray - but it still
| isn't really suitable.
|
| The controls suck for artists, and the math sucks for GPUs. This
| is only true of cubics, if you restrict yourself to quadratics
| (although that brings other challenges), both the control issue
| goes away (you can just click+drag the curve!) and the
| performance issue goes away (quadratics are triangles, GPUs love
| them)
|
| That's the summary of the talk[1] I gave at SYCL'22. In that
| talk, I didn't have time to present the downsides of my solution
| (which are real!) so if you watch it please keep that in mind -
| the talk is about the problem statement, not a solution. We are
| exploring a different solution today than what was presented in
| that talk. My overall point in there, though, is a solid one:
| vector graphics as they exist today suck for artists and GPUs
| alike.
|
| The only reason we stick with vector graphics in their current
| form is because of SVG & compatibility with existing tooling. But
| isn't it crazy? We have new bitmap image formats all the time,
| and so few vector graphics formats.
|
| In Mach engine[2] we're continuing to explore this space, end-to-
| end, from author tooling -> format -> rendering. I'm not claiming
| we have a perfect solution, we don't, but we're at least thinking
| about this problem. Kudos to the authors of this article for
| thinking about this space as well.
|
| [0] https://bezier.method.ac/
|
| [1] https://www.youtube.com/watch?v=QTybQ-5MlrE
|
| [2] https://machengine.org
| CharlesW wrote:
| > _But I 've never met an artist or graphic designer who didn't
| express some deep frustration at Bezier controls and how hard
| they are to work with._
|
| That surprises me, because Illustrator (especially earlier
| versions) is all about Bezier curves, and in my experience it
| doesn't take long before you start to "think" like the Pen
| tool. I don't recall working with an artist who couldn't intuit
| how they worked after creating with them for a few weeks.
| crazygringo wrote:
| You can easily learn how to use them.
|
| That doesn't mean they don't stop being frustrating.
|
| I will commonly wish there was a method to change a curve in
| a single drag in some particular situation, rather than 20
| drags of fiddling with beziers, trying to figure out if
| adding another control point is necessary or redundant.
|
| Just because you figure out the intuition behind them doesn't
| turn them into an _efficient_ way of achieving results.
| Because the intuition of beziers translates poorly to our
| innate human /artistic intuitions of curves.
| pavlov wrote:
| Postscript used cubic Beziers, but TrueType, specified some ten
| years later by Apple with the learnings from practical use of
| Postscript on Macs, opted to only support quadratics instead.
|
| Donald E. Knuth seems to think pretty highly of this decision:
|
| _"The quadratic has the great advantage that there 's a real
| cheap way to render them. You can make hardware to draw a
| quadratic spline lickety-split. It's all Greek mathematics, the
| conic sections. You can describe a quadratic spline by a
| quadratic equation (x, y) so that the value of f(x, y) is
| positive on one side of the curve and negative on the other
| side. And then you can just follow along pixel by pixel, and
| when x changes by one and y changes by one, you can see which
| way to move to draw the curve in the optimal way. And the
| mathematics is really simple for a quadratic. The corresponding
| thing for a cubic is six times as complicated, and it has extra
| very strange effects in it because cubic curves can have cusps
| in them that are hidden. They can have places where the
| function will be plus on both sides of the cubic, instead of
| plus on one side and minus on the other._
|
| _"The algorithm that 's like the quadratic one, but for
| cubics, turns out that you can be in something that looks like
| a very innocuous curve, but mathematically you're passing a
| singular point. That's sort of like a dividing by zero even
| though it doesn't look like there's any reason to do so. The
| bottom line is that the quadratic curves that TrueType uses
| allow extremely fast hardware implementations, in parallel."_
|
| https://lists.nongnu.org/archive/html/freetype-devel/2000-01...
| vidarh wrote:
| And then OpenType added cubic bezier back in.... by embedding
| postscript font definitions.... Before they went one better
| and added support for embedding _SVG_ for emojis.
|
| (I ported a tiny TrueType renderer from C to Ruby, and looked
| at what it'd take to add OpenType support, since OpenType
| uses the same container format; font file formats look like
| they were designed by a drunk student as a prank)
| TheRealPomax wrote:
| those are both Bezier curves. They're just second vs. first
| order Bezier curves, but all the same math applies, and
| polybeziers are _so_ much harder to work with when they 're
| quadratic instead of cubic, it's not even funny.
| slimsag wrote:
| Wow, I didn't know Knuth said that. I would've been 7 years
| old at the time - wild.
| pmcjones wrote:
| Knuth has been saying interesting things for a very long
| time. He began _The Art of Computer Programming_ project in
| 1962.
| jheriko wrote:
| good work. i've always found bezier curves impractical and
| overrated, using standard polynomial interpolations or more
| easily understood variants.
___________________________________________________________________
(page generated 2023-09-10 23:00 UTC)