通过随机点绘制漂亮的贝塞尔曲线

15

我正在使用RaphaelJS和JavaScript绘制一个通过随机点输出到SVG的平滑线条。 该线条严格水平,不在X轴上返回。 目前,我使用三次贝塞尔曲线从一个点到另一个点绘制线条。

问题是,这条线看起来不够好看。两个曲线在一个点处拼接不美观,其中一个曲线结束并开始另一个曲线时,拼接点的角度相当随机。 如何使上一个曲线平稳转换为下一个曲线,同时仍让线条穿过给定点?


你是使用贝塞尔曲线将所有点连接在一起,还是每对两个点使用不同的贝塞尔曲线? - Ricky Bobby
每对夫妇一个不同的。 - Nameless
4个回答

13

链接已更新,将点赞(需要对答案进行编辑以便我可以编辑)。 - Garbit

9

三次样条插值

如果你想要通过点绘制线条,那么你需要进行插值。贝塞尔曲线是带有控制节点的三次曲线,但是三次样条是一组通过n个点的三次曲线,并且每个曲线之间变化平滑。有关数学方面的详细信息,请参见维基百科文章

为了构建通过一组点的三次样条,您不幸地必须执行一个迭代过程;您基本上正在创建n-1个三次曲线并将它们的参数匹配在一起,这给您n+1个同时方程式解。一旦您完成了这个过程,随着移动点,您可以使用以前的解作为起点。

在Raphael中执行此操作,您需要生成三次样条,然后计算每个段的等效贝塞尔控制值。

有一些javascript代码可以为您计算三次样条,例如JavaScript(通过CoffeeScript)中的三次样条

分段多项式

与三次样条的另一种选择是将三次(或更高阶)多项式拟合到每组几个点上;例如,对于每4个点,拟合三次多项式,包括重叠部分。因此,点10-13形成从11到12的线的三次曲线。它不会像三次样条那样平滑,但应该更接近。这与三次样条非常相似,但无需求解曲线参数以使所有内容平滑。

分段多项式的问题在于它使用了高阶多项式,这些多项式是不稳定的,并且当点不在多项式线上或点彼此靠近时,您可能会得到大的折痕和颤动。

要在Raphael中绘制此图,您最好只需更频繁地采样该行并使用直线来绘制它。

线条形状

一个重要的考虑因素是您想要绘制什么样的线条。如果您只需要平滑的线条,请使用三次样条。但是,如果您正在绘制统计数据或其他特定类型的线条,则最好查看高斯分解或其他内容:三次样条是三次多项式(ax3 + bx2 + cx + d = 0),因此您不能很好地逼近正弦曲线(音频/信号)或高斯曲线(信号/统计)或指数曲线(衰减曲线,长尾统计)。


在SVG路径中,我只能使用直线、二次贝塞尔曲线、三次贝塞尔曲线或椭圆的一部分。 - Nameless

0

你考虑过对点处的切线角度进行平均吗?这样可以消除“不美观的接缝”。


0

我建议您拿出Foley和van Dam的交互式计算机图形基础,查看参数曲线的Hermite形式。 Hermite曲线由两个端点(曲线通过)和两个切向量定义,控制曲线在通过这些点时的方向。 它可以通过几个矩阵乘法轻松转换为Bezier形式,但优点是:对于平滑连接,曲线的相邻部分将在重合点处使用完全相同的切线,而使用Beziers则必须强制三个点共线。


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