SVG:将弧转换为Cubic Bezier

问题描述 投票:3回答:3

我正在尝试做一些我会非常简单的事情:用Cubic Bezier曲线替换SVG路径中的所有弧。

这个:http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes并没有真正帮助我,因为它没有真正说明转换。

我知道如何制作简单的Arcs,但SVG Arcs确实有很多参数。

所以我需要的只是一个算法:

rx ry x-axis-rotation large-arc-flag sweep-flag x y

(以及弧的起点)

并计算:

x1 y1 x2 y2 x y

(当然,起点,x和y保持相同的值......)

有人知道这样的事吗?

提前致谢! :-)

javascript svg bezier approximation
3个回答
3
投票

结果证明这是不可能的。我的意思是,数学上,至少。你不能用普通的三次贝塞尔曲线做圆弧,你总是会有一个误差,所以根据弧的角度,你可能需要不止一条贝塞尔曲线。

话虽如此,立方贝塞尔曲线对于四分之一圆弧非常有效,所以如果你的弧小于那个,你可以使用一条曲线,如果你有更宽的弧,你可以简单地将它除以一个合理的数字(之间)四分之一和半圆?使用两条曲线。在半到三夸脱之间?使用三条。全圆?四条曲线。非常简单)。

那么,这有多少工作?事实证明,如果你必须从头开始:a fair bit of work,但你可以跳到“好吧那么我需要的最终公式是什么”然后变得相对简单。

如果我们有角度phi,那么你的弧的三次曲线近似,只要我们将弧的起点与x轴对齐(这样弧开始于y = 0,并从那里逆时针运行),我们有圆弧半径R,是:

start coordinate = {
  x: R,
  y: 0
}

control point 1 = {
  x: R,
  y: R * 4/3 * tan( phi / 4)
}

control point 2 = {
  x: R * ( cos(phi) + 4/3 * tan( phi/4 ) * sin(phi) ),
  y: R * ( sin(phi) - 4/3 * tan( phi/4 ) * cos(phi) ),
}

end coordinate = {
  x: R * cos(phi),
  y: R * sin(phi)
}

数学!但实际上只是“插入角度,获得我们需要的坐标”。简单!

但是如果我们的弧不与x轴对齐怎么办?我们应用一个哑“旋转+平移”来对齐我们的弧,然后我们完成后反向运行旋转/平移。解释here


2
投票

大多数SVG渲染库必须这样做,因为2D图形库似乎不直接支持相对于X轴旋转的弧。

所以你可以在Batik中查找代码。或者这是我的SVG库中的代码(也可以从Batik借用):

https://code.google.com/p/androidsvg/source/browse/src/com/caverock/androidsvg/SVGAndroidRenderer.java#2540

它是Java,但应该很容易转换为JS。


0
投票

您还可以查看来自SnapSVG的this function,它可能是由Adobe Illustrator以某种方式使用的(它由名为“adobe-webplatform”的用户托管),以将弧转换为立方体命令。它也用于SVGO(ptimizer)。

我仍然试图破译它,但标准实际上非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.