gpt4 book ai didi

python - Python 中的参数化曲面创建

转载 作者:行者123 更新时间:2023-11-28 18:52:03 28 4
gpt4 key购买 nike

是否有用于处理参数化 (u-v) 曲面的 Python 模块?我正在寻找与 scipy.interpolate 的样条函数类似的 3D 东西,我可以在其中通过一组 2D 点创建参数化样条:

xypts = [[0., 1., 5., 2.], [4., 3., 6., 7.]]
tck, u = scipy.interpolate.splprep(xypts, s=0, k=3)

然后像这样在样条曲线上的任何 t 值处获取一个点:

t = 0.5
intxypt = scipy.interpolate.splev(t, tck)

所以,我想要的是像这样工作的东西:

# xyzpts is a 3 x m x n matrix, with m and n >= 4 for a cubic surface
tck, s, t = srfprep(xyzpts, s=0, k=3)
u, v = 0.5, 0.5
intxyzpt = srfev(u, v, tck)

前段时间我编写了自己的代码来执行此操作,但坦率地说,它有点糟糕(缓慢且脆弱,尤其是在表面边缘),我正在寻找更标准和优化的东西。

最佳答案

这可能是显而易见的,但如果您能够猜测对应于每个数据点的 u-v 坐标(最简单的情况 u=xv=y 如果表面是一个图),参数插值 (u,v) -> (x,y,z) 本质上是 3 个独立数据集(x、y 和 z 坐标)的二维插值,因此您可以使用任何常用的二维插值方法。

splprep 实际上是这样工作的,假设点是有序的,并根据 u[i] = u[i-1] 分配 u 坐标] + dist(p[i], p[j]) 使用欧氏距离。如果您知道哪些点“彼此相邻”,则这可以推广到二维。例如,如果 x,y,z 数据是二维数组,您可以这样做

from scipy import interpolate
import numpy as np

# example dataset (wavy cylinder)

def surf(u, v):
x = np.cos(v*np.pi*2) * (1 + 0.3*np.cos(30*u))
y = np.sin(v*np.pi*2) * (1 + 0.3*np.cos(30*u))
z = 2*u
return x, y, z

ux, vx = np.meshgrid(np.linspace(0, 1, 20),
np.linspace(0, 1, 20))
x, y, z = surf(ux, vx)

# reconstruct (u, v) using the existing (!) neighbourhood information
du = np.sqrt(np.diff(x, axis=0)**2 + np.diff(y, axis=0)**2 + np.diff(z, axis=0)**2)
dv = np.sqrt(np.diff(x, axis=1)**2 + np.diff(y, axis=1)**2 + np.diff(z, axis=1)**2)
u = np.zeros_like(x)
v = np.zeros_like(x)
u[1:,:] = np.cumsum(du, axis=0)
v[:,1:] = np.cumsum(dv, axis=1)

u /= u.max(axis=0)[None,:] # hmm..., or maybe skip this scaling step -- may distort the result
v /= v.max(axis=1)[:,None]

# construct interpolant (unstructured grid)
ip_surf = interpolate.CloughTocher2DInterpolator(
(u.ravel(), v.ravel()),
np.c_[x.ravel(), y.ravel(), z.ravel()])

# the BivariateSpline classes might also work here, but the above is more robust

# plot projections
import matplotlib.pyplot as plt

u = np.random.rand(2000)
v = np.random.rand(2000)

plt.subplot(131)
plt.plot(ip_surf(u, v)[:,0], ip_surf(u, v)[:,1], '.')
plt.title('xy')
plt.subplot(132)
plt.plot(ip_surf(u, v)[:,1], ip_surf(u, v)[:,2], '.')
plt.title('yz')
plt.subplot(133)
plt.plot(ip_surf(u, v)[:,2], ip_surf(u, v)[:,0], '.')
plt.title('zx')
plt.show()

编辑:好的,我不完全确定上面计算的 u,v 在实践中有多稳健,因为它似乎有失真的空间。但是,下面的 LocallyLinearEmbedding 在这方面可能效果更好。

如果您不能猜测u,v 值,例如您只有一堆点而没有邻域信息,问题就会变得更加困难。这里合适的关键词似乎是“表面重建”和“流形学习”。

我没有尝试,但在我看来,您可以使用来自 scikits-learn 的 LocallyLinearEmbedding 轻松获得合适的 u,v 坐标,see this example .他们有一堆不同的算法,这看起来足够可靠。结果 u = Y[:,0]; v = Y[:,1] 然后您可以在非结构化二维插值方法中使用,如上所示。

也许谷歌搜索更多会显示更多包。

关于python - Python 中的参数化曲面创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11120558/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com