木匣子

Web/Game/Programming/Life etc.

闭合的均匀 B-Spline

最近阅读了 Anders Hoff 写的 ON GENERATIVE ALGORITHMS 系列文章。非常的赞!一直很喜欢这种结合数学的美学作品。

其中 Sand Spline 一文给了我很大的启发。在他的算法里,他使用了 B-Spline 样条来构造一个不断运动的圆状环,准确地说应该是一个圆状弧线,因为这个曲线没有封闭,留下了一个缺口。

In this animation the spline starts on the right and moves counter-clockwise. You will also notice that the level of noise is larger the further out along the spline we go. This has nothing to do with the spline itself, but it is a nice way to keep the starting node in its original position.

– Sand Spline

我不太确定他说的 “This has nothing to do with the spline itself” 指的是什么,但是我决定想办法 “修复” 这个令人不愉快的缺口。

简单地学习 B-spline 后,我发现了一种十分简单的方法来构造闭合的 B-Spline 曲线:Wrapping Control Points,示意图如下:

wrapping control points

通过在曲线尾部重复头部的控制点,然后将曲线的基函数均匀化(即每一组控制点用的基函数都一样,可以避免曲线头尾经过控制点),最终将使曲线头尾相连。

我写了一个简单的 Demo 来展示使用这个方法得到的效果(曲线的每一段由红蓝颜色区别,受四个控制点):

另外为了简化基函数的方程计算,我还引用了一个现成的基函数矩阵(推导过程见此文):

$$ M=\frac{1}{6}\begin{bmatrix} 1 & 4 & 1 & 0\\ -3 & 0 & 3 & 0\\ 3 & -6 & 3 & 0\\ -1 & 3 & -3 & 1 \end{bmatrix} $$

最后试着用这个封闭的 B-Spline 做了个 Sand Spline:

去掉了曲线断开的缺口后,是不是感觉更加优雅了?