3

パラメトリック (uv) サーフェスを処理するための 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)

しばらく前にこれを行う独自のコードを書きましたが、率直に言って、それはちょっと面倒です (特に表面のエッジでは遅くて壊れやすい) ので、より標準的で最適化されたものを探しています。

4

1 に答える 1

1

これはおそらく明らかですが、各データ ポイントに対応する UV 座標を推測できる場合 (サーフェスがグラフの場合の最も単純なケース)、パラメトリック補間u=xは本質的に 3 つの個別のデータセット (x、y、および z 座標)、通常の 2 次元内挿法を使用できます。v=y(u,v) -> (x,y,z)

splprep実際、ポイントが順序付けられていると仮定し、ユークリッド距離を使用してu座標を割り当てることにより、このように機能します。u[i] = u[i-1] + dist(p[i], p[j])どの点が「互いに隣り合っている」かがわかっている場合、これは 2 次元に一般化されます。たとえば、x,y,zデータが 2 次元配列である場合、次のことができます。

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-learnu,vを使用して適切な座標を簡単に取得できるようです。この例を参照してください。彼らにはさまざまなアルゴリズムがたくさんあり、これは十分にしっかりしているようです. 結果は、上に示したように、構造化されていない 2 次元内挿法で使用できます。LocallyLinearEmbeddingu = Y[:,0]; v = Y[:,1]

もっとグーグルで検索すると、より多くのパッケージが表示されるかもしれません。

于 2012-06-20T17:26:59.893 に答える