首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的参数化曲面创建

Python中的参数化曲面创建
EN

Stack Overflow用户
提问于 2012-06-20 21:21:28
回答 1查看 2.8K关注 0票数 3

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

代码语言:javascript
复制
xypts = [[0., 1., 5., 2.], [4., 3., 6., 7.]]
tck, u = scipy.interpolate.splprep(xypts, s=0, k=3)

然后在样条线上的任意t值处得到一个点,如下所示:

代码语言:javascript
复制
t = 0.5
intxypt = scipy.interpolate.splev(t, tck)

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

代码语言:javascript
复制
# 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)

不久前我写了自己的代码来做这件事,但坦率地说,它有点糟糕(缓慢和脆弱,特别是在表面边缘),我正在寻找更标准和更优化的东西。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-21 01:27:00

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

splprep实际上是以这种方式工作的,它假设这些点是有序的,并使用欧几里德距离根据u[i] = u[i-1] + dist(p[i], p[j])分配u坐标。如果你知道哪些点是“相邻的”,这可以推广到2-D。例如,如果x,y,z数据是二维数组,则可以执行以下操作

代码语言:javascript
复制
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,see this example中的LocallyLinearEmbedding获得合适的u,v坐标。他们有一堆不同的算法,这似乎足够可靠。然后,您可以在非结构化2-D插值方法中使用生成的u = Y[:,0]; v = Y[:,1],如上所示。

也许googling more会发现更多的套餐。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11120558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档