2012-06-20 45 views
3

是否有Python模塊用於處理參數(u-v)曲面?我在尋找的東西是這樣的3D模擬到scipy.interpolate的樣條函數,在那裏我可以通過一組二維的創建參數樣條指出正是如此:在Python中創建參數曲面

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) 

我寫我自己的代碼來做到這這前一段時間,但坦率地說還挺吮吸(SLO w和脆弱的,特別是在表面邊緣),我正在尋找更標準和優化的東西。

回答

1

這可能是明顯的,但如果能夠猜出的UV座標對應於每個數據點(最簡單的情況u=xv=y如果所述表面是一個曲線圖),參數插值(u,v) -> (x,y,z)本質上是3個獨立的2-d的內插數據集(x,y和z座標),因此您可以使用任何常用的2-D插值方法。

splprep實際上是這樣工作的,通過假定點是有序的,並根據u[i] = u[i-1] + dist(p[i], p[j])使用歐氏距離分配u座標。如果你知道哪些點是「彼此相鄰的」,這將推廣到2D。例如,如果x,y,z數據來作爲2-d陣列,可以做

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是,因爲它似乎有變形的空間。不過,下面的本地線性嵌入可能在這方面效果更好。

如果能猜到u,v值,比如你剛纔一堆點,並沒有鄰近地區的信息,問題就變得更加困難。這裏適當的關鍵詞似乎是「表面重建」和「多種學習」。

我沒有嘗試,但在我看來,你可以很容易地從scikits-learn,see this example使用LocallyLinearEmbedding獲得合適的u,v座標。他們有一堆不同的算法,這似乎足夠穩固。由此產生的u = Y[:,0]; v = Y[:,1]然後可以在非結構化2-D插值方法中使用,如上所示。

也許googling更多將揭示更多的軟件包。

+0

不,這是*不明顯(* head smack *)!你給了我的見解,我需要重新實現一些更好的東西,謝謝。對於記錄,這些是我創建的翼型曲面,從具有相同點數的截面曲線開始。我已經有了來自這些曲線的'u'值; 'v'值只是相對的截面高度。 – subnivean