How does inkscape calculate the coordinates for control points for "smooth edges"?

bezier, inkscape, svg

Solution

I have found the corresponding piece of code in Inkscape's source tree under `src/ui/tool/node.cpp`, method `Node::_updateAutoHandles`:

void Node::_updateAutoHandles()
{

    // Recompute the position of automatic handles.
    // For endnodes, retract both handles. (It's only possible to create an end auto node
    // through the XML editor.)
    if (isEndNode()) {
        _front.retract();
        _back.retract();
        return;
    }

    // Auto nodes automaticaly adjust their handles to give an appearance of smoothness,
    // no matter what their surroundings are.
    Geom::Point vec_next = _next()->position() - position();
    Geom::Point vec_prev = _prev()->position() - position();
    double len_next = vec_next.length(), len_prev = vec_prev.length();
    if (len_next > 0 && len_prev > 0) {
        // "dir" is an unit vector perpendicular to the bisector of the angle created
        // by the previous node, this auto node and the next node.
        Geom::Point dir = Geom::unit_vector((len_prev / len_next) * vec_next - vec_prev);
        // Handle lengths are equal to 1/3 of the distance from the adjacent node.
        _back.setRelativePos(-dir * (len_prev / 3));
        _front.setRelativePos(dir * (len_next / 3));
    } else {
        // If any of the adjacent nodes coincides, retract both handles.
        _front.retract();
        _back.retract();
    }
}

Problem

I am wondering what algorithm (or formula) Inkscape uses to calculate the control points if the nodes on a path are made "smooth". That is, if I have a path with five nodes whose `d` attribute is ``` M 115.85065,503.57451 49.653441,399.52543 604.56143,683.48319 339.41126,615.97628 264.65997,729.11336 ``` And I change the nodes to smooth, the `d` attribute is changed to ``` M 115.85065,503.57451 C 115.85065,503.57451 24.747417,422.50451 49.653441,399.52543 192.62243,267.61777 640.56491,558.55577 604.56143,683.48319 580.13686,768.23328 421.64047,584.07809 339.41126,615.97628 297.27039,632.32348 264.65997,729.11336 264.65997,729.11336 ``` Obviously, Inkscape calculates the control point coordinates (second last and last coordinate pair on lines on or after `C`). I am interested in the algorithm Inkscape uses for it.

Original source