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 ]
            ); 
        }
相关文章
相关标签/搜索