图形学 · 简谈 Bézier curve

611 阅读8分钟

skewY_1.gif

(截图自:Nobel Tech)

1. 前序

Bézier curve,也就是大名鼎鼎的“贝塞尔曲线”。

你可能对这个概念不是很熟悉,但是如果你碰巧使用过 Windows XP 及以下,那么一定或多或少在【屏幕保护程序】中见过它。

“Bézier curve”以法国工程师 Pierre Bézier 命名。在1960年代初,供职于雷诺汽车的 Pierre 将其广泛应用在车辆主体的设计工序当中。

同时,由于贝塞尔曲线在数学上足够精简地对于现实曲线进行了拟合,便随着时间发展,逐渐成为计算机矢量图形学的基础。

一直到今天,你可以在游戏开发、艺术创作、字体设计、动画制作、机器人控制、建筑设计、路径规划,从数理逻辑到视觉表达再到工业工程甚至航空军事等等非常多的地方,都可以看到这种曲线的大量应用。

比如在主流设计软件中,常见的“钢笔”工具就是三次贝塞尔曲线的应用之一,而你在游乐园玩耍的过山车,也是用贝塞尔曲线来设计的。

image (25).png

(截图自:知网)

如果在知网上以“贝塞尔曲线”为关键词搜索,就会有大量研究出现。

可以说它已经成为了构建现代社会的基础理论设施之一。

2. 构成

想象一下,如果是你,会如何描述一个曲线?

首先,两个端点一定不能少,任何线段都会有开始和结束。

然后,如果这个线段是弯曲的,我们需要知道如何定义弯曲的方向和程度。

可以假想,线段弯曲是因为受到了一定程度的力的影响。就像一条毛线平搭在空中,中间会受到重力影响而自然下垂。

从而为了拟合一个现实曲线,我们也可以在任意直线段上施加一个具有方向的力,从而带动整个直线弯曲。

而力场是处处存在的,力的作用点可以选取线段上的任意一点,但线段长度随机、坐标随机,唯一在一开始就可以确定的只有两个端点,从而顺其自然,端点成为切入点。

贝塞尔想了一个非常巧妙的方法,它在线段的端点上,施加一个拖拽的“力”,端点是固定的,但是在“力”的作用下,线段中间的点会伴随发生位移。

而众所周知,“力”是矢量的,具有任意方向性,也具有任意大小。

那么用数学来描述这个拖拽的作用力,其实就是一个矢量。

这个矢量可视化之后,如果将端点安置为矢量的起点,那么这个矢量的终点就会出现在端点的周围。

这个终点,就是控制点,也称为:锚点。

锚点和端点,组成了贝塞尔曲线的物理构成。

image (26).png

而计算规则是贝塞尔曲线的另一个,也是最有趣的地方。它决定了“拖拽”效果具体是什么样子的,也最终决定了曲线的外观。

这种规则在实际应用中,可以根据需求执行至无数类结果,通常,数学表达上因为规则的特定系数存在 n 次方种,所以用“阶”来命名描述。从 1 到 n,代表从一阶到 n 阶。

本篇接下来简单介绍三种最常见的,也正是一阶、二阶、三阶贝塞尔曲线,方便理解这是一种怎样的存在。

3. 三个经典类型

① 一阶(线性)贝塞尔曲线

B(t)=P0+t(P1P0)=(1t)P0+tP1, t[0,1]B(t)=P_0+t(P_1-P_0)=(1-t)P_0+tP_1,\ t\in[0,1]

这个公式中,B(t) 表示贝塞尔曲线上任意一点的位置。

t 从 0~1 遍历下来,便构成了完整的曲线。

P0 和 P1 便是线段的两个端点,P0 为起点,P1 为终点。

t 叫做插值,这种算法也被称为插值法。

可以看到,两个端点的系数相加,即为 1。

如果画出来就很直观,在这个公式中,贝塞尔曲线上的任意一点,都在两个端点相连的直线段上。

Bézier_1_big.gif

(示意图:wiki)

是的,贝塞尔曲线不仅可以描述弯曲的线段,也可以表示直线段。或者说,直线段是曲线的一种形式。不弯曲,不代表不能弯曲。

一阶贝塞尔曲线是一条直线,故而也被称为线性贝塞尔曲线:Linear Bézier curves

当然了,初中数学也教过我们,笛卡尔坐标系下任意直线的表示方法为:

y=ax+b{a=P1P0b=P0x=ty=B(t)\begin{aligned} & y = ax+b & \begin{cases} a = P_1-P_0 \\ b = P_0 \\ x = t \\ y = B(t) \\ \end{cases} \end{aligned}

故而,一阶贝塞尔曲线符合线性规则。

② 二阶(平方)贝塞尔曲线

B(t)=(1t)2P0+2t(1t)P1+t2P2, t[0,1]B(t)=(1-t)^2P_0+2t(1-t)P_1+t^2P_2,\ t\in[0,1]

线性贝塞尔曲线还很难看出锚点的作用,从二阶开始,这个用来标定控制作用的点就出现了。

贝塞尔曲线是这么描述的,在规模为 (n) 的所有功能点集合中,第一个点 P0 表示起始端点,最后一个点 P(n-1) 表示终点,中间点全部依次为控制点(锚点)。同时,阶数为 n-1。

二阶贝塞尔曲线共有三个功能点,P1 为锚点,首尾的 P0 和 P2 为端点。

至于系数,可以很直观地发现,这是在一阶的基础上,做了平方处理。

((1t)+t)2=(1t)2+2t(1t)+t2((1-t)+t)^2 = (1-t)^2+2t(1-t)+t^2

故由此,称之为平方贝塞尔曲线:Quadratic Bézier curves

从平方被引入开始,曲线点所在的维度,就从一维线性,来到了二维平面。

此时弯曲就出现了。

Bézier_2_big.gif (示意图:wiki)

从线性曲线上可以发现,贝塞尔曲线点的运动路径是在所在直线上运动的。那么,当这个直线本身也发生了运动,那么最终绘制出的线段就是弯曲的。

而想要控制这个直线运动,就需要额外的锚点来规定一个新的路径,使直线的两个端点以运动,来构建新直线整体变化的路径。也就是上图所示。

在平方曲线中,这个单独的锚点,与前后两个点构成两条直线,分别约束了绿色直线两个端点的运动轨迹。从而得到了最终的曲线结果。

如果你恰好玩过《Cities: Skylines》(中译:《城市天际线》/《都市天际线》)这款游戏,就会发现游戏中的弯曲道路规划就是用的平方贝塞尔曲线。

image (27).png (截图自:T4rget)

③ 三阶(立方)贝塞尔曲线

二阶的锚点同时对两个端点进行了控制,那如果为了更自由一些,分别控制两个端点,那么此时就来到了三阶贝塞尔曲线。

不难举一反三,三次贝塞尔曲线是插值系数的三次方变化。

((1t)+t)3=(1t)3+3t(1t)2+3t2(1t)+t3B(t)=(1t)3P0+3t(1t)2P1+3t2(1t)P2+t3P3, t[0,1]\begin{aligned} & ((1-t)+t)^3 = (1-t)^3+3t(1-t)^2+3t^2(1-t)+t^3 \\ & B(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3,\ t\in[0,1]\\ \end{aligned}

  一共有四个功能点:两个端点,两个锚点。

两个锚点分别作用在两个端点上,也代表了一种运动趋势,曲线的运动方向从 P0 出发,先朝着 P1 运动,而后转向 P2 最后来到了终点 P3。

Bézier_3_big.gif (示意图:wiki)

因为再一次升阶,三阶也就是立方,所以人们也叫立方贝塞尔曲线:Cubic Bézier curves。

三阶贝塞尔曲线也是当前主流设计软件中的常用曲线,其中以“钢笔”工具最为出名。

image (28).png

而在游戏《Planet Coaster》(中译:《过山车之星》)中,你也可以看到它。

image (29).png (截图自:Freya Holmér)

4. 扩展

综上不难推出,扩展至通用表达的 n 阶贝塞尔曲线:

B(t)=i=0n(ni)Pi(1t)(ni)ti=(n0)P0(1t)(n)t0+(n1)P1(1t)(n1)t1+ ...+(nn1)Pn1(1t)1tn1+(nn)Pn(1t)0tn, t[0,1]\begin{aligned} B(t) &=\sum_{i=0}^{n}{\binom{n}{i}P_i(1-t)^{(n-i)}t^i} \\ &= \binom{n}{0}P_0(1-t)^{(n)}t^0+\binom{n}{1}P_1(1-t)^{(n-1)}t^1 \\ & +\ ...\\ & +\binom{n}{n-1}P_{n-1}(1-t)^{1}t^{n-1}+\binom{n}{n}P_n(1-t)^{0}t^n,\ t\in[0,1] \end{aligned}

Bézier_4_big.gif 四阶贝塞尔曲线,via: wiki

BezierCurve.gif 五阶贝塞尔曲线,via: wiki

是不是很有趣?

基本上现有工具都可以直接单独绘制出贝塞尔曲线。

但是在艺术创作中,我们也可以通过使用线性插值函数 lerp() 来将贝塞尔曲线的绘制生成过程呈现出来。

比如下图就是绘制的二次和三次贝塞尔曲线的生成过程,你可以在各大新媒体艺术展上看到它的身影。

最神奇的是,这张图里没有一条曲线,全部是用直线段绘制的,但是你能看到边框曲线的存在,当直线段无限密集,这个边缘变得无限平滑后,它就是标准的贝塞尔曲线了。

image (22).png

这张图是用 Processing 生成的,十分方便。

当然了,现实操作中,也并不是任意曲线都可以用贝塞尔曲线来描述。

虽然可以无限拟合,但从成本的角度考虑,有一些曲线更适合用其他方式来绘制,比如:圆弧。

贝塞尔曲线固然应用十分普遍,但也不是唯一。具体使用还是要根据实际情况来考虑,不能唯一论。

此外,国外有大佬制作了一份关于贝塞尔曲线的介绍视频,这里也十分安利大家看看。

B站有搬运,链接在这里:www.bilibili.com/video/BV1hL…

祝大家看地开心。