两条平滑曲线相乘_平滑多条曲线

Canvas 画曲线(非圆弧)有两个方法:

1. quadraticCurveTo(cpx, cpy, x, y)

2. bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

本文只讲quadraticCurveTo(),先来看如何画一条曲线。

我们需要曲线的 开始点(p0) 和 结束点(p1),外加一个控制点(pc),虽然说有3个点,但实际画图时,我们关心的只是开始点和结束点

可以看到曲线经过 p0 和 p1 两个点,控制点pc 只是用来调整曲线的形状的。

如果曲线要经过3个点呢?不好做了吧?

这里介绍一个公式,从上图可知,曲线不经过控制点,但曲线肯定会经过某个点,这个点怎么求呢?

xc = x1 * 2 - (x0 + x2) / 2;

yc = y1 * 2 - (y0 + y2) / 2;

(x0, y0) 是开始点,(x2, y2) 是结束点,(xc, yc) 是控制点,而 (x1, y1) 则是曲线会经过的某点。

继续刚才的3点画线,我们可以把第二个点当作点(x1, y1),于是

如果有4个点呢?这里需要总结一个算法,先看一个图:

首先声明一下,这张图原本不是用来解释本文的,我从别处截来,但是可以讲解我想说的东西。

这条曲线很平滑,注意中间的两个黑点,他俩都是相邻控制点的中点,于是我得出了以下结论:

通过第一个控制点,循环算出之后的控制点,相邻的两个控制点的中点是曲线会经过的点。

仔细看3个点的例子,我们算出了控制点,它就是第一个控制点。

第二个控制点怎么算呢?

我们知道曲线会经过p2,所以 p2 是第一个控制点 和 第二个控制点的中点,于是

// (ctrlX, ctrlY) 是第一个控制点

ctrlX = 2 * x2 - ctrlX;

ctrlY = 2 * y2 - ctrlY;

之后的控制点都可以这样计算,下面我给出一段算法:

/**

* @param {object} c 即canvas.getContext('2d')

* @param {array} points 数组元素格式为{x: 0, y: 0}

*/

function drawMultipleCurves(c, points) {

var len = points.length;

if (len < 3) {

return;

}

// 计算第一个控制点

var ctrlX = 2 * points[1].x - 0.5 * (points[0].x + points[2].x);

ctrlY = 2 * points[1].y - 0.5 * (points[0].y + points[2].y);

// 画出前三个点的曲线

c.beginPath();

c.moveTo(points[0].x, points[0].y);

c.quadraticCurveTo(ctrlX, ctrlY, points[2].x, points[2].y);

if (len === 3) {

c.stroke();

return;

}

for (var i = 2; i < len - 1; i++) {

// 计算下个控制点

ctrlX = 2 * points[i].x - ctrlX;

ctrlY = 2 * points[i].y - ctrlY;

c.quadraticCurveTo(ctrlX, ctrlY, points[i + 1].x, points[i + 1].y);

}

c.stroke();

}

最后看一个经过6个点的曲线吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值