转自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 ] ); }