Комментарий @ Фанга ниже. Лучше использовать вместо этого интерполирующий сплайн Catmull-Rom, который одновременно интерполирует и имеет свойство локального управления. Подробнее здесь
Для склеивания кубических кривых Безье c, которые интерполируются (больше похоже на натуральные кубические c сплайны), см. Ниже оригинальный ответ.
=============================================== ====================
Ниже приведен javascript
-подобный псевдокод, который вычисляет серию (до) кубов c Кривые Безье, которые вместе объединяются в , достигают одного плавного прохода кривой через заданные точки . Примечание bezier
в приведенном ниже коде предполагается функцией, которая вычисляет (полиномиальную форму) куби c по заданным контрольным точкам (что уже является известным алгоритмом). Примечание2 приведенный ниже алгоритм предназначен для 1d кривых, его легко настроить для 2d кривых (ie вычислить координаты x и y)
function bezierThrough( knots )
{
var i, points, segments;
computePoints = function computePoints( knots ) {
var i, p1, p2, a, b, c, r, m, n = knots.length-1;
p1 = new Array(n);
p2 = new Array(n);
/*rhs vector*/
a = new Array(n);
b = new Array(n);
c = new Array(n);
r = new Array(n);
/*left most segment*/
a[0] = 0;
b[0] = 2;
c[0] = 1;
r[0] = knots[0] + 2*knots[1];
/*internal segments*/
for(i=1; i<n-1; i++)
{
a[i] = 1;
b[i] = 4;
c[i] = 1;
r[i] = 4*knots[i] + 2*knots[i+1];
}
/*right segment*/
a[n-1] = 2;
b[n-1] = 7;
c[n-1] = 0;
r[n-1] = 8*knots[n-1] + knots[n];
/*solves Ax=b with the Thomas algorithm (from Wikipedia)*/
for(i=1; i<n; i++)
{
m = a[i] / b[i-1];
b[i] = b[i] - m*c[i - 1];
r[i] = r[i] - m*r[i-1];
}
p1[n-1] = r[n-1] / b[n-1];
for(i=n-2; i>=0; --i)
p1[i] = (r[i]-c[i]*p1[i+1]) / b[i];
/*we have p1, now compute p2*/
for (i=0;i<n-1;i++)
p2[i] = 2*knots[i+1] - p1[i+1];
p2[n-1] = (knots[n]+p1[n-1])/2;
return [p1, p2];
};
if ( 1 === knots.length )
{
segments = [knots[0]];
}
else if ( 2 === knots.length )
{
segments = [bezier([knots[0], knots[1]])];
}
else
{
segments = [];
points = computePoints(knots);
for(i=0; i<knots.length-1; i++)
segments.push(bezier([knots[i], points[0][i], points[1][i], knots[i+1]]));
}
return segments;
}
см. Также соответствующий пост
Адаптированный код от здесь