Как обычно лень писать, поэтому вот результат.
/*
* Кривые Безье
*/
var Bezier = function() {}
/*
* Получить точку
* @param float x
* @param float y
* @return object
*/
Bezier.prototype.getPoint = function(x, y) {
return {
x: x,
y: y
};
}
/*
* Добавить точки для отрисовки
* @param array points
*/
Bezier.prototype.pushPoints = function(points) {
this.points = points;
}
/*
* Точки для отрисовки
* @var array
*/
Bezier.prototype.points = [ ];
/*
* Линейная
* @param float t
* @return object
*/
Bezier.prototype.linear = function(t) {
return this.getPoint(
(1 - t) * this.points[0].x + t * this.points[1].x,
(1 - t) * this.points[0].y + t * this.points[1].y
);
}
/*
* Квадратичная
* @param float t
* @return object
*/
Bezier.prototype.quadratic = function(t) {
return this.getPoint(
(1 - t) * (1 - t) * this.points[0].x + 2 * (1 - t) * t * this.points[1].x + t * t * this.points[2].x,
(1 - t) * (1 - t) * this.points[0].y + 2 * (1 - t) * t * this.points[1].y + t * t * this.points[2].y
);
}
/*
* Кубическая
* @param float t
* @return object
*/
Bezier.prototype.cubic = function(t) {
return this.getPoint(
(1 - t) * (1 - t) * (1 - t) * this.points[0].x + 3 * (1 - t) * (1 - t) * t * this.points[1].x + 3 * (1 - t) * t * t * this.points[2].x + t * t * t * this.points[3].x,
(1 - t) * (1 - t) * (1 - t) * this.points[0].y + 3 * (1 - t) * (1 - t) * t * this.points[1].y + 3 * (1 - t) * t * t * this.points[2].y + t * t * t * this.points[3].y
);
}
<html> <head> <title></title> <style> body { background-color: #2d2d30; } canvas { background-color: #ffffff; width: 600px; height: 600px; display: block; margin: 0 0 10px 0; } .legend { background-color: #e6e7e8; width: 590px; padding: 5px; } .black { color: #000; } .blue { color: #0000ff; } .green { color: #008000; } </style> <script src="bezier.js" type="text/javascript"></script> </head> <body> <canvas id="bezirer"></canvas> <div class="legend"> <p class="black">Исходный график</p> <p class="blue">Безье второго порядка</p> <p class="green">Безье третьего порядка</p> </div> <script> (function() { // скрипт не оптимизирован (!) // опорные точки var points = [ [0, 0], [200, 50], [400, 400], [600, 30] ]; // шаг для рассчета кривой Безье var step = 0.01; // "Время" var t = 0; // точка var point; // Bezier var bezier = new Bezier(); // канвас var canvas = document.getElementById('bezirer'); // контекст var context = canvas.getContext("2d"); // настройки канваса canvas.width = 600; canvas.height = 600; // отрисовка нормального графика context.lineWidth = 2; context.strokeStyle = '#000000'; context.moveTo(0, 0); context.beginPath(); for(var i = 0; i<points.length; ++i) { context.lineTo(points[i][0], points[i][1]); } context.stroke(); // отрисовка квадратичного графика context.lineWidth = 2; context.strokeStyle = '#0000ff'; context.moveTo(0, 0); context.beginPath(); t = 0; bezier.pushPoints([ bezier.getPoint(points[0][0], points[0][1]), bezier.getPoint(points[1][0], points[1][1]), bezier.getPoint(points[2][0], points[2][1]) ]); do { point = bezier.quadratic(t); context.lineTo(point.x, point.y); t = parseFloat((t + step).toFixed(2)); } while (t <= 1) context.stroke(); // отрисовка кубического графика context.lineWidth = 2; context.strokeStyle = '#008000'; context.moveTo(0, 0); context.beginPath(); t = 0; bezier.pushPoints([ bezier.getPoint(points[0][0], points[0][1]), bezier.getPoint(points[1][0], points[1][1]), bezier.getPoint(points[2][0], points[2][1]), bezier.getPoint(points[3][0], points[3][1]) ]); do { point = bezier.cubic(t); context.lineTo(point.x, point.y); t = parseFloat((t + step).toFixed(2)); } while (t <= 1) context.stroke(); })(); </script> </body> </html>