木匣子

Web/Game/Programming/Life etc.

Chaikin 曲线

贝塞尔曲线是一种通过点构造曲线的的插值方法,想要绘制一个90度的圆弧,需要精确计算起点和终点以及数个控制点的位置。圆弧这样的特定形状至少还有可靠的表达式来计算,但是想要一此更随意而优美的曲线,就不容易办到了。(Neither is a superset of the other — Bezier curves cannot produce circular arcs and circular arcs cannot produce Bezier curves.——Curved Paths

好再还有其它的方法可以绘制曲线。一个叫 Chaikin 的人提出了一种通过已知折线段构造曲线的方法 Chaikins-Algorithm,其原理有点像木工打磨家具,把锐利的角磨掉,一次又一次,直到家具看起来圆滑为止。在工业上类似的术语叫倒角(corner cutting)。

我用 processing 做了一个演示,大约迭代4次左右,就可以形成曲线:

倒角的方法是通过直线插值的方法完成的,每次迭代,在原有线段的每两个点之间取1/4和3/4处的点连接起来创建新的线段。第一次写的时候我把插值函数顺序写反了,结果出现了这个好玩的艺术形状:

正确的插值函数应该是:

Point interpolate(Point p0, Point p1, float t) {
    return new Point(
        p0.x*(1-t) + p1.x*t,
        p0.y*(1-t) + p1.y*t
    );
}

如果把折线首尾相连,就可以得到闭合曲线。可以想像小时候画圆的时候,先画个正方形,然后慢慢把四个角擦掉一点点,然后把缺口用线连起来,最后就得到圆了。

参考文献:

CHAIKIN’S ALGORITHMS FOR CURVES
http://graphics.cs.ucdavis.edu/education/CAGDNotes/Chaikins-Algorithm/Chaikins-Algorithm.html