画布HTML-lineTo和Bezier曲线之间的平滑度

时间:2019-05-24 21:32:08

标签: javascript html math canvas bezier

也许这是一个数学问题,但让我们看看:

我正在使用HTML5画布绘制折线图。 图表基本上是位置X时间。 每条线代表给定时间(X)中处于位置(Y)的车辆。 我只知道车辆何时通过道路上的确定点。因此,如果车辆在两点之间停止,我没有它实际停止的信息,但是当它经过下一个点时,我将能够绘制一条几乎是水平的线,因为平均速度即该线斜率会很小。

在这些情况下,我们定义了,如果车辆行驶速度低于10公里/小时,我应该考虑将其停下来并绘制一条水平的平滑线。

基本上,我必须对此进行转换:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';

ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);
ctx.lineTo(220, 70);
ctx.lineTo(240, 110);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

对此:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';

ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);

ctx.bezierCurveTo(
  50, 70,
  210, 50,
  220, 70
)

ctx.lineTo(240, 110);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

问题是:我如何为贝塞尔曲线点选择好的值? 在上面的示例中,我已经通过实验完成了。我找不到一种以编程方式选择好的点值的方法,因此我的线看起来不会像这样糟糕:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';

ctx.beginPath();
ctx.moveTo(0, 30);
ctx.lineTo(20, 50);

ctx.bezierCurveTo(
  20, 70,
  180, 50,
  220, 70
)

ctx.lineTo(240, 110);
ctx.stroke();


ctx.beginPath();
ctx.moveTo(0, 80);
ctx.lineTo(20, 100);

ctx.bezierCurveTo(
  20, 120,
  220, 100,
  220, 120
)

ctx.lineTo(280, 150);
ctx.stroke();
<canvas id="myCanvas" width="300" height="170" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

我正在寻找一种计算简单的解决方案,因为每次都会用很多行重绘此解决方案,所以我不希望这会降低性能。

感谢任何提示!

1 个答案:

答案 0 :(得分:0)

我找到了一个很好的解决方案:使用线插值。

具有以下几段,并想像一下我想在BC之间进行平滑处理,如何选择一些能保证平滑曲线而不是折断的贝塞尔曲线点?

The scenario before smoothing

首先,我对段AB进行插值,并找到点B',这是线AB会触及C的Y坐标的点。然后,我使用相同的过程来找到C'

Interpolating points

B'C'为贝塞尔曲线提供了很好的点,以使事物平滑到一条水平线:

bezier curve using B' and C'

这在计算上也很简单,因为找到线方程很简单。