Определение значения B-сплайна в произвольной координате X - PullRequest
0 голосов
/ 30 октября 2018

Я создал открытый, зажатый, кубический, b-сплайн на множестве точек данных xp и yp.

Сплайн параметризован вектором u, который охватывает область xp.

Моя цель - определить координату "y" b-сплайна в заданной координате "x" в области xp.

Как и ожидается при формировании параметрических кривых, когда я передаю значение "4" в splev после вычисления tck, возвращается значение для координат x и y, соответствующее параметру 4.

Я могу использовать метод Ньютона, чтобы определить значение параметра u по заданной координате "x"; Это, однако, косвенно и требует большего времени вычислений, чем может позволить мое окончательное приложение.

Кто-нибудь может предложить более прямой способ определения координаты "y" на b-сплайне для данного "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()

На приведенном ниже рисунке показан направляющий многоугольник и b-сплайн, сгенерированный вышеуказанным кодом. Оранжевая точка в точке x = 4 соответствует точке, которую я хочу напрямую определить для значения y b-сплайна. Черная точка - это значение b-сплайна, когда значение 4 передается в качестве параметра.

Plot from above script

с несколькими полезными ссылками:

Быстрый алгоритм b-сплайна с 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

1 Ответ

0 голосов
/ 21 мая 2019

Метод roots класса PPoly может стать решением вашей проблемы. Это будет быстрее, чем Ньютон, и даст вам все решения, если их будет больше.

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()
...