Reputation: 11
Pardon this long post.
I am new to BSpline and is struggling to understand few things. I have a set of data points for which I need to construct a BSpline curve. The Datapoints are as follows:
x = [150 130 148]
y = [149 114 79]
After running the following function:
from scipy.interpolate import splprep, splev
tck, u = splprep([x, y], k =2, s = 0)
I am getting
parameters u = [0. 0.505987 1.]
knots t = [0, 0, 0, 1, 1, 1]
coefficients c = [array([150. , 111.01850233, 148. ]), array([149. , 114.83829958, 79. ])]
k = 2 (this is the degree of curve I have used as an input for splprep).
I now need to test whether the t,c,k values generated are correct or not.
I ran the following function -
newPts = splev(u, tck)
This is giving me back the x and y data points I used in slprep.
newPts[0] = x
newPts[1] = y
Plotting newPts[0]againt newPts[1] gives me the following spline
The second test I ran was changing the parameters value to
u = np.linspace(0,1,5)
then ran the following
newPts = splev(u, tck)
This time my spline curve looks like the following
From the following links computing the parameters, knot vector generation, I deduced that my parameter(u) and knots(t) are derived correctly. However, the computation of coeffcients look complicated. But from the Global Curve interpolation formula, found here, coefficient matrix, I can see the coefficient matrix is an nXn, matrix that is in my case it has to be a 3X3 matrix. But the coefficient matrix that I am getting is 2X3 that too the first array are the coefficients of x and the last array are the coefficients of y.
I really need a concrete way to prove if the coefficients derived from the splprep library are correct or not.
Really appreciate the help.
Upvotes: 1
Views: 503
Reputation: 1169
Yes, the values are correct. Let me show you how I have checked them using the Wolfram language (AKA Mathematica):
First, I take the control points (what you saved as c
)
cps={{150,149},{111.01850233,114.83829958},{148,79}};
Since there are no internal knots (i.e., t=[0, 0, 0, 1, 1, 1]
), your B-spline actually reduces to a Bézier curve. Let's create it:
curve:=BezierFunction[cps]
Now we can evaluate it in the parameters u
and check that it interpolates your data.
In[23]:= curve[0]
Out[23]= {150.,149.}
In[24]:= curve[0.505987]
Out[24]= {130.,114.}
In[25]:= curve[1]
Out[25]= {148.,79.}
We can even plot the entire curve:
data={{150,149}, {130,114},{148,79}};
Graphics[{PointSize[Large],BezierCurve[cps], Green, Line[cps],Red,Point[cps],Blue, Point[data]}]
The curve is black, its control polygon red and the data points blue; clearly, the curve passes through all the three data points.
Upvotes: 0