2 views

I have created an open, clamped, cubic, b-spline on the set of data points xp and yp.

The spline is parametarized by the vector u which spans the domain of xp.

My goal is to determine the "y" coordinate of the b-spline at a given "x" coordinate in the domain of xp.

As is expected behavior when generating parametric curves, when I pass the value "4" into splev after calculating tck, the value for both the x and y coordinate corresponding to the parameter 4 is returned.

I am able to use Newton's method to determine the value of the parameter u at a given "x" coordinate; This is however indirect and requires more computation time than my final application can permit.

Can anyone suggest a more direct way to determine the "y" coordinate on the b-spline for a given "x"?

import numpy as np

import matplotlib.pyplot as plt

from scipy import interpolate

xp = [0., 0.71428571, 1.42857143, 2.14285714, 2.85714286, 3.57142857, 4.28571429, 5.]

yp = [0., -0.86217009, -2.4457478, -2.19354839, -2.32844575, -0.48680352, -0.41055718, -3.]

length = len(xp)

t = np.linspace(0., xp[-1], length - 2, endpoint=True)

t = np.append([0, 0, 0], t)

t = np.append(t, [xp[-1], xp[-1], xp[-1]])

tck = [t, [xp, yp], 3]

u = np.linspace(0, 5., 1000, endpoint=True)

out = interpolate.splev(u, tck)

x_value_in_xp_domain = 4.

y_value_out = interpolate.splev(x_value_in_xp_domain, tck)

plt.plot(xp, yp, linestyle='--', marker='o', color='purple')

plt.plot(out[0], out[1], color = 'teal')

plt.plot(x_value_in_xp_domain, y_value_out[1], marker='o', color = 'orangered')

plt.plot(y_value_out[0], y_value_out[1], marker='o', color = 'black')

plt.axvline(x=x_value_in_xp_domain, color = 'orangered')

plt.show()

The below image shows the guide polygon and the b-spline generated by the above code. The orange point at x=4 corresponds the point I wish to directly determine the y value of the b-spline at. The black point is the value of the b-spline when the value of 4 is passed as a parameter.

providing a few useful references:

Fast b-spline algorithm with numpy/scipy

https://github.com/kawache/Python-B-spline-examples

https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve.html

http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html

by (41.4k points)

You can use roots() method of PPoly, that is faster than Newton, and it will give you all the solutions in case if  there is more than one.

sx = interpolate.BSpline(t, xp, 3)

sy = interpolate.BSpline(t, yp, 3)

x0 = 4

u0 = interpolate.PPoly.from_spline((sx.t, sx.c - x0, 3)).roots()

sy(u0)

plt.plot(xp, yp, linestyle='--', marker='o', color='purple')

plt.plot(out[0], out[1], color = 'teal')

plt.plot(sx(u0), sy(u0), 'o')

plt.show()

Gain practical exposure with data science projects in Intellipaat's Data Science course online.