LINK: http://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A#.E9.9B.BB.E8.85.A6.E7.B9.AA.E5.9C.96
在數(shù)學(xué)的數(shù)值分析領(lǐng)域中,貝茲曲線(Bézier curve)是電腦圖形學(xué)中相當(dāng)重要的參數(shù)曲線。更高維度的廣泛化貝茲曲線就稱(chēng)作貝茲曲面,其中貝茲三角是一種特殊的實(shí)例。
貝茲曲線於1962年,由法國(guó)工程師皮埃爾·貝茲(Pierre Bézier)所廣泛發(fā)表,他運(yùn)用貝茲曲線來(lái)為汽車(chē)的主體進(jìn)行設(shè)計(jì)。貝茲曲線最初由 Paul de Casteljau 於1959年運(yùn)用 de Casteljau 演算法開(kāi)發(fā),以穩(wěn)定數(shù)值的方法求出貝茲曲線。
[編輯] 實(shí)例說(shuō)明
[編輯] 線性貝茲曲線
給定點(diǎn) P0、P1,線性貝茲曲線只是一條兩點(diǎn)之間的直線。這條線由下式給出:
且其等同於線性插值。
[編輯] 二次方貝茲曲線
二次方貝茲曲線的路徑由給定點(diǎn) P0、P1、P2 的函數(shù) B(t) 追蹤:
。
TrueType 字型就運(yùn)用了以貝茲樣條組成的二次貝茲曲線。
[編輯] 三次方貝茲曲線
P0、P1、P2、P3 四個(gè)點(diǎn)在平面或在三維空間中定義了三次方貝茲曲線。曲線起始於 P0 走向 P1,並從 P2 的方向來(lái)到 P3。一般不會(huì)經(jīng)過(guò) P1 或 P2;這兩個(gè)點(diǎn)只是在那裡提供方向資訊。 P0 和 P1 之間的間距,決定了曲線在轉(zhuǎn)而趨進(jìn) P3 之前,走向 P2 方向的「長(zhǎng)度有多長(zhǎng)」。
曲線的參數(shù)形式為:
。
現(xiàn)代的成象系統(tǒng),如 PostScript、Asymptote 和 Metafont,運(yùn)用了以貝茲樣條組成的三次貝茲曲線,用來(lái)描繪曲線輪廓。
[編輯] 一般化
n 階貝茲曲線可如下推斷。給定點(diǎn) P0、P1、…、Pn,其貝茲曲線即
。
例如 n = 5:
。
如上公式可如下遞歸表達(dá): 用
表示由點(diǎn) P0、P1、…、Pn 所決定的貝茲曲線。則
用平常話來(lái)說(shuō),n 階的貝茲曲線,即雙 n - 1 階貝茲曲線之間的插值。
[編輯] 術(shù)語(yǔ)
一些關(guān)於參數(shù)曲線的術(shù)語(yǔ),有
即多項(xiàng)式
又稱(chēng)作 n 階的伯恩斯坦基底多項(xiàng)式,定義 00 = 1。
點(diǎn) Pi 稱(chēng)作貝茲曲線的控制點(diǎn)。多邊形以帶有線的貝茲點(diǎn)連接而成,起始於 P0 並以 Pn 終止,稱(chēng)作貝茲多邊形(或控制多邊形)。貝茲多邊形的凸包(convex hull)包含有貝茲曲線。
[編輯] 註解
- 開(kāi)始於 P0 並結(jié)束於 Pn 的曲線,即所謂的端點(diǎn)插值法屬性。
- 曲線是直線的充分必要條件是所有的控制點(diǎn)都位在曲線上。同樣的,貝茲曲線是直線的充分必要條件是控制點(diǎn)共線。
- 曲線的起始點(diǎn)(結(jié)束點(diǎn))相切於貝茲多邊形的第一節(jié)(最後一節(jié))。
- 一條曲線可在任意點(diǎn)切割成兩條或任意多條子曲線,每一條子曲線仍是貝茲曲線。
- 一些看似簡(jiǎn)單的曲線(如圓)無(wú)法以貝茲曲線精確的描述,或分段成貝茲曲線(雖然當(dāng)每個(gè)內(nèi)部控制點(diǎn)對(duì)單位圓上的外部控制點(diǎn)水平或垂直的的距離為
時(shí),分成四段的貝茲曲線,可以小於千分之一的最大半徑誤差近似於圓)。
- 位於固定偏移量的曲線(來(lái)自給定的貝茲曲線),又稱(chēng)作偏移曲線(假平行於原來(lái)的曲線,如兩條鐵軌之間的偏移)無(wú)法以貝茲曲線精確的形成(某些瑣屑實(shí)例除外)。無(wú)論如何,現(xiàn)存的啟發(fā)法通常可為實(shí)際用途中給出近似值。
[編輯] 建構(gòu)貝茲曲線
[編輯] 線性曲線
![線性貝茲曲線演示動(dòng)畫(huà),t in [0,1]](http://upload.wikimedia.org/wikipedia/commons/8/89/Bezier_1_big.gif) |
線性貝茲曲線演示動(dòng)畫(huà),t in [0,1] |
線性貝茲曲線函數(shù)中的 t 會(huì)經(jīng)過(guò)由 P0 至 P1 的 B(t) 所描述的曲線。例如當(dāng) t=0.25 時(shí),B(t) 即一條由點(diǎn) P0 至 P1 路徑的四分之一處。就像由 0 至 1 的連續(xù) t,B(t) 描述一條由 P0 至 P1 的直線。
[編輯] 二次曲線
為建構(gòu)二次貝茲曲線,可以中介點(diǎn) Q0 和 Q1 作為由 0 至 1 的 t:
- 由 P0 至 P1 的連續(xù)點(diǎn) Q0,描述一條線性貝茲曲線。
- 由 P1 至 P2 的連續(xù)點(diǎn) Q1,描述一條線性貝茲曲線。
- 由 Q0 至 Q1 的連續(xù)點(diǎn) B(t),描述一條二次貝茲曲線。
 |
|
![二次貝茲曲線演示動(dòng)畫(huà),t in [0,1]](http://upload.wikimedia.org/wikipedia/commons/2/2d/Bezier_2_big.gif) |
二次貝茲曲線的結(jié)構(gòu) |
|
二次貝茲曲線演示動(dòng)畫(huà),t in [0,1] |
[編輯] 高階曲線
為建構(gòu)高階曲線,便需要相應(yīng)更多的中介點(diǎn)。對(duì)於三次曲線,可由線性貝茲曲線描述的中介點(diǎn) Q0、Q1、Q2,和由二次曲線描述的點(diǎn) R0、R1 所建構(gòu):
 |
|
![三次貝茲曲線演示動(dòng)畫(huà),t in [0,1]](http://upload.wikimedia.org/wikipedia/commons/f/ff/Bezier_3_big.gif) |
三次貝茲曲線的結(jié)構(gòu) |
|
三次貝茲曲線演示動(dòng)畫(huà),t in [0,1] |
對(duì)於四次曲線,可由線性貝茲曲線描述的中介點(diǎn) Q0、Q1、Q2、Q3,由二次貝茲曲線描述的點(diǎn) R0、R1、R2,和由三次貝茲曲線描述的點(diǎn) S0、S1 所建構(gòu):
 |
|
![四次貝茲曲線演示動(dòng)畫(huà),t in [0,1]](http://upload.wikimedia.org/wikipedia/commons/7/7d/Bezier_4_big.gif) |
四次貝茲曲線的結(jié)構(gòu) |
|
四次貝茲曲線演示動(dòng)畫(huà),t in [0,1] |
(還可參閱五階貝茲曲線的構(gòu)成。)
[編輯] 應(yīng)用
[編輯] 電腦繪圖
貝塞爾曲線被廣泛地在計(jì)算機(jī)圖形中用來(lái)為平滑曲線建立模型。
二次和三次貝塞爾曲線最為常見(jiàn)
[編輯] 程式範(fàn)例
下列程式碼為一簡(jiǎn)單的實(shí)際運(yùn)用範(fàn)例,展示如何使用 C 標(biāo)出三次方貝茲曲線。注意,此處僅簡(jiǎn)單的計(jì)算多項(xiàng)式係數(shù),並讀盡一系列由 0 至 1 的 t 值;實(shí)踐中一般不會(huì)這麼做,遞歸求解通常會(huì)更快速——以更多的記憶體為代價(jià),花費(fèi)較少的處理器時(shí)間。不過(guò)直接的方法較易於理解並產(chǎn)生相同結(jié)果。以下程式碼已使運(yùn)算更為清晰。實(shí)踐中的最佳化會(huì)先計(jì)算係數(shù)一次,並在實(shí)際計(jì)算曲線點(diǎn)的迴圈中反複使用。此處每次都會(huì)重新計(jì)算,損失了效率,但程式碼更清楚易讀。
曲線的計(jì)算可在曲線陣列上將相連點(diǎn)畫(huà)上直線——點(diǎn)越多,曲線越平滑。
在部分架構(gòu)中,下以程式碼也可由動(dòng)態(tài)程式設(shè)計(jì)進(jìn)行最佳化。舉例來(lái)說(shuō),dt 是一個(gè)常數(shù),cx * t 則等同於每次反覆就修改一次常數(shù)。經(jīng)反覆應(yīng)用這種最佳化後,迴圈可被重寫(xiě)為沒(méi)有任何乘法(雖然這個(gè)過(guò)程不是穩(wěn)定數(shù)值的)。
/*
產(chǎn)生三次方貝茲曲線的程式碼
*/
typedef struct
{
float x;
float y;
}
Point2D;
/*
cp 在此是四個(gè)元素的陣列:
cp[0] 為起始點(diǎn),或上圖中的 P0
cp[1] 為第一個(gè)控制點(diǎn),或上圖中的 P1
cp[2] 為第二個(gè)控制點(diǎn),或上圖中的 P2
cp[3] 為結(jié)束點(diǎn),或上圖中的 P3
t 為參數(shù)值,0 <= t <= 1
*/
Point2D PointOnCubicBezier( Point2D* cp, float t )
{
float ax, bx, cx;
float ay, by, cy;
float tSquared, tCubed;
Point2D result;
/* 計(jì)算多項(xiàng)式係數(shù) */
cx = 3.0 * (cp[1].x - cp[0].x);
bx = 3.0 * (cp[2].x - cp[1].x) - cx;
ax = cp[3].x - cp[0].x - cx - bx;
cy = 3.0 * (cp[1].y - cp[0].y);
by = 3.0 * (cp[2].y - cp[1].y) - cy;
ay = cp[3].y - cp[0].y - cy - by;
/* 計(jì)算位於參數(shù)值 t 的曲線點(diǎn) */
tSquared = t * t;
tCubed = tSquared * t;
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
return result;
}
/*
ComputeBezier 以控制點(diǎn) cp 所產(chǎn)生的曲線點(diǎn),填入 Point2D 結(jié)構(gòu)的陣列。
呼叫者必須分配足夠的記憶體以供輸出結(jié)果,其為 <sizeof(Point2D) numberOfPoints>
*/
void ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve )
{
float dt;
int i;
dt = 1.0 / ( numberOfPoints - 1 );
for( i = 0; i < numberOfPoints; i++)
curve[i] = PointOnCubicBezier( cp, i*dt );
}
另一種貝茲曲線的應(yīng)用是在動(dòng)畫(huà)中,描述物件的運(yùn)動(dòng)路徑等等。此處,曲線的 x、y 位置不用來(lái)標(biāo)示曲線,但用來(lái)表示圖形位置。當(dāng)用在這種形式時(shí),連續(xù)點(diǎn)之間的距離會(huì)變的更為重要,且大多不是平均比例。點(diǎn)將會(huì)串的更緊密,控制點(diǎn)更接近每一個(gè)點(diǎn),而更為稀疏的控制點(diǎn)會(huì)散的更開(kāi)。如果需要線性運(yùn)動(dòng)速度,進(jìn)一步處理時(shí)就需要循所需路徑將點(diǎn)平均分散。
[編輯] 有理貝茲曲線
有理貝茲增加可調(diào)節(jié)的權(quán)重,以提供更近似於隨意的形狀。分子是加權(quán)的伯恩斯坦形式貝茲曲線,而分母是加權(quán)的伯恩斯坦多項(xiàng)式的總和。
給定 n + 1 控制點(diǎn) Pi,有理貝茲曲線可如下描述:
或簡(jiǎn)單的
[編輯] 參閱
[編輯] 參考文獻(xiàn)