我希望使用B样条计算numpy中闭合曲线的曲率。我想评估样条曲线表示的导数而不是数据,以获得平滑的结果。但是,下面的代码会返回错误:
Traceback (most recent call last):
File "<stdin>", line 16, in <module>
File "/Users/jfl/anaconda/lib/python2.7/site-packages/scipy/interpolate/fitpack.py", line 1212, in splder
c = (c[1:-1-k] - c[:-2-k]) * k / dt
TypeError: unsupported operand type(s) for -: 'list' and 'list'
shell returned 1
所以我想知道我是否正确使用splder
功能......
import numpy as np
import scipy.interpolate as intplt
import matplotlib.pyplot as plt
t = np.linspace(0,2*np.pi,100)
x = np.cos(t)
y = np.sin(t)
pts = np.vstack((x,y))
tck, u = intplt.splprep(pts, u=None,k=3, s=0.0, per=1)
u_new = np.linspace(u.min(), u.max(), 1000)
x_new, y_new = intplt.splev(u_new, tck, der=0)
tck_der1 = intplt.splder(tck)
tck_der2 = intplt.splder(tck_der1)
xp, yp = intplt.splev(u_new, tck_der1, der=0)
xpp, ypp = intplt.splev(u_new, tck_der2, der=0)
plt.figure()
plt.plot(x,y,".")
plt.plot(x_new,y_new)
plt.figure()
curvature = np.abs(xp* ypp - yp* xpp) / np.power(xp** 2 + yp** 2, 3 / 2)
plt.plot(u_new,curvature)
plt.show()
答案 0 :(得分:1)
splder
仅支持标量样条线(使用y = f(x)
插入函数splrep
),而不支持使用splprep
获得的矢量样条线。在任何情况下,您都不需要它:只需使用der
的{{1}}参数:
splev
这不是导数的一般有限差分评估; xp, yp = intplt.splev(u_new, tck, der=1)
xpp, ypp = intplt.splev(u_new, tck, der=2)
实际上会使用样条结构来计算它,这就是你想要做的事情。
我猜你尝试了上述内容并对输出感到不满:
但这只是Matplotlib很有趣。绘图窗口从+ 9.998e-1到+ 9.998e-1 + 0.0006。换句话说,曲率几乎是恒定的(1),因此matplotlib放大了来自插值的不可避免的噪声。只需设置合理的绘图窗口,问题就会消失。
(或者,使用像splev
这样的例子来获得漂亮的非常数曲率。)