如何快速估算Python中点与双三次样条曲面之间的距离?

Bri*_*ian 9 python numpy spline scipy

如何快速估算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')   
Run Code Online (Sandbox Code Playgroud)

而且我有一些表面的测量点:

# 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 )
Run Code Online (Sandbox Code Playgroud)

我想找到表面s_ideal上每个点的最近点p.一般情况可能有多种解决方案用于大幅度变化的样条曲线,因此我将问题局限于已知在z点的投影点附近只有一个解的表面.这不是一个很小的测量或表面定义点,所以我想优化速度,即使牺牲精度也许1E-5.

想到的方法是使用梯度下降方法并对每个测量点执行类似操作p:

  1. 使用pt = [p_x, p_y, p_z]作为初始测试点,其中p_z = s_ideal(pt)
  2. 计算斜率(正切)载体m = [ m_x, m_y ]pt
  3. 计算矢量rptp:r = p - pt
  4. 如果角度theta之间rm是90度的一些阈值之内,则pt是最终点.
  5. 否则,更新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 ]
Run Code Online (Sandbox Code Playgroud)

我发现表明一种方法可以为1D情况产生非常高精度的快速结果,但它只是单一维度,对我来说可能太难转换为2.

gri*_*llo -1

是的!将 K 均值与聚类结合使用就可以做到这一点。所以s_ideal将是目标,然后你继续训练p_z。最终,您将获得质心,该质心将为您提供曲面上s_ideal与 中每个点最近的点p

是一个例子,它非常接近你想要的。