2012年9月27日 星期四

  Bezier curve  - 貝茲曲線

          修電腦圖學的一定聽過它, 詳細說明可以去wiki看,在我認為它是種可參數化(畫XD)的曲線,為什麼要理解它呢? 因為有時候你必須自己製造所想要的曲線出來,,你可以由輸入的起點,控制點,終點做出想要的曲線出來!!

這裡實作二次Bezier curve:

首先要知道線性貝茲曲線的定義:

B(t) = P0 + (P1-P0)t  = (1-t)P0 + tP1  , t在[0,1]區間內  --------(1)
P0,P1可以想成一條直線上的兩個端點,而在這條直線上的任意一點為B點,
(其實由向量空間可以看的出來,B點為原點(P0)加上Vector(P1-P0)做normalize後乘以純量 )
所以參數化表示後就如同公式(1)





在這邊可得知一次貝茲公式可得 一條直線線段,那二次就可以得到曲線線段了:


二次貝茲曲線還要再加入第三個點--->控制點  ,由控制點來控制曲線彎曲的幅度如上圖
所以要求得B點很簡單先求得Q0點再求得Q1點,接者就可以求出目前的B點

a :  Q0(t) =  (1-t)P0 + P1

b:  Q1(t)  = (1-t)P1+  P2

c: B(t) = (1-t)Q0 + Q1

t 在0,1區間內

把  a跟b所求得的 Q0 跟Q1帶入 c式  可得 -> B(t) = ((1-t)^2)*P0 + 2(1-t)(t)*P1 + (t^2)*P2

這邊附上demo 影片 以及部分 C# code

code : private void calculate(PointF start,PointF control,PointF end)
{ if (t < 1)
{
B_t.X = ((float)Math.Pow((1 - t), 2)) * start.X + ((float)(2 * (1 - t) *t*control.X + ((float)Math.Pow(t, 2)) * end.X;

B_t.Y = ((float)Math.Pow((1 - t), 2)) * start.Y + ((float)(2 * (1 - t) * t)) * control.Y + ((float)Math.Pow(t, 2)) * end.Y;

g_for_image[0].FillEllipse(Brushes.Black, B_t.X, B_t.Y, 5, 5);



t = t + 0.01;

calculate(start, control, end);

}
}

;