轉自https://github.com/hujiulong/blog/issues/1 喜歡的能夠去給原做者點贊 謝謝~~~git
開個新坑。。鑑於本人數學還給了體育老師,原做者一筆帶過的問題本人作了詳細分析。沒有對比就沒有傷害啊啊啊==github
ps:目前本人的數學水平不是高等數學,甚至不如高中數學了了了。。。學習
貝塞爾公式:spa
二次貝塞爾曲線動態圖:3d
靜態圖:code
三次貝塞爾曲線動態圖:blog
四次貝塞爾曲線動態圖:數學
五次貝塞爾曲線動態圖:it
三四五次貝塞爾曲線動態圖沒啥用,看看就行。io
最終效果:
由簡入繁,首先實現一條靜態貝塞爾曲線。此時用戶須要提供三個點,p0,控制點,p2
/* *繪製二次貝塞爾曲線路徑1 *@param {Object} ctx *@param {Array<number>} p0 *@param {Array<number>} p1 *@param {Array<number>} p2 */ function drawCurvePath(ctx,p0,p1,p2){ ctx.moveTo(p0[0],p0[1]); ctx.quadraticCurveTo( p1[0],p1[1], p2[0],p2[1] ); }
原做者的話:
若是咱們是在作一個圖形庫,咱們想給使用者提供一個繪製曲線的方法。
對於使用者來講,他只想在給定的起點和終點間間繪製一條曲線,他想要獲得的曲線儘可能美觀,可是又不想關心具體的實現細節,若是還須要給第三個點,使用者會有必定的學習成本(至少須要弄明白什麼是貝塞爾曲線)。
看到這裏你可能會比較疑惑,即便是二次貝塞爾曲線也須要三個控制點,只有起點和終點怎麼繪製曲線呢。
咱們能夠在起點和終點的垂直平分線上選一點做爲第三個控制點,能夠提供給使用者一個參數來控制曲線的彎曲程度
圖1-1
如上所示:向量BA = 向量OA - 向量OB = [ Ax - Bx , Ay - By];爲了方便展現,長度方向一致的向量也爲相等向量。
圖1-2
如圖所示,圖1-2中向量OA 和 圖1-1中的向量BA爲相等向量 設向量BA 爲 v
向量OC 垂直於 OA 那麼向量OC 座標爲 [ v1, -v0 ] = [Ay - By,Bx-Ax]
把向量OC平移到向量OA的中垂線重合的地方 ,以下圖
此時向量OD座標爲向量OC座標[Ay - By,Bx-Ax]+向量OA中點座標 此時控制點爲D
而t = [0-1] 決定了 曲線的彎曲程度
/* *繪製曲線路徑 *@param {CanvasRenderingContext2D} ctx *@param {Array<number>} start *@param {Array<number>} end *@param {number} curvature 曲度 */ function drawCurvePath( ctx, start, end, curveness ) { // 計算中間控制點 /* *中間控制點cp cp = start和end中點座標 + 向量od (向量od長度爲起點到終點線段的長度,方向爲起點到終點線段的垂直平分線) *curveness */ var cp = [ ( start[ 0 ] + end[ 0 ] ) / 2 + ( start[ 1 ] - end[ 1 ] ) * curveness, ( start[ 1 ] + end[ 1 ] ) / 2 -+( end[ 0 ] - start[ 0 ] ) * curveness ]; ctx.moveTo( start[ 0 ], start[ 1 ] ); ctx.quadraticCurveTo( cp[ 0 ], cp[ 1 ], end[ 0 ], end[ 1 ] ); }