Python:沿着三次样条函数找到 x(返回 y),它产生等距的顺序 (x,y) 对
Python: find x along cubic spline (returning y) which yields sequential (x,y) pairs in equal distance
假设我有一个从点 [0,0] 到 [10,10] 的三次样条,其边界值为零导数:
spl = scipy.interpolate.CubicSpline(x = [0,10], y = [0,10], bc_type=((1,0),(1,0)))
如果我将在 x 处计算的样条的输出作为它的 y 坐标,我得到从起点到终点的 'path':
y_coordinate = spl(x_coordinate)
现在可以非常直接地定期评估此样条 spaced x,例如 numpy.linspace。
如果我有兴趣找到 x 的序列,并且序列点之间 (x,y) space 中的欧几里德距离相等,我该怎么办?
当我希望几件事相等时,我将它们放在一个数组中并要求 SciPy 最小化该数组的方差。它往往运作良好。
在下面的代码中,我决定(无论好坏)仅使用内部点作为变量(称为 t
),在计算距离之前插入端点 a、b。另一种方法是将所有点用作变量,但施加 t[0] == a
和 t[-1] == b
.
的约束
import numpy as np
from scipy import interpolate, optimize
import matplotlib.pyplot as plt
spl = interpolate.CubicSpline(x = [0, 10], y = [0, 10], bc_type=((1, 0), (1, 0)))
def distances_var(t, a, b):
atb = np.concatenate(([a], t, [b])) # added endpoints
y = spl(atb)
dist_squared = np.diff(atb)**2 + np.diff(y)**2
return np.var(dist_squared)
a, b = 0, 10
n = 7 # how many points to put
res = optimize.minimize(distances_var, np.linspace(a, b, n)[1:-1], args=(a, b))
x = np.concatenate(([a], res.x, [b])) # the points we want
xx = np.linspace(a, b, 500) # for plotting the curve
plt.axes().set_aspect('equal')
plt.plot(xx, spl(xx))
plt.plot(x, spl(x), 'ro')
plt.show()
假设我有一个从点 [0,0] 到 [10,10] 的三次样条,其边界值为零导数:
spl = scipy.interpolate.CubicSpline(x = [0,10], y = [0,10], bc_type=((1,0),(1,0)))
如果我将在 x 处计算的样条的输出作为它的 y 坐标,我得到从起点到终点的 'path':
y_coordinate = spl(x_coordinate)
现在可以非常直接地定期评估此样条 spaced x,例如 numpy.linspace。
如果我有兴趣找到 x 的序列,并且序列点之间 (x,y) space 中的欧几里德距离相等,我该怎么办?
当我希望几件事相等时,我将它们放在一个数组中并要求 SciPy 最小化该数组的方差。它往往运作良好。
在下面的代码中,我决定(无论好坏)仅使用内部点作为变量(称为 t
),在计算距离之前插入端点 a、b。另一种方法是将所有点用作变量,但施加 t[0] == a
和 t[-1] == b
.
import numpy as np
from scipy import interpolate, optimize
import matplotlib.pyplot as plt
spl = interpolate.CubicSpline(x = [0, 10], y = [0, 10], bc_type=((1, 0), (1, 0)))
def distances_var(t, a, b):
atb = np.concatenate(([a], t, [b])) # added endpoints
y = spl(atb)
dist_squared = np.diff(atb)**2 + np.diff(y)**2
return np.var(dist_squared)
a, b = 0, 10
n = 7 # how many points to put
res = optimize.minimize(distances_var, np.linspace(a, b, n)[1:-1], args=(a, b))
x = np.concatenate(([a], res.x, [b])) # the points we want
xx = np.linspace(a, b, 500) # for plotting the curve
plt.axes().set_aspect('equal')
plt.plot(xx, spl(xx))
plt.plot(x, spl(x), 'ro')
plt.show()