Reputation: 40553
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.
Upvotes: 3
Views: 1714
Reputation: 40553
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();
}
}
Upvotes: 5
Reputation: 301
I'm not 100% sure of the quality of this information. But at least at some point in time for calculating some curves inkscape seems to have used >>spiro<<.
Take a quick look at the page, he's providing a link to his PhD-thesis: http://www.levien.com/phd/thesis.pdf in which he's introducing the theory/algorithms ...
Cheers
I'm currently investigating a bit into the matter for a similar purpose, so I stumbled across ... http://www.w3.org/TR/SVG11/paths.html#PathDataCurveCommands ... the specification of curves for SVG. So curves, like not circles or arcs, are cubic or quadratic beziers then ... Have a look at wikipedia for bezier formulas as well: http://en.wikipedia.org/wiki/B-spline#Uniform_quadratic_B-spline
Upvotes: 1