// Функция рисует линию по указанным точка. function drawCurve(points) { const context = canvas.getContext("2d"); context.lineWidth = 10; context.strokeStyle = "#4663C9" context.beginPath(); context.moveTo(points[0].x, points[0].y); for (let index = 1; index < points.length; index++) { context.lineTo(points[index].x, points[index].y); } context.stroke(); }
Используя функцию drawCurve рисование кривой будет выглядеть следующим образом:
const points = [ { x: 100, y: 100 }, { x: 200, y: 100 }, { x: 200, y: 200 }, { x: 300, y: 200 }, { x: 300, y: 100 }, { x: 400, y: 100 } ] drawCurve(points)
Используя формулу из предыдущего раздела реализуем функцию smoothing, которая создает две новые точки на каждую прямую образованную между оригинальными точками переданными в качестве аргумента функции smoothing:
// Функция создает новые точки используя алгоритм Чайкина. function smoothing(points) { const result = [points[0]] let index = 0 const last_index = points.length - 1 while (index < last_index) { const first = points[index] const second = points[index + 1] // Определение длины отрезка const dx = second.x - first.x const dy = second.y - first.y // 25% и 75% относительно длины полученного отрезка result.push({x: first.x + dx * 0.25, y: first.y + dy * 0.25}) result.push({x: first.x + dx * 0.75, y: first.y + dy * 0.75}) index++ } result.push(points[last_index]) return result }
Доработаем функцию drawCurve, таким образом чтобы перед рисованием она вызывала smoothing для сглаживания кривой.
// Функция рисует линию по указанным точка. function drawCurve(points) { // Создание новых точек для сглаживания кривой points = smoothing(points) const context = canvas.getContext("2d"); context.lineWidth = 10; context.strokeStyle = "#4663C9" context.beginPath(); context.moveTo(points[0].x, points[0].y); for (let index = 1; index < points.length; index++) { context.lineTo(points[index].x, points[index].y); } context.stroke(); }
Новая версия функции drawCurve рисует следующую кривую:
На изображении выше кривая стала более плавной, но выглядит все еще ломанной. Для того, чтобы избавиться от резких углов на нашей кривой достаточно повторить алгоритм несколько раз увеличив количество точек для рисования кривой. Доработаем функцию drawCurve еще раз.
// Функция рисует линию по указанным точка. function drawCurve(points, smooth) { // Создание новых точек для сглаживания кривой for (let i = 0; i < smooth; i++) { points = smoothing(points) } const context = canvas.getContext("2d"); context.lineWidth = 10; context.strokeStyle = "#4663C9" context.beginPath(); context.moveTo(points[0].x, points[0].y); for (let index = 1; index < points.length; index++) { context.lineTo(points[index].x, points[index].y); } context.stroke(); }
Новый аргумент smooth управляет количеством итераций сглаживания, для получения плавной кривой 3 итерация будет достаточно.
const points = [ { x: 100, y: 100 }, { x: 200, y: 100 }, { x: 200, y: 200 }, { x: 300, y: 200 }, { x: 300, y: 100 }, { x: 400, y: 100 } ] drawCurve(points, 3)
Весь исходный код примеров к данной статье вы можете найти на GitHub.