貝塞爾曲線

在數學的數值分析領域中，**貝茲曲線**（英語：Bézier curve）是電腦圖學中相當重要的參數曲線。更高維度的廣泛化貝茲曲線就稱作貝茲曲面，其中貝茲三角是一種特殊的實例。

貝茲曲線於 1962 年，由法國工程師皮埃爾・貝茲（Pierre Bézier）所廣泛發表，他運用貝茲曲線來為汽車的主體進行設計。貝茲曲線最初由保爾・德・卡斯特里奧於 1959 年運用德卡斯特里奧演算法開發，以穩定數值的方法求出貝茲曲線。

## 實例說明

### 線性貝茲曲線

給定點 **P**0、**P**1，線性貝茲曲線只是一條兩點之間的直線。這條線由下式給出：

　
: $\mathbf {B} (t)=\mathbf {P} _{0}+(\mathbf {P} _{1}-\mathbf {P} _{0})t=(1-t)\mathbf {P} _{0}+t\mathbf {P} _{1}{\mbox{ , }}t\in [0,1]$

且其等同於線性插值。

### 二次方貝茲曲線

二次方貝茲曲線的路徑由給定點 **P**0、**P**1、**P**2 的函式 **B**（_t_）追蹤：

　
: $\mathbf {B} (t)=(1-t)^{2}\mathbf {P} _{0}+2t(1-t)\mathbf {P} _{1}+t^{2}\mathbf {P} _{2}{\mbox{ , }}t\in [0,1]$

TrueType 字型就運用了以貝茲樣條組成的二次貝茲曲線。

### 三次方貝茲曲線

**P**0、**P**1、**P**2、**P**3 四個點在平面或在三維空間中定義了三次方貝茲曲線。曲線起始於 **P**0 走向 **P**1，並從 **P**2 的方向來到 **P**3。一般不會經過 **P**1 或 **P**2；這兩個點只是在那裡提供方向資訊。**P**0 和 **P**1 之間的間距，決定了曲線在轉而趨進 **P**2 之前，走向 **P**1 方向的「長度有多長」。

曲線的參數形式為：

　
: $\mathbf {B} (t)=\mathbf {P} _{0}(1-t)^{3}+3\mathbf {P} _{1}t(1-t)^{2}+3\mathbf {P} _{2}t^{2}(1-t)+\mathbf {P} _{3}t^{3}{\mbox{ , }}t\in [0,1]$

現代的成象系統，如 PostScript、Asymptote 和 Metafont，運用了以貝茲樣條組成的三次貝茲曲線，用來描繪曲線輪廓。

## 一般化

 $n$ 階貝茲曲線可如下推斷。給定點 **P**0、**P**1、…、**P**n，其貝茲曲線即

　
: $\mathbf {B} (t)=\sum _{i=0}^{n}{n \choose i}\mathbf {P} _{i}(1-t)^{n-i}t^{i}={n \choose 0}\mathbf {P} _{0}(1-t)^{n}t^{0}+{n \choose 1}\mathbf {P} _{1}(1-t)^{n-1}t^{1}+\cdots +{n \choose n-1}\mathbf {P} _{n-1}(1-t)^{1}t^{n-1}+{n \choose n}\mathbf {P} _{n}(1-t)^{0}t^{n}{\mbox{ , }}t\in [0,1]$ 。

例如 $n=5$ ：

　
: $\mathbf {B} (t)=\mathbf {P} _{0}(1-t)^{5}+5\mathbf {P} _{1}t(1-t)^{4}+10\mathbf {P} _{2}t^{2}(1-t)^{3}+10\mathbf {P} _{3}t^{3}(1-t)^{2}+5\mathbf {P} _{4}t^{4}(1-t)+\mathbf {P} _{5}t^{5}{\mbox{ , }}t\in [0,1]$ 。

如上公式可如下遞迴表達：
用 $\mathbf {B} _{\mathbf {P} _{0}\mathbf {P} _{1}\ldots \mathbf {P} _{n}}$ 表示由點 **P**0、**P**1、…、**P**n 所決定的貝茲曲線。則

　
: $\mathbf {B} (t)=\mathbf {B} _{\mathbf {P} _{0}\mathbf {P} _{1}\ldots \mathbf {P} _{n}}(t)=(1-t)\mathbf {B} _{\mathbf {P} _{0}\mathbf {P} _{1}\ldots \mathbf {P} _{n-1}}(t)+t\mathbf {B} _{\mathbf {P} _{1}\mathbf {P} _{2}\ldots \mathbf {P} _{n}}(t)$

用平常話來說， $n$ 階的貝茲曲線，即雙 $n-1$ 階貝茲曲線之間的插值。

### 術語

一些關於參數曲線的術語，有

　
: $\mathbf {B} (t)=\sum _{i=0}^{n}\mathbf {P} _{i}\mathbf {b} _{i,n}(t),\quad t\in [0,1]$

即多項式

　
: $\mathbf {b} _{i,n}(t)={n \choose i}t^{i}(1-t)^{n-i},\quad i=0,\ldots n$

又稱作 _n_ 階的伯恩斯坦基底多項式，定義 00 = 1。

點 **P**i 稱作貝茲曲線的**控制點**。多邊形以帶有線的貝茲點連接而成，起始於 **P**0 並以 **P**n 終止，稱作**貝茲多邊形**（或**控制多邊形**）。貝茲多邊形的凸包（convex hull）包含有貝茲曲線。

### 註解

* 開始於 **P**0 並結束於 **P**n 的曲線，即所謂的**端點插值法**屬性。
* 曲線是直線的充分必要條件是所有的控制點都位在曲線上。同樣的，貝茲曲線是直線的充分必要條件是控制點共線。
* 曲線的起始點（結束點）相切於貝茲多邊形的第一節（最後一節）。
* 一條曲線可在任意點切割成兩條或任意多條子曲線，每一條子曲線仍是貝茲曲線。
* 一些看似簡單的曲線（如圓）無法以貝茲曲線精確的描述，或分段成貝茲曲線（雖然當每個內部控制點對單位圓上的外部控制點水平或垂直的的距離為 $4\left({\sqrt {2}}-1\right)/3$ 時，分成四段的貝茲曲線，可以小於千分之一的最大半徑誤差近似於圓）。
* 位於固定偏移量的曲線（來自給定的貝茲曲線），又稱作**偏移曲線**（假平行於原來的曲線，如兩條鐵軌之間的偏移）無法以貝茲曲線精確的形成（某些平凡實例除外）。無論如何，現存的啟發法通常可為實際用途中給出近似值。

## 建構貝茲曲線

### 線性曲線

線性貝茲曲線函式中的 _t_ 會經過由 **P**0 至 **P**1 的 **B**（_t_）所描述的曲線。例如當 _t=0.25_ 時，**B**（_t_）即一條由點 **P**0 至 **P**1 路徑的四分之一處。就像由 0 至 1 的連續 _t_，**B**（_t_）描述一條由 **P**0 至 **P**1 的直線。

### 二次曲線

為建構二次貝茲曲線，可以中介點 **Q**0 和 **Q**1 作為由 0 至 1 的 _t_：

* 由 **P**0 至 **P**1 的連續點 **Q**0，描述一條線性貝茲曲線。
* 由 **P**1 至 **P**2 的連續點 **Q**1，描述一條線性貝茲曲線。
* 由 **Q**0 至 **Q**1 的連續點 **B**（_t_），描述一條二次貝茲曲線。

### 高階曲線

為建構高階曲線，便需要相應更多的中介點。對於三次曲線，可由線性貝茲曲線描述的中介點 **Q**0、**Q**1、**Q**2，和由二次曲線描述的點 **R**0、**R**1 所建構：

對於四次曲線，可由線性貝茲曲線描述的中介點 **Q**0、**Q**1、**Q**2、**Q**3，由二次貝茲曲線描述的點 **R**0、**R**1、**R**2，和由三次貝茲曲線描述的點 **S**0、**S**1 所建構：

還可參閱五階貝茲曲線的構成：

這些運動軌跡使用 de Casteljau 演算法計算出貝茲曲線。

## 升階

_n_ 次貝茲曲線可以轉換為一個形狀完全相同的 _n+1_ 次貝茲曲線。
這在軟體只支援特定階次的貝茲曲線時很有用。
例如，Cairo 只支援三次貝茲曲線，你就可以用升階的方法在 Cairo 畫出二次貝茲曲線。

我們利用 $\mathbf {B} (t)=(1-t)\mathbf {B} (t)+t\mathbf {B} (t)$ 這個特性來做升階。我們把曲線方程式中每一項 $\mathbf {b} _{i,n}(t)\mathbf {P} _{i}$ 都乘上 (1 −_t_) 或 _t_，讓每一項都往上升一階。以下是將二階升為三階的範例

　
: ${\begin{aligned}&{}\quad (1-t)^{2}\mathbf {P} _{0}+2(1-t)t\mathbf {P} _{1}+t^{2}\mathbf {P} _{2}\\&=(1-t)^{3}\mathbf {P} _{0}+(1-t)^{2}t\mathbf {P} _{0}+2(1-t)^{2}t\mathbf {P} _{1}\\&{}\qquad +2(1-t)t^{2}\mathbf {P} _{1}+(1-t)t^{2}\mathbf {P} _{2}+t^{3}\mathbf {P} _{2}\\&=(1-t)^{3}\mathbf {P} _{0}+3(1-t)^{2}t{\frac {\mathbf {P} _{0}+2\mathbf {P} _{1}}{3}}+3(1-t)t^{2}{\frac {2\mathbf {P} _{1}+\mathbf {P} _{2}}{3}}+t^{3}\mathbf {P} _{2}\end{aligned}}$

對任何的 _n_ 值，我們都可以使用以下等式

　
: ${n+1 \choose i}(1-t)\mathbf {b} _{i,n}={n \choose i}\mathbf {b} _{i,n+1},\quad (1-t)\mathbf {b} _{i,n}={\frac {n+1-i}{n+1}}\mathbf {b} _{i,n+1}$

　
: ${n+1 \choose i+1}t\mathbf {b} _{i,n}={n \choose i}\mathbf {b} _{i+1,n+1},\quad t\mathbf {b} _{i,n}={\frac {i+1}{n+1}}\mathbf {b} _{i+1,n+1}$

　
: ${\begin{aligned}\mathbf {B} (t)&=(1-t)\sum _{i=0}^{n}\mathbf {b} _{i,n}(t)\mathbf {P} _{i}+t\sum _{i=0}^{n}\mathbf {b} _{i,n}(t)\mathbf {P} _{i}\\&=\sum _{i=0}^{n}{\frac {n+1-i}{n+1}}\mathbf {b} _{i,n+1}(t)\mathbf {P} _{i}+\sum _{i=0}^{n}{\frac {i+1}{n+1}}\mathbf {b} _{i+1,n+1}(t)\mathbf {P} _{i}\\&=\sum _{i=0}^{n+1}\left({\frac {i}{n+1}}\mathbf {P} _{i-1}+{\frac {n+1-i}{n+1}}\mathbf {P} _{i}\right)\mathbf {b} _{i,n+1}(t)=\sum _{i=0}^{n+1}\mathbf {b} _{i,n+1}(t)\mathbf {P'} _{i}\end{aligned}}$

式中 $\mathbf {P} _{-1}$ 和 $\mathbf {P} _{n+1}$ 可以任意挑選。

因此，新的控制點為

　
: $\mathbf {P'} _{i}={\frac {i}{n+1}}\mathbf {P} _{i-1}+{\frac {n+1-i}{n+1}}\mathbf {P} _{i},\quad i=0,\ldots ,n+1.$

## 應用

### 電腦繪圖

由於需要點陣化更精細的解析度時，重新插值（補點）的計算量較小，貝茲曲線被廣泛地在電腦圖形中用來為平滑曲線建立模型。貝茲曲線是向量圖形檔案和相應軟體（如 PostScript、PDF 等）能夠處理的唯一曲線，用於光滑地近似其他曲線。

二次和三次貝茲曲線最為常用。

### 程式範例

下列程式碼為一簡單的實際運用範例，展示如何使用 C 語言標出三次方貝茲曲線。注意，此處僅簡單的計算多項式係數，並讀盡一系列由 0 至 1 的 t 值；實踐中一般不會這麼做，遞迴求解通常會更快速 —— 以更多的記憶體為代價，花費較少的處理器時間。不過直接的方法較易於理解並產生相同結果。以下程式碼已使運算更為清晰。實踐中的最佳化會先計算係數一次，並在實際計算曲線點的迴圈中反複使用。此處每次都會重新計算，損失了效率，但程式碼更清楚易讀。

曲線的計算可在曲線陣列上將相連點畫上直線 —— 點越多，曲線越平滑。

在部分架構中，下以程式碼也可由動態規劃進行最佳化。舉例來說，_dt_ 是一個常數，_cx_ \* _t_ 則等同於每次反覆就修改一次常數。經反覆應用這種最佳化後，迴圈可被重寫為沒有任何乘法（雖然這個過程不是穩定數值的）。

另一種貝茲曲線的應用是在動畫中，描述物件的運動路徑等等。此處，曲線的 x、y 位置不用來標示曲線，但用來表示圖形位置。當用在這種形式時，連續點之間的距離會變的更為重要，且大多不是平均比例。點將會串的更緊密，控制點更接近每一個點，而更為稀疏的控制點會散的更開。如果需要線性運動速度，進一步處理時就需要循所需路徑將點平均分散。

## 多項式表示法

有時我們可能想要把貝茲曲線表示為多項式，而非比較不直接的伯恩斯坦多項式。使用二項式定理和貝茲曲線的定義，重新整理後可以得到：

　
: $\mathbf {B} (t)=\sum _{j=0}^{n}{t^{j}\mathbf {C} _{j}}$

此處

　
: $\mathbf {C} _{j}={\frac {n!}{(n-j)!}}\sum _{i=0}^{j}{\frac {(-1)^{i+j}\mathbf {P} _{i}}{i!(j-i)!}}=\prod _{m=0}^{j-1}(n-m)\sum _{i=0}^{j}{\frac {(-1)^{i+j}\mathbf {P} _{i}}{i!(j-i)!}}.$

計算曲線上的點時需要多次計算 $\mathbf {B} (t)$ ，因此事先計算好 $\mathbf {C} _{j}$ 會比較實際；然而要小心高階曲線可能會缺乏數值穩定性（需使用 De Casteljau 演算法來處理）。注意其空積為 1。

## 有理貝茲曲線

有理貝茲增加可調節的權重，以提供更近似於隨意的形狀。分子是加權的伯恩斯坦形式貝茲曲線，而分母是加權的伯恩斯坦多項式的總和。

給定 _n_ + 1 控制點 **P**i，有理貝茲曲線可如下描述：

　
: $\mathbf {B} (t)={\frac {\sum _{i=0}^{n}b_{i,n}(t)\mathbf {P} _{i}w_{i}}{\sum _{i=0}^{n}b_{i,n}(t)w_{i}}}$

或簡單的

　
: $\mathbf {B} (t)={\frac {\sum _{i=0}^{n}{n \choose i}t^{i}(1-t)^{n-i}\mathbf {P} _{i}w_{i}}{\sum _{i=0}^{n}{n \choose i}t^{i}(1-t)^{n-i}w_{i}}}$

## 參閱

* de Casteljau 演算法
* 樣條
* 貝茲樣條
* 貝茲曲面
* 貝茲三角
* NURBS
* string art，Bézier curves are also formed by many common forms of string art, where strings are looped across a frame of nails.
* 埃爾米特曲線

## 參考文獻

### 參照

### 來源

## 外部連結

* 三階貝茲曲線 applet （頁面存檔備份，存於網際網路檔案館）（英文）
* 即時數學貝茲 applet （頁面存檔備份，存於網際網路檔案館）（英文）
* 各種樣條類型的即時數學貝茲 applet，樣條的 JAVA 程式設計 （頁面存檔備份，存於網際網路檔案館）在互動式介紹樣條 （頁面存檔備份，存於網際網路檔案館）（英文）
* Hermite 與 Bezier 曲線繪製方法
* 北斗星君簡介貝茲曲線 （頁面存檔備份，存於網際網路檔案館）