贝塞尔曲线在计算机图形学中用于绘制形状,用于 CSS 动画以及许多其他地方。
它们非常简单,值得学习一次,然后在矢量图形和高级动画的世界中感到舒适。
本文提供了对贝塞尔曲线是什么的理论性但非常必要的见解,而下一篇文章展示了我们如何将它们用于 CSS 动画。
请花时间阅读和理解这个概念,它会对你很有帮助。
控制点
一个贝塞尔曲线是由控制点定义的。
可能会有 2、3、4 个或更多。
例如,两点曲线
三点曲线
四点曲线
如果你仔细观察这些曲线,你会立即注意到
-
点并不总是在曲线上。 这是完全正常的,稍后我们将看到曲线的构建方式。
-
曲线的阶数等于点数减一。 对于两点,我们有一条线性曲线(即直线),对于三点,我们有二次曲线(抛物线),对于四点,我们有三次曲线。
-
曲线始终位于控制点的凸包内
由于最后一个属性,在计算机图形学中可以优化交点测试。如果凸包不相交,那么曲线也不相交。因此,首先检查凸包的交点可以得到一个非常快的“不相交”结果。检查凸包的交点要容易得多,因为它们是矩形、三角形等等(参见上图),比曲线简单得多。
贝塞尔曲线在绘制中的主要价值在于——通过移动点,曲线以直观明显的方式发生变化。
尝试在下面的示例中使用鼠标移动控制点。
正如你所注意到的,曲线沿着切线 1 → 2 和 3 → 4 延伸。
经过一些练习,就会清楚地知道如何放置点以获得所需的曲线。通过连接多条曲线,我们几乎可以得到任何东西。
以下是一些示例
德卡斯特里奥算法
贝塞尔曲线有一个数学公式,但我们稍后再讨论,因为德卡斯特里奥算法与数学定义相同,并直观地展示了它的构造方式。
首先让我们看看 3 点示例。
以下是演示,以及解释。
控制点(1、2 和 3)可以使用鼠标移动。按下“播放”按钮运行它。
构建 3 点贝塞尔曲线的德卡斯特里奥算法
-
绘制控制点。在上面的演示中,它们被标记为:
1
、2
、3
。 -
在控制点之间构建线段 1 → 2 → 3。在上面的演示中,它们是棕色。
-
参数
t
从0
移动到1
。在上面的示例中,使用步长0.05
:循环遍历0, 0.05, 0.1, 0.15, ... 0.95, 1
。对于这些
t
值中的每一个-
在每个棕色线段上,我们取一个位于距离其起点成比例于
t
的点。由于有两个线段,我们有两个点。例如,对于
t=0
——两个点都将在线段的起点,对于t=0.25
——在线段长度的 25% 处,对于t=0.5
——50%(中间),对于t=1
——在线段的末端。 -
连接这些点。在下图中,连接线段被绘制为蓝色。
-
对于t=0.25 |
对于 t=0.5 |
---|---|
-
现在在 蓝色 线段上,取一个与
t
值成比例的距离上的点。也就是说,对于t=0.25
(左图),我们在线段左四分之一的末端有一个点,而对于t=0.5
(右图),则在线段的中间有一个点。在上面的图片中,该点是 红色 的。 -
当
t
从0
运行到1
时,t
的每个值都会在曲线上添加一个点。这些点的集合形成了贝塞尔曲线。它在上面的图片中是红色的,并且是抛物线。
这是一个针对 3 个点的过程。但对于 4 个点也是一样的。
4 个点的演示(点可以用鼠标移动)
4 个点的算法
- 用线段连接控制点:1 → 2,2 → 3,3 → 4。将会有 3 个 棕色 线段。
- 对于
0
到1
区间内的每个t
- 我们在这些线段上取距离从起点开始与
t
成比例的点。这些点被连接起来,因此我们有两个 绿色线段。 - 在这些线段上,我们取与
t
成比例的点。我们得到一个 蓝色线段。 - 在蓝色线段上,我们取一个与
t
成比例的点。在上面的例子中,它是 红色 的。
- 我们在这些线段上取距离从起点开始与
- 这些点一起形成了曲线。
该算法是递归的,可以推广到任意数量的控制点。
给定 N 个控制点
- 我们连接它们,最初得到 N-1 个线段。
- 然后对于
0
到1
的每个t
,我们在每个线段上取距离与t
成比例的点,并将它们连接起来。将会有 N-2 个线段。 - 重复步骤 2,直到只剩下一个点。
这些点构成了曲线。
运行和暂停示例,以清楚地看到线段以及曲线的构建方式。
一条看起来像 y=1/t
的曲线
锯齿形控制点也可以正常工作
可以制作循环
一条非光滑的贝塞尔曲线(是的,这也有可能)
如果算法描述中有什么不清楚的地方,请查看上面的实时示例,以了解曲线的构建方式。
由于该算法是递归的,我们可以构建任意阶的贝塞尔曲线,即:使用 5、6 或更多个控制点。但在实践中,许多点没有用。通常我们取 2-3 个点,对于复杂的线条,将几个曲线粘合在一起。这样开发和计算起来更简单。
数学
贝塞尔曲线可以用数学公式描述。
正如我们所见,实际上不需要知道它,大多数人只是通过鼠标移动点来绘制曲线。但如果你对数学感兴趣,这里就是公式。
给定控制点Pi
的坐标:第一个控制点的坐标为P1 = (x1, y1)
,第二个为P2 = (x2, y2)
,依此类推,曲线的坐标由依赖于参数t
的方程描述,该参数来自区间[0,1]
。
-
2点曲线的公式
P = (1-t)P1 + tP2
-
对于3个控制点
P = (1−t)2P1 + 2(1−t)tP2 + t2P3
-
对于4个控制点
P = (1−t)3P1 + 3(1−t)2tP2 +3(1−t)t2P3 + t3P4
这些是向量方程。换句话说,我们可以用x
和y
代替P
来获得相应的坐标。
例如,3点曲线是由以下计算得到的点(x,y)
形成的
x = (1−t)2x1 + 2(1−t)tx2 + t2x3
y = (1−t)2y1 + 2(1−t)ty2 + t2y3
我们应该用 3 个控制点的坐标来代替 x1, y1, x2, y2, x3, y3
,然后当 t
从 0
变到 1
时,对于每个 t
值,我们都会得到曲线的 (x,y)
坐标。
例如,如果控制点是 (0,0)
、(0.5, 1)
和 (1, 0)
,则方程变为
x = (1−t)2 * 0 + 2(1−t)t * 0.5 + t2 * 1 = (1-t)t + t2 = t
y = (1−t)2 * 0 + 2(1−t)t * 1 + t2 * 0 = 2(1-t)t = –2t2 + 2t
现在,当 t
从 0
运行到 1
时,每个 t
的 (x,y)
值集形成了这些控制点的曲线。
总结
贝塞尔曲线由其控制点定义。
我们看到了贝塞尔曲线的两种定义
- 使用绘图过程:德卡斯特里奥算法。
- 使用数学公式。
贝塞尔曲线的优点
- 我们可以通过移动控制点来用鼠标绘制平滑的线条。
- 复杂的形状可以由多个贝塞尔曲线组成。
用途
- 在计算机图形学、建模、矢量图形编辑器中。字体由贝塞尔曲线描述。
- 在 Web 开发中 - 用于 Canvas 和 SVG 格式的图形。顺便说一下,上面的“实时”示例是用 SVG 编写的。它们实际上是一个单一的 SVG 文档,它被赋予不同的点作为参数。您可以在单独的窗口中打开它并查看源代码:demo.svg.
- 在 CSS 动画中,用于描述动画的路径和速度。
评论
<code>
标签,对于多行代码,请使用<pre>
标签,对于超过10行的代码,请使用沙箱(plnkr,jsbin,codepen…)