貝塞爾曲線解析-Cocos2dx 01

      在數學數值分析領域中,貝塞爾曲線英語:Bézier curve)是電腦圖形學中至關重要的參數曲線。更高維度的普遍化貝塞爾曲線就稱做貝塞爾曲面,其中貝塞爾三角是一種特殊的實例。php

       貝塞爾曲線於1962年,由法國工程師皮埃爾·貝塞爾(Pierre Bézier)所普遍發表,他運用貝塞爾曲線來爲汽車的主體進行設計。貝塞爾曲線最初由Paul de Casteljau於1959年運用de Casteljau算法開發,以穩定數值的方法求出貝塞爾曲線。html

 

線性貝塞爾曲線[編輯]web

     給定點P0P1,線性貝塞爾曲線只是一條兩點之間的直線。這條線由下式給出:算法

  • \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]

且其等同於線性插值數組

      線性貝塞爾曲線函數中的t會通過由P0P1Bt)所描述的曲線。例如當t=0.25時,Bt)即一條由點P0P1路徑的四分之一處。就像由0至1的連續tBt)描述一條由P0P1的直線。架構

二次方貝塞爾曲線[編輯]

     二次方貝塞爾曲線的路徑由給定點P0P1P2的函數Bt)追蹤:函數

  • \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字型就運用了以貝塞爾樣條組成的二次貝塞爾曲線。ui

 

     爲建構二次貝塞爾曲線,能夠中介點Q0Q1做爲由0至1的tspa

  • P0P1的連續點Q0,描述一條線性貝塞爾曲線。

  • P1P2的連續點Q1,描述一條線性貝塞爾曲線。

  • Q0Q1的連續點Bt),描述一條二次貝塞爾曲線。

  •           

     

三次方貝塞爾曲線[編輯]

       P0P1P2P3四個點在平面或在三維空間中定義了三次方貝塞爾曲線。曲線起始於P0走向P1,並從P2的方向來到P3。通常不會通過P1P2;這兩個點只是在那裏提供方向資訊。P0P1之間的間距,決定了曲線在轉而趨進P3以前,走向P2方向的「長度有多長」。

曲線的參數形式爲:

  • \mathbf{B}(t)=\mathbf{P}_0(1-t)^3+3\mathbf{P}_1t(1-t)^2+3\mathbf{P}_2t^2(1-t)+\mathbf{P}_3t^3 \mbox{ , } t \in [0,1]

現代的成象系統,如PostScriptAsymptoteMetafont,運用了以貝塞爾樣條組成的三次貝塞爾曲線,用來描繪曲線輪廓。

       

       對於四次曲線,可由線性貝塞爾曲線描述的中介點Q0Q1Q2Q3,由二次貝塞爾曲線描述的點R0R1R2,和由三次貝塞爾曲線描述的點S0S1所建構:

    

程式範例

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

在部分架構中,下以程式碼也可由動態規劃進行最優化。舉例來講,dt是一個常數,cx * t則等同於每次反覆就修改一次常數。經反覆應用這種最優化後,循環可被重寫爲沒有任何乘法(雖然這個過程不是穩定數值的)。

/*
 產生貝塞爾曲線的算法
*/
 typedef struct{
    float x;
    float y;}Point2D;
 /*
  cp 在此是四個元素的數組: 
  cp[0] 爲起點,或上圖中的 P0 
  cp[1] 爲第一控制點,或上圖中的 P1 
  cp[2] 爲第二控制點,或上圖中的 P2 
  cp[3] 爲結束點,或上圖中的 P3 
  t 爲參數值,0 <= t <= 1
*/
 Point2D PointOnCubicBezier( Point2D* cp, float t ){
    float   ax, bx, cx;
    float   ay, by, cy;
    float   tSquared, tCubed;
    Point2D result;
 
    /*計算多項式係數 */
 
    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;
 
    /*計算t位置的點值*/
 
    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 以控制點 cp 所產生的曲線點,填入 Point2D 結構數組。 
    調用方必須分配足夠的空間以供輸出,<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 );}

   在歷史上,研究貝塞爾曲線的人最初是按照已知曲線參數方程來肯定四個點的思路設計出這種矢量曲線繪製法。

   若是已知一條曲線的參數方程,係數都已知,而且兩個方程裏都含有一個參數t,它的值介於0、1之間,表現形式以下所示:
x(t) = ax * t ^ 3 + bx * t ^ 2 + cx * t + x0
y(t) = ay * t ^ 3 + by * t ^ 2 + cy * t + y0

因爲這條曲線的起點(x0,y0)是已知的,咱們能夠用如下的公式來求得剩餘三個點的座標:
x1 = x0 + cx / 3
x2 = x1 + ( cx + bx ) / 3
x3 = x0 + cx + bx + ax

y1 = y0 + cy / 3
y2 = y1 + ( cy + by ) / 3
y3 = y0 + cy + by + ay

仔細觀察一下就知道了,不管方程的已知和所求是什麼,老是有六個未知數,而且咱們總能找到六個等式(記住(x0,y0)老是已知的),也就是說,上面的方法是徹底可逆的,所以咱們能夠根據四個已知點座標來反求曲線參數公式的係數。稍微一變換就獲得了下面這組公式:
cx = 3 * ( x1 - x0 )
bx = 3 * ( x2 - x1 ) - cx
ax = x3 - x0 - cx - bx

cy = 3 * ( y1 - y0 )
by = 3 * ( y2 - y1 ) - cy
ay = y3 - y0 - cy - by

因此說,對於座標任意的四個已知點,你總能建立一條貝塞爾曲線這樣在邏輯判斷及使用中就能夠建立本身所需的貝塞爾曲線效果。

參考:

http://zh.wikipedia.org/wiki/貝茲曲線

http://blog.chinaunix.net/uid-20622737-id-3161025.html

相關文章
相關標籤/搜索