假设(X,Y,Z)坐标中的一组点是曲面上的点,我希望能够在任意(X,Y)坐标处插值Z值。我发现使用mlab.griddata在网格上插值可以获得一些成功,但我希望能够为任何(X,Y)坐标调用通用函数。
这组点形成一个大致半球形的表面。为了简化问题,我试图编写一种方法,在下面的x,y和z坐标定义的半球的已知点之间插值。虽然有一个分析解决方案可以找到完美球体的z = f(x,y),这样你就不需要插值,实际的点集将不是一个完美的球体,所以我们应该假设我们需要在未知(X,Y)坐标处插值。 Link to IPython notebook with point data
resolution = 10
u = np.linspace(-np.pi / 2, np.pi / 2, resolution)
v = np.linspace(0, np.pi, resolution)
U, V = np.meshgrid(u, v)
xs = np.sin(U) * np.cos(V)
ys = np.sin(U) * np.sin(V)
zs = np.cos(U)
我一直在使用scipy.interpolate.interp2d
,它“返回一个函数,其调用方法使用样条插值来查找新点的值。”
def polar(xs, ys, zs, resolution=10):
rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys))
ts = np.arctan2(ys, xs)
func = interp2d(rs, ts, zs, kind='cubic')
vectorized = np.vectorize(func)
# Guesses
ri = np.linspace(0, rs.max(), resolution)
ti = np.linspace(0, np.pi * 2, resolution)
R, T = np.meshgrid(ri, ti)
Z = vectorized(R, T)
return R * np.cos(T), R * np.sin(T), Z
不幸的是,我得到了非常奇怪的结果,类似于另一个StackOverflow user who tried to use interp2d。
迄今为止我发现的最大成功是使用inverse squares估算(X,Y)处的Z值。但该函数不能很好地估计Z = 0附近的Z值。
如果在(x,y,z)中给出一组点,我该怎么做才能得到一个函数z = f(x, y)
?我在这里遗漏了什么......我是否需要更多的点云来可靠地估算表面上的值?
修改
这是我写完的功能。该函数接受xs, ys, zs
的输入数组,并使用x, y
在scipy.interpolate.griddata
进行插值,这不需要常规网格。我确信有一种更聪明的方法可以做到这一点,并希望任何更新,但它的工作原理,我不关心性能。包括一个片段,以防将来帮助任何人。
def interpolate(x, y, xs, ys, zs):
r = np.sqrt(x*x + y*y)
t = np.arctan2(y, x)
rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys))
ts = np.arctan2(ys, xs)
rs = rs.ravel()
ts = ts.ravel()
zs = zs.ravel()
ts = np.concatenate((ts - np.pi * 2, ts, ts + np.pi * 2))
rs = np.concatenate((rs, rs, rs))
zs = np.concatenate((zs, zs, zs))
Z = scipy.interpolate.griddata((rs, ts), zs, (r, t))
Z = Z.ravel()
R, T = np.meshgrid(r, t)
return Z
答案 0 :(得分:2)
您说您已尝试使用griddata
。那为什么那不起作用?如果新点没有规则间隔,griddata
也可以使用。例如,
# Definitions of xs, ys and zs
nx, ny = 20, 30
x = np.linspace(0, np.pi, nx)
y = np.linspace(0, 2*np.pi, ny)
X,Y = np.meshgrid(x, y)
xs = X.reshape((nx*ny, 1))
ys = Y.reshape((nx*ny, 1))
## Arbitrary definition of zs
zs = np.cos(3*xs/2.)+np.sin(5*ys/3.)**2
## new points where I want the interpolations
points = np.random.rand(1000, 2)
import scipy.interpolate
zs2 = scipy.interpolate.griddata(np.hstack((xs, ys)), zs, points)
这不是你想要的吗?
答案 1 :(得分:1)
如果我理解了您的问题,您可以获得由{/ p>定义的积分xs
,ys
,zs
xs = np.sin(U) * np.cos(V)
ys = np.sin(U) * np.sin(V)
zs = np.cos(U)
你想要的是能够插入并找到给定x和y的z值吗?你为什么需要插值?上面的等式代表一个球体,它们可以重写为xs*xs + ys*ys + zs*zs = 1
,因此这个问题有一个简单的解析解决方案:
def Z(X, Y):
return np.sqrt(1-X**2-Y**2)
## or return -np.sqrt(1-X**2-Y**2) since this equation has two solutions
除非我误解了这个问题。