2013-03-13 124 views
4

我有一個具有2個控制點的三次貝塞爾曲線。起點和控制點是已知的。在給定控制點,起點和終點的情況下,需要獲得曲線的所有點。 我想要實現的是給定一個從1到曲線長度的值。獲得每個點在該位置的X和Y以及alpha(角度)。 我找不到一個很好的參考或工作代碼。 我使用的是javascript。在javascript中查找三次貝塞爾曲線的所有點

+0

那裏尋找:http://stackoverflow.com/questions/4089443/find-the-tangent-of-a-point-on-a-cubic-bezier-curve-on-an-iphone – XDnl 2013-03-13 22:46:48

回答

15

如果我理解正確,您正試圖確定Bezier在每個點上的位置和斜率(曲線的切線)。我們假設你的起點是(ax,ay),終點是(dx,dy),你的控制點是(bx,by)和(cx,cy)。

位置很簡單。首先,計算混合函數。這些控制曲線上控制點的「效果」。

B0_t = (1-t)^3 
B1_t = 3 * t * (1-t)^2 
B2_t = 3 * t^2 * (1-t) 
B3_t = t^3 

請注意,當t爲0(且其他一切爲零)時,B0_t是1。此外,當t是1時(並且其他一切都爲零),B3_t是1。所以曲線從(ax,ay)開始,到(dx,dy)結束。

任何中間點(px_t,py_t)將通過以下給出(變化噸從0到1,在一個循環內小的增量):

px_t = (B0_t * ax) + (B1_t * bx) + (B2_t * cx) + (B3_t * dx) 
py_t = (B0_t * ay) + (B1_t * by) + (B2_t * cy) + (B3_t * dy) 

斜率也是容易做到的。使用https://stackoverflow.com/a/4091430/1384030

B0_dt = -3(1-t)^2 
B1_dt = 3(1-t)^2 -6t(1-t) 
B2_dt = - 3t^2 + 6t(1-t) 
B3_dt = 3t^2 

給出的方法,所以x和y的變化率是:

px_dt = (B0_dt * ax) + (B1_dt * bx) + (B2_dt * cx) + (B3_dt * dx) 
py_dt = (B0_dt * ay) + (B1_dt * by) + (B2_dt * cy) + (B3_dt * dy) 

然後用Math.atan2(py_dt,px_dt)得到角(弧度)。

4

De Casteljau algorithm更具數值穩定性。這裏還有一個額外的好處,就是它可以計算切點(即切線角度)作爲計算該點前的步驟。

但是,它按照參數值工作,而不是長度。作爲繪製曲線的一部分,最好按參數計算點數,而不是數值。參數的範圍將分別爲​​,0對應的起始點和1曲線的終點。

+2

是的,它有三個優點。 *適用於任何程度的樣條,無需修改。 *它不需要電源功能。 *最有價值的是結果具有參數「t」的切線和點,因此,對於需要解析公式在計算上更簡單的情況。 – divanov 2013-04-03 20:07:02