2016-05-09 18 views
5

面上の点である(X、Y、Z)私は任意の(X、Y)座標でZ値を補間できるようにしたいと考えています。グリッド上の値を補間するのにmlab.griddataを使用して成功しましたが、任意の(X、Y)座標に対して一般的な使用関数を呼び出せるようにしたいと考えています。(X、Y、Z)座標で定義された点の集合を与え、任意の(X、Y)でZ値を補間する

点の集合は、ほぼ半球面を形成する。問題を簡略化するために、私は下のx、y、z座標で定義された半球の既知の点の間の値を補間する方法を書こうとしています。あなたが補間する必要がないような完璧な球のz = f(x、y)を見つける解は存在しますが、実際の点集合は完全な球ではありませんので、未知の(X、Y)座標の値を補間する。 Link to IPython notebook with point data

resolution = 10 
u = np.linspace(-np.pi/2, np.pi/2, resolution) 
v = np.linspace(0, np.pi, resolution) 

U, V = np.meshgrid(u, v) 

xs = np.sin(U) * np.cos(V) 
ys = np.sin(U) * np.sin(V) 
zs = np.cos(U) 

Iはscipy.interpolate.interp2d、使用されてきた「呼び出しメソッド新しい点の値を見つけるために、スプライン補間を使用する関数を返す」を

def polar(xs, ys, zs, resolution=10): 
    rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys)) 
    ts = np.arctan2(ys, xs) 
    func = interp2d(rs, ts, zs, kind='cubic') 
    vectorized = np.vectorize(func) 

    # Guesses 
    ri = np.linspace(0, rs.max(), resolution) 
    ti = np.linspace(0, np.pi * 2, resolution) 

    R, T = np.meshgrid(ri, ti) 
    Z = vectorized(R, T) 
    return R * np.cos(T), R * np.sin(T), Z 

残念ながら、私は同様に別のStackOverflowのuser who tried to use interp2dに、かなり奇妙な結果を得ることができます。

Polar result

私はこれまでの(X、Y)でのZの値を推定するためにinverse squaresを使用して発見した最も成功。しかし、この関数は、Z = 0付近のZの値を推定するのには完璧ではありません。

Inverse Squares result

私は、(x、y、z)における点の集合を与えられた機能z = f(x, y)を取得するために何ができますか?私はここで何かを見逃しています...表面上の値を確実に見積もるためにポイントクラウド以上のものが必要ですか?

EDIT:

これは私が執筆を終わった機能です。この関数はxs, ys, zsの入力配列を取り、通常のグリッドを必要としないscipy.interpolate.griddataを使用してx, yで補間します。私はこれを行うよりスマートな方法があると確信していると、更新プログラムを感謝しますが、それは動作し、私はパフォーマンスに関係していない。将来の誰にでも役立つ場合に備えてスニペットを含める。

def interpolate(x, y, xs, ys, zs): 
    r = np.sqrt(x*x + y*y) 
    t = np.arctan2(y, x) 

    rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys)) 
    ts = np.arctan2(ys, xs) 

    rs = rs.ravel() 
    ts = ts.ravel() 
    zs = zs.ravel() 

    ts = np.concatenate((ts - np.pi * 2, ts, ts + np.pi * 2)) 
    rs = np.concatenate((rs, rs, rs)) 
    zs = np.concatenate((zs, zs, zs)) 


    Z = scipy.interpolate.griddata((rs, ts), zs, (r, t)) 
    Z = Z.ravel() 
    R, T = np.meshgrid(r, t) 
    return Z 
+0

機械学習を使用します。 :) – erip

+0

あなたはscipy.interpolate.LinearNDInterpolatorを試しましたか?私はこれらのタイプの問題のためにそれに関して良い経験を持っています。 –

答えて

2

あなたはgriddataを試したと言います。では、なぜそれは動作していませんでしたか? griddataは、新しいポイントが規則的に間隔を置かない場合にも機能します。たとえば、

# Definitions of xs, ys and zs 
nx, ny = 20, 30 
x = np.linspace(0, np.pi, nx) 
y = np.linspace(0, 2*np.pi, ny) 

X,Y = np.meshgrid(x, y) 

xs = X.reshape((nx*ny, 1)) 
ys = Y.reshape((nx*ny, 1)) 

## Arbitrary definition of zs 
zs = np.cos(3*xs/2.)+np.sin(5*ys/3.)**2 

## new points where I want the interpolations 
points = np.random.rand(1000, 2) 

import scipy.interpolate 
zs2 = scipy.interpolate.griddata(np.hstack((xs, ys)), zs, points) 

これはあなたの後のものではありませんか?

+0

はい、これは動作します。ありがとうございました!私は基本的な関数呼び出し(interp2dの戻り値のような)を取得し、一度に1つのポイントを渡す実装を望んでいましたが、(X、Y)の配列の配列を渡すように他のコードを常にリファクタリングすることができます。 –

1

私はあなたの質問を理解していれば、あなたが欲しい何

xs = np.sin(U) * np.cos(V) 
ys = np.sin(U) * np.sin(V) 
zs = np.cos(U) 

で定義されているポイントxsyszsを持っているが与えられたためにZ値を補間して見つけることができるようにすることですxとy?なぜ補間が必要ですか?上記の式は球を表し、彼らはxs*xs + ys*ys + zs*zs = 1ように書き換えることができるので、この問題への容易な解析解があります:私は質問を誤解しない限り、

def Z(X, Y): 
    return np.sqrt(1-X**2-Y**2) 
    ## or return -np.sqrt(1-X**2-Y**2) since this equation has two solutions 

が。

+0

ああ、明確にするために、点の集合はおおよそ半球であるので、解析的解は必ずしも真実ではないでしょう。私はこれを含めるように私の質問を編集します... –

関連する問題