什么是贝塞尔曲线?
贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发。1962年,法国工程师皮埃尔·贝塞尔(Pierre Bézier)将其应用于汽车的主体设计,并广泛发表。
众所周知:
- 线段(一次贝塞尔曲线):给定起点与终点的坐标,就能确定唯一的一条线段;
- 圆(椭圆):给定圆心坐标和半径大小,就可以通过方程计算出圆周上每一点的坐标;
- 矩形:给定对角点的坐标,也可以顺利求出四条边上的所有点。
随着计算机日益普及,常常需要在电脑绘制图形,如果采用鼠绘的方式无疑很难绘制出满意的图形。那么,除了抛物线等规则的曲线,普通的曲线该如何在电脑上描述呢?答案便是贝塞尔曲线。
如何绘制一条贝塞尔曲线?
$n$次贝塞尔曲线由三类点来描述:
- 一个 起点 $P_0$
- $n-1$个 控制点 $P_1,\cdots,P_{n-1}$
- 一个 终点 $P_n$
| 二次贝塞尔曲线 | 三次贝塞尔曲线 | 四次贝塞尔曲线 |
|---|---|---|
![]() |
![]() |
![]() |
如图所示,可将所有点依次组成一个坐标向量 $P=[P_0,P_1,\cdots,P_n]^T$。
通过下述方法即可绘制一个精度为$t$的贝塞尔曲线:
- 将坐标向量$P$($P^*$)中两两相邻点确定的线段$t$等分;
- 取第$i$个等分点,构成新的坐标向量$P^*$;
- 重复步骤1~2,直到$P^*$中仅含一个点,该点便是贝塞尔曲线上的点;
- 重复步骤1~3,将贝塞尔曲线上的点用光滑的线连接起来。
如何计算贝塞尔曲线上的点?
以三次贝塞尔曲线为例,其坐标向量为
\[P=[P_0,P_1,P_2,P_3]^T\]根据矢量运算法则,得到第$i$个等分点的坐标(第一次迭代)为
\[X_i=\frac{i}{t}(P_1-P_0)+P_0\] \[Y_i=\frac{i}{t}(P_2-P_1)+P_1\] \[Z_i=\frac{i}{t}(P_3-P_2)+P_2\]整理即
\[X_i=(1-\frac{i}{t})P_0+\frac{i}{t}P_1\] \[Y_i=(1-\frac{i}{t})P_1+\frac{i}{t}P_2\] \[Z_i=(1-\frac{i}{t})P_2+\frac{i}{t}P_3\]同理,第二次迭代得到
\[K_i=(1-\frac{i}{t})X_i+\frac{i}{t}Y_i\] \[M_i=(1-\frac{i}{t})Y_i+\frac{i}{t}Z_i\]整理即
\[K_i=(1-\frac{i}{t})^2P_0+2\frac{i}{t}(1-\frac{i}{t})P_1+(\frac{i}{t})^2P_2\] \[M_i=(1-\frac{i}{t})^2P_1+2\frac{i}{t}(1-\frac{i}{t})P_2+(\frac{i}{t})^2P_3\]经过最终迭代后,得到曲线上的第$i$点坐标
\[B_i=(1-\frac{i}{t})^3P_0+3\frac{i}{t}(1-\frac{i}{t})^2P_1+3(1-\frac{i}{t})(\frac{i}{t})^2P_2+(\frac{i}{t})^3P_3\]记$k=\frac{i}{t}$。显然,$k\in[0,1]$。
因此,$n$次贝塞尔曲线可以简记为
\[B(k)=\sum_{m=0}^n\begin{pmatrix}n\\m\end{pmatrix}k^m(1-k)^{n-m}P_m\]matlab 程序示例
自定义m函数bezi2()可以求取任意精度(默认为100)与任意阶(由坐标向量中的点数确定)的贝塞尔曲线,结果为以复数形式表示的贝塞尔曲线上点的坐标。其源码如下:
>> plot(bezi2([1,1;1,3;9,1;9,3])), grid
function [B] = bezi2(P‚t)
% P = [起点,坐标;...;控制点,坐标;...;终点,坐标]
% t = 曲线精度(默认100)
% B = [(t+1)×2]
if nargin < 2, t = 100; end
n = size(P,1);
k = (0:t)'/t;
b = zeros(t+1,n);
for i=1:n,
b(:,i) = nchoosek(n-1,i-1)*(1-k).^(n-i).*k.^(i-1);
end
B = b*P*[1;1j];
end
运行结果如图:

与缺少其中一个控制点的二次贝塞尔曲线对比图如下:

从图中可以看到,控制点有点类似于“拉扯”的效果。因此,通过控制控制点的个数与位置,就能轻松在电脑上绘制出理想的曲线。



