【发布时间】:2017-07-26 20:36:38
【问题描述】:
如何在 Python 中快速估计点与双三次样条曲面之间的距离?是否有我可以在 SciPy、NumPy 或其他包中利用的现有解决方案?
我有一个由双三次插值定义的表面:
import numpy as np
import scipy.interpolate
# Define regular grid surface
xmin,xmax,ymin,ymax = 25, 125, -50, 50
x = np.linspace(xmin,xmax, 201)
y = np.linspace(ymin,ymax, 201)
xx, yy = np.meshgrid(x, y)
z_ideal = ( xx**2 + yy**2 ) / 400
z_ideal += z_ideal + np.random.uniform(-0.5, 0.5, z_ideal.shape)
s_ideal = scipy.interpolate.interp2d(x, y, z_ideal, kind='cubic')
我已经得到了该表面的一些测量点:
# Fake some measured points on the surface
z_measured = z_ideal + np.random.uniform(-0.1, 0.1, z_ideal.shape)
s_measured = scipy.interpolate.interp2d(x, y, z_measured, kind='cubic')
p_x = np.random.uniform(xmin,xmax,10000)
p_y = np.random.uniform(ymin,ymax,10000)
p_z = s_measured( p_x, p_y )
我想找到表面s_ideal 上与p 中每个点最近的点。一般情况下,对于变化很大的样条曲线可能有多种解决方案,因此我将问题限制在已知在点沿 z 的投影附近只有一个解决方案的表面上。
这不是极少数的测量或表面定义点,所以我想优化速度,即使牺牲精度到可能1E-5。
想到的方法是使用梯度下降法,对每个测量点做类似p:
- 使用
pt = [p_x, p_y, p_z]作为初始测试点,其中p_z = s_ideal(pt) - 计算斜率(切线)矢量
m = [ m_x, m_y ]pt - 计算从
pt到p的向量r:r = p - pt - 如果
r和m之间的角度theta在90 度的某个阈值内,那么pt就是最后一点。 - 否则,将
pt更新为:
r_len = numpy.linalg.norm(r)
dx = r_len * m_x
dy = r_len * m_y
if theta > 90:
pt = [ p_x + dx, p_y + dy ]
else:
pt = [ p_x - dx, p_y - dy ]
我发现this 建议一种方法可以快速产生一维情况下的高精度结果,但它是单一维度的,我可能很难转换为二维。
【问题讨论】: