Я пытаюсь воспроизвести пример Mathematica для B-сплайна с Python.
Код математического примера читает
pts = {{0, 0}, {0, 2}, {2, 3}, {4, 0}, {6, 3}, {8, 2}, {8, 0}};
Graphics[{BSplineCurve[pts, SplineKnots -> {0, 0, 0, 0, 2, 3, 4, 6, 6, 6, 6}], Green, Line[pts], Red, Point[pts]}]
и производит то, что я ожидаю. Теперь я пытаюсь сделать то же самое с Python/scipy:
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as si
points = np.array([[0, 0], [0, 2], [2, 3], [4, 0], [6, 3], [8, 2], [8, 0]])
x = points[:,0]
y = points[:,1]
t = range(len(x))
knots = [2, 3, 4]
ipl_t = np.linspace(0.0, len(points) - 1, 100)
x_tup = si.splrep(t, x, k=3, t=knots)
y_tup = si.splrep(t, y, k=3, t=knots)
x_i = si.splev(ipl_t, x_tup)
y_i = si.splev(ipl_t, y_tup)
print 'knots:', x_tup
fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, y, label='original')
plt.plot(x_i, y_i, label='spline')
plt.xlim([min(x) - 1.0, max(x) + 1.0])
plt.ylim([min(y) - 1.0, max(y) + 1.0])
plt.legend()
plt.show()
Это приводит к тому, что это также интерполировано, но выглядит не совсем правильно. Я параметризую и сплайны x- и y-компоненты отдельно, используя те же узлы, что и математика. Тем не менее, я получаю сверх- и недомогания, которые делают мою интерполированную кривую носовой частью вне выпуклой оболочки контрольных точек. Какой правильный способ сделать это/как это делает математика?