Canvas HTML - плавность между линией T и кривой Безье - PullRequest
0 голосов
/ 25 мая 2019

Возможно, это скорее математический вопрос, но давайте посмотрим:

Я использую HTML5 Canvas для рисования линейной диаграммы.Диаграмма в основном Позиция X Время.Каждая строка представляет транспортное средство в позиции (Y) в данный момент времени (X).У меня есть только информация о том, когда транспортное средство проезжало определенные точки на дороге.Поэтому, если транспортное средство останавливается между двумя точками, у меня нет информации о том, что оно фактически остановилось, но когда оно пройдет через следующую точку, я смогу провести линию, которая будет почти горизонтальной, потому что средняя скорость, то есть линиянаклон будет очень маленьким.

В этих сценариях мы определили, что если транспортное средство двигалось ниже 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 голосов
/ 27 мая 2019

Я нашел хорошее решение для моей проблемы: использование интерполяции строк.

Имея следующие сегменты и представьте, что я хочу сгладить все в диапазоне от B до C, как я могу выбрать несколько точек Безье, которые бы гарантировали гладкую кривую вместо ломаной?

The scenario before smoothing

Сначала я интерполирую сегмент AB и нахожу точку B', которая является точкой, в которой линия AB коснется координаты Y для C.Затем я использую тот же процесс, чтобы найти C':

Interpolating points

Точки B' и C' дают хорошие очки для Безье в порядкечтобы сгладить все до горизонтальной линии:

bezier curve using B' and C'

Это также достаточно просто в вычислительном отношении, поскольку найти линейное уравнение довольно просто.

...