返回

曲线连接不平滑分析与解决

前端

在实际开发中,偶尔会出现曲线是圆滑的,但是端点连接处不是平滑的现象,这种情况往往在选择日期较少,端点两边的曲线斜率相对值差别较大时出现。 使用 Echarts 的在线编辑可以很容易复现出来。 在展开具体分析之前,我们先介绍一下背景知识。

我们先想一下如何在两点之间画一条曲线,比方说在笛卡尔坐标系中,我们有 (2, 3) 和 (5, 7) 两个点,如何在这两个点之间画一条曲线呢? 直观上来看,两条直线都应该可以,但其实两条直线之间的面积并不是最小的,也就是说,在两条直线以外,还有其他的曲线面积更小。

有一条神奇的曲线可以让我们用一个公式表示整个曲线的过程,我们称之为参数方程。 例如,对于一般的二次贝塞尔曲线,其参数方程如下:

$B(t) = (1 - t)^2P_0 + 2t(1 - t)P_1 + t^2P_2, \quad 0 \le t \le 1$

其中,(P_0), (P_1), (P_2) 是控制点,(t) 是参数。

当我们只有两个控制点时,经过数学推导可以得到一个简化后的公式:

$B(t) = (1 - t)P_0 + tP_1, \quad 0 \le t \le 1$

根据该公式,我们很容易用代码实现出两点之间的曲线绘制:

function drawCurve(ctx, x0, y0, x1, y1) {
    ctx.moveTo(x0, y0);
    for (let t = 0; t <= 1; t += 0.01) {
        let x = (1 - t) * x0 + t * x1;
        let y = (1 - t) * y0 + t * y1;
        ctx.lineTo(x, y);
    }
}

现在我们再回到 Echarts 曲线连接不平滑的问题。当我们只有两个数据点时,Echarts 默认使用上面介绍的贝塞尔曲线进行连接。 但是,当数据点较少时,端点两边的曲线斜率相对值差别较大,会导致贝塞尔曲线在端点处不平滑。

为了解决这个问题,我们可以使用其他的曲线拟合算法,例如三次样条曲线或三次 B 样条曲线。这些曲线拟合算法可以生成更平滑的曲线,即使在端点处也是如此。

在 Echarts 中,我们可以通过设置 smooth 选项来选择不同的曲线拟合算法。例如,要使用三次样条曲线,我们可以设置 smooth: true

var myChart = echarts.init(document.getElementById('main'));

var option = {
    series: [{
        type: 'line',
        smooth: true,
        data: [2, 3, 5, 7]
    }]
};

myChart.setOption(option);

通过设置 smooth 选项,我们就可以得到一条平滑的曲线,即使在端点处也是如此。