B-сплайновые кривые

У меня есть набор точек, которые я хочу сгладить, используя кривые B-сплайна.
Мой вопрос заключается в том, как я могу реализовать кривые B-сплайна, чтобы сгладить этот набор точек?
Я хочу реализовать это с помощью C ++.

3

Решение

Вот функция для любого заданного количества точек:

void Spline(double x[N+1],double y[N+1], // input
double A[N],double B[N],     // output
double C[N],double D[N])     // output
{
double w[N];
double h[N];
double ftt[N+1];

for (int i=0; i<N; i++)
{
w[i] = (x[i+1]-x[i]);
h[i] = (y[i+1]-y[i])/w[i];
}

ftt[0] = 0;
for (int i=0; i<N-1; i++)
ftt[i+1] = 3*(h[i+1]-h[i])/(w[i+1]+w[i]);
ftt[N] = 0;

for (int i=0; i<N; i++)
{
A[i] = (ftt[i+1]-ftt[i])/(6*w[i]);
B[i] = ftt[i]/2;
C[i] = h[i]-w[i]*(ftt[i+1]+2*ftt[i])/6;
D[i] = y[i];
}
}

Вот как вы можете распечатать результаты этой функции:

void PrintSpline(double x[N+1],            // input
double A[N], double B[N], // input
double C[N], double D[N]) // input
{
for (int i=0; i<N; i++)
{
cout << x[i] << " <= x <= " << x[i+1] << " : f(x) = ";
cout << A[i] << "(x-" << x[i] << ")^3 + ";
cout << B[i] << "(x-" << x[i] << ")^2 + ";
cout << C[i] << "(x-" << x[i] << ")^1 + ";
cout << D[i] << "(x-" << x[i] << ")^0";
cout << endl;
}
}

Обратите внимание, что обе функции предполагают x[0] < x[1] < ... < x[N],

4

Другие решения

Первоначально я рекомендовал использовать подгонку по методу наименьших квадратов с функциями сплайна для подгонки точек данных с последующей повторной выборкой на подгоненном сплайне, чтобы получить более плавный набор точек данных (см. Мои комментарии после ОП). Здесь я хотел бы рекомендовать другой подход, который может быть проще, чем подход наименьшего квадрата:

1) создать кубическую кривую Эрмита, интерполируя все точки данных. Кривая кубического Эрмита в основном представляет собой кривую, состоящую из множества сегментов кубической полиномиальной кривой между двумя последовательными точками данных. Кривая кубического Эрмита, как правило, только C1 непрерывна.
2) использовать метод Кьелландера для сглаживания кубической кривой Эрмита. Этот метод в основном вычисляет разрыв C2 в узлах (то есть в точках данных) и затем корректирует узлы соответствующим образом, чтобы уменьшить разрыв C2.
3) После сглаживания узлы кубической кривой Эрмита станут вашим новым набором точек данных.

Вот ссылка на сайт для метода Кьелландера (и других методов сплайнового обтекателя). Исходные коды доступны для скачивания.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector