Inkscape如何计算“平滑边缘”的控制点坐标?

3
我想知道Inkscape在将路径节点变为“平滑”时使用了什么算法(或公式)来计算控制点。也就是说,如果我有一条包含五个节点的路径,其d属性为:
M 115.85065,503.57451
  49.653441,399.52543 
  604.56143,683.48319 
  339.41126,615.97628 
  264.65997,729.11336

我将节点更改为平滑曲线,d属性也随之改变为:

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

显然,Inkscape计算控制点坐标(在C之后的行上或行末端的倒数第二和最后一对坐标)。我对Inkscape用于此的算法感兴趣。
2个回答

5

我在Inkscape的源代码树中找到了相应的代码,位于src/ui/tool/node.cpp,方法为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();
    }
}

1

我不确定这些信息的质量是否100%正确。

但是至少在某个时间点上,为了计算某些曲线, inkscape似乎使用了 >>spiro<< 技术。

http://www.levien.com/spiro/

快速浏览一下页面,他提供了一个链接到他的博士论文: http://www.levien.com/phd/thesis.pdf 在其中他介绍了理论/算法...

干杯

编辑:

我目前正在为类似的目的进行一些调查,所以我偶然发现... http://www.w3.org/TR/SVG11/paths.html#PathDataCurveCommands ... SVG 曲线的规范。 因此曲线,不是圆或弧,是三次或二次贝塞尔曲线... 也可以看看维基百科上的贝塞尔公式: http://en.wikipedia.org/wiki/B-spline#Uniform_quadratic_B-spline


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接