javascript - Canvas HTML - lineTo 和 Bezier 曲线之间的平滑度

标签 javascript html math canvas bezier

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

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

在这些场景中,我们定义了如果车辆移动速度低于 10Km/h,我应该认为它停止了并且应该画一条水平平滑线。

基本上我必须改变这个:

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>

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

感谢您的任何提示!

最佳答案

我找到了解决问题的好方法:使用线插值。

有了以下片段,想象一下我想要平滑 BC 之间的东西,我怎样才能选择一些贝塞尔点来保证平滑的曲线而不是 splinter 的曲线?

The scenario before smoothing

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

Interpolating points

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

bezier curve using B' and C'

这在计算上也足够简单,因为找到直线方程相当简单。

关于javascript - Canvas HTML - lineTo 和 Bezier 曲线之间的平滑度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56299742/

相关文章:

html - 在 Internet Explorer 的浏览器后退按钮上关闭表单字段自动完成

opencv - 降采样但不完全划分的影响

Java双丢精度计算

javascript - 在mvc3中动态添加javascript函数

javascript - 另一种获取数组 Javascript 整数的所有组合的方法

javascript - 为什么这个 map reduce Promises 数组不起作用,但只是减少它呢?

math - 是否可以创建允许 360 度旋转的四元数扭曲解决方案?

javascript - 设置 Apple TV 视频 JavaScript

css - 文章分页类拆分 div 并弄乱页面布局

html - 光标 : pointer on a div does not work