如何对一个三次贝塞尔曲线进行偏移?

32

我正在尝试创建一个“平行”的贝塞尔曲线。我已经接近成功,但还差一点。我试图保持两个曲线之间的1像素偏移(红色和蓝色)。

当前尝试

我的主要目标是使用边缘偏移算法来扩展/收缩SVG路径。


解决方案

对于任何其他正在寻找解决方案的人,我已经创建了一个AS3版本。

http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/


纯属猜测,我自己从未尝试过,但您可以在曲线显示为某种“图像”后将其复制,并以所需的偏移量重新绘制为新颜色。 - warren
@warren 它不会保持1像素的偏移。 - Sean Thayne
如果你从0,02,2再到0,2画一条曲线,然后将曲线复制到图像中并以4,4为中心重新绘制(而不是2,2),那么这不会产生1像素的偏移吗? - warren
3
只有在某些情况下才会生效,这取决于曲线的复杂程度。如果你说的是一个非常简单的弧线,弧度很小,那么你的方法是可行的。但对于其他的情况,你需要让它直接与原始线相交。这完全取决于曲线的角度难度。 - Sean Thayne
1
这个问题似乎与此相关:https://dev59.com/TnA75IYBdhLWcg3wm6Uj - Magnus Hoff
4个回答

16

你是否也有立方曲线或更高阶的推广,还是你的解决方案只适用于二次曲线?(如果是,那么相关文档是否可用?=) - Mike 'Pomax' Kamermans
1
抱歉,我没有三次方程的解决方案...但是我意识到您可以使用二次方程的近似值来代替三次方程,并且每个近似值都要偏移,因为在每个偏移的极端处,切线不会改变。 - microbians
链接已经失效了。 - aheze
1
@aheze 已经恢复正常工作。 - microbians

11

来自维基百科:(http://en.wikipedia.org/wiki/B%C3%A9zier_curve)

从给定的Bézier曲线偏移固定距离处的曲线,通常称为偏移曲线(类似于铁路轨道之间的偏移),不能被一个Bézier曲线完全形成(除了一些微不足道的情况)。然而,有启发式方法通常可以给出实际目的下足够的近似值。

您还可以查看此处指示的论文: Outline of cubic bezier curve stroke


你能解释至少一个启发式吗?(我知道曲线平滑化) - user1196549

8
你所要求的被称为数学中的平移或偏移曲线。维基百科上的贝塞尔曲线文章(其他人引用过)未能将“偏移曲线”链接到正确的文章,但我已在几秒钟前修复了它。在矢量图形世界中,同样的概念被称为对路径进行描边

一般来说,对于三次/贝塞尔曲线,偏移曲线是一个10次多项式!来源:Kilgard, p. 28

如果你只想栅格化这样的偏移曲线,而不是计算它们的解析形式,你可以例如查看ghostscript的源代码。你也可以查看这个专利申请,看看NV_path_rendering是如何做到的。

如果您想转换或近似偏移曲线,那么涵盖METAFONT到PostScript字体的TUG论文MetaFog是一个很好的参考。METAFONT系统先于PostScript出现,它允许用(更复杂的数学)描边操作来描述字体,但由于速度原因,PostScript Type 1字体只允许使用填充而不是一般的PostScript绘图。

另一个算法以(仅两个)贝塞尔曲线(每侧一个)来逼近偏移量,并提供了在PostScript中的代码,在Gernot Hoffmann的这篇论文第7节中介绍。(感谢OpenGL论坛上的某人发现了这篇文章。)

实际上有很多这样的算法。我找到了一篇1997年的调查报告,介绍了各种用于近似偏移曲线的算法。它们假设源曲线是Bezier或NURBS。


7
通常情况下,不可能将三次贝塞尔曲线的偏移表示为另一条三次贝塞尔曲线(具体来说,当您有尖点或曲率半径接近偏移距离时,这会出现问题)。但是,您可以以任何精度近似偏移量。
请尝试以下操作:
1. 偏移所涉及的Beziers(您已经做得相当不错); 2. 测量每个原始曲线与相应偏移曲线之间的差异。我建议尝试大约10个样本,看看效果如何; 3. 对于任何超出公差的偏移,请使用deCastlejau算法对其进行细分和迭代。
我没有实现偏移(因为我使用的内核已经有偏移),但这似乎值得一试。

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