jani-c
jani-c

Reputation: 11

How are the coefficients derived in the scipy.interpolate.splprep function

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

spline evlaluation 1

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

spline evaluation 2

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

Answers (1)

Dominik Mokriš
Dominik Mokriš

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]}]

Graph of the curve

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

Related Questions