问题描述
假设我有一组 x,y 坐标来标记轮廓上的点.有没有一种方法可以构建轮廓的样条表示,我可以在沿其长度的特定位置对其进行评估并恢复插值的 x、y 坐标?
Suppose I have a set of x,y coordinates that mark points along contour. Is there a way that I can build a spline representation of the contour that I can evaluate at a particular position along its length and recover interpolated x,y coordinates?
X 和 Y 值之间通常不是 1:1 对应的情况,因此单变量样条对我没有好处.双变量样条会很好,但据我所知,scipy.interpolate
中用于评估双变量样条的所有函数取 x,y 值并返回 z,而我需要给出 z 并返回 x,y(因为 x,y 是一条线上的点,每个 z 映射到一个唯一的 x,y).
It is often not the case that there is a 1:1 correspondence between X and Y values, so univariate splines are no good to me. Bivariate splines would be fine, but as far as I can tell all of the functions for evaluating bivariate splines in scipy.interpolate
take x,y values and return z, whereas I need to give z and return x,y (since x,y are points on a line, each z maps to a unique x,y).
这是我希望能够做的事情的草图:
Here's a sketch of what I'd like to be able to do:
import numpy as np
from matplotlib.pyplot import plot
# x,y coordinates of contour points, not monotonically increasing
x = np.array([ 2., 1., 1., 2., 2., 4., 4., 3.])
y = np.array([ 1., 2., 3., 4., 2., 3., 2., 1.])
# f: X --> Y might not be a 1:1 correspondence
plot(x,y,'-o')
# get the cumulative distance along the contour
dist = [0]
for ii in xrange(x.size-1):
dist.append(np.sqrt((x[ii+1]-x[ii])**2 + (y[ii+1]-y[ii])**2))
d = np.array(dist)
# build a spline representation of the contour
spl = ContourSpline(x,y,d)
# resample it at smaller distance intervals
interp_d = np.linspace(d[0],d[-1],1000)
interp_x,interp_y = spl(interp_d)
推荐答案
您想要使用参数样条,而不是从 x
值中插值 y
,您设置一个新参数 t
,并使用单变量从 t
的值插入 y
和 x
两者的样条.您如何为每个点分配 t
值会影响结果,正如您的问题所暗示的那样,使用距离可能是一个好主意:
You want to use a parametric spline, where instead of interpolating y
from the x
values, you set up a new parameter, t
, and interpolate both y
and x
from the values of t
, using univariate splines for both. How you assign t
values to each point affects the result, and using distance, as your question suggest, may be a good idea:
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate
x = np.array([ 2., 1., 1., 2., 2., 4., 4., 3.])
y = np.array([ 1., 2., 3., 4., 2., 3., 2., 1.])
plt.plot(x,y, label='poly')
t = np.arange(x.shape[0], dtype=float)
t /= t[-1]
nt = np.linspace(0, 1, 100)
x1 = scipy.interpolate.spline(t, x, nt)
y1 = scipy.interpolate.spline(t, y, nt)
plt.plot(x1, y1, label='range_spline')
t = np.zeros(x.shape)
t[1:] = np.sqrt((x[1:] - x[:-1])**2 + (y[1:] - y[:-1])**2)
t = np.cumsum(t)
t /= t[-1]
x2 = scipy.interpolate.spline(t, x, nt)
y2 = scipy.interpolate.spline(t, y, nt)
plt.plot(x2, y2, label='dist_spline')
plt.legend(loc='best')
plt.show()
这篇关于任意轮廓的平滑样条表示,f(长度)-->x,y的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!