B-spline curves
I have a set of points that I want to smooth using B-spline curves.
My question is, how can I implement B-spline curves to flatten these sets of points?
I want to implement this with C ++.
Here is the 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];
}
}
This 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;
}
}
Note that both functions accept x[0] < x[1] < ... < x[N]
.
I initially recommend using a least square fit with spline functions to fit the data points, and then resampling on the set spline to get a smoother set of data points (see my comments after OP). Here I would like to recommend a different approach that might be simpler than the smallest area approach:
1) create a cubic Hermite curve interpolating all data points. A cubic Hermite curve is basically a curve made up of many cubic segments of a polynomial curve between two consecutive data points. The cubic Hermite curve, generally speaking, is only C1 continuous.
2) use the Kjellander method to smooth the Hermite cubic curve. This method basically calculates the C2 breaks at the nodes (i.e., at the data points) and then adjusts the nodes accordingly to reduce the C2 break.
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 wrap methods). Source codes are available for download.