canvas 貝塞爾曲線動畫繪製

轉自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 ]
            ); 
        }
相關文章
相關標籤/搜索