Search code examples
bezierinkscapecubic-bezier

Algorithm behind Inkscape's auto-smooth nodes


I am generating smooth curves by interpolating (lots of) points. I want to have local support (i.e. only few points determine the smooth curve locally), so I do not want to use a classical interpolation spline. Bezier curves to me would be a natural solution and Inkscape's auto-smooth nodes (http://tavmjong.free.fr/INKSCAPE/MANUAL/html/Paths-Editing.html#Paths-Node-AutoSmooth) do pretty well what I want to have. But I have trouble finding the implementation in the source or some reference to the underlying algorithm.

Is anybody here aware of the algorithm or familiar enough with Inkscape's source so they can point me in the right direction?

For context: I am calculating a smooth path for a pen plotter but can not wait to have all supporting points available.


Solution

  • The code is here and I've implemented a version in Python using the svgpathtools library in a gist

    Here is a diagram showing the method.

    Given three points a, b, and c where b is auto-smooth and b has two control points u and v, then:

    • Let x be a unit vector perpendicular to the the angle bisector of ∠abc
    • u = b - x * 1/3|ba|
    • v = b + x * 1/3|bc|

    As far as I know, there is nothing special about the constant 1/3 and you could vary it to have larger or smaller curvature.

    UPDATE: while watching this excellent video I re-encountered this 1/3 constant and indeed it is special and comes from a Hermite spline. It is briefly mentioned on the Cubic Hermite Spline Wikipedia page. Editing the auto-smooth control nodes acts to edit the Hermite spline velocity vectors.