I have a set of points which I want to smooth using B-spline curves.
My question is how can I implement B-spline curves to smooth these set of points?
I want to implement this using c++.
问题:
回答1:
Here is a function for any given number of points:
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];
}
}
Here is how you can print the results of this function:
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;
}
}
Please note that both functions assume x[0] < x[1] < ... < x[N]
.
回答2:
I originally recommend using Least Square fitting with spline functions to fit the data points, followed by resampling on the fitted spline to obtain a smoother set of data points (please see my comments after the OP). Here I would like to recommend a different approach, which could be simpler than the Least Square fitting approach:
1) create cubic Hermite curve interpolating all the data points. The cubic Hermite curve basically is a curve composed of many cubic polynomial curve segments in between two consecutive data points. A cubic Hermite curve is in general only C1 continuous.
2) use Kjellander method to smooth the cubic Hermite curve. This method basically compute the C2 discontinuity at the nodes (i.e., at the data points) and then adjust the nodes accordingly to reduce the C2 discontinuity.
3) After smoothing, the nodes of the cubic Hermite curve will be your new set of data points.
Here is a link for the Kjellander method (and other spline fairing methods). Source codes are available for download.