canvas 贝塞尔曲线动画绘制

转自https://github.com/hujiulong/blog/issues/1 喜欢的可以去给原作者点赞 谢谢~~~

开个新坑。。鉴于本人数学还给了体育老师,原作者一笔带过的问题本人做了详细分析。没有对比就没有伤害啊啊啊==

ps:目前本人的数学水平不是高等数学,甚至不如高中数学了了了。。。

贝塞尔公式:

二次贝塞尔曲线动态图:

静态图:

三次贝塞尔曲线动态图:

四次贝塞尔曲线动态图:

五次贝塞尔曲线动态图:

三四五次贝塞尔曲线动态图没啥用,看看就行。

最终效果:

由简入繁,首先实现一条静态贝塞尔曲线。此时用户需要提供三个点,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 ]
            ); 
        }

 

转载于:https://www.cnblogs.com/liuxinxin4288/p/9451100.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值