2012-03-11 34 views
8

だ私は今は、F(x、y)を近似できるようにするZ軸上スプライン曲面補間

f(x1,y1) = 10 
f(x2,y2) = 12 
f(x3,y3) = 5 
f(x4,y4) = 2 
... 
f(xn,yn) = 21 

の表面を規定する点のn個を持っていると言います。私は線形、特にスプライン近似のアルゴリズムを探しています。アルゴリズムの例や少なくともいくつかのポインタは素晴らしいでしょう。

+0

[wikipedia] [1]の記事は少し難しいですが、少なくとも例のセクションを見てみてください。 [1]:http://en.wikipedia.org/wiki/Spline_interpolation –

+1

x、yコントロールポイントは通常のグリッドにありますか? –

+0

形式f(x、y)の関数については、基礎となるデータの形式(次数Kの多項式、Nガウスの和など)について仮定し、最小二乗で係数を決定することがより一般的です。それはここで働くだろうか?データが表すものについて何か知っていますか?スプラインが本当に必要な場合は、NURBS http://en.wikipedia.org/wiki/NURBSをご覧ください。彼らはレンダリングのために素晴らしいプロパティを持っています。正規のグリッド上にない限り、(x、y)点のDelaunay三角形を構築して基底を取得します。平面フィッティングの場合、標準最小二乗適合が必要です。 – Gene

答えて

1

(xi, yi)XY平面内の四角形をサンプリングする場合は、ベジェ(またはBspline)サーフェスのコントロールポイントとして使用できます。この点で、フィッティングは関係ありません。

あなたが得る表面は、あなたの点の凸包にあり、境界の点を交差(補間)します。{xi, yi}

お試ししたい場合は、This forums postingMatlabに単純なコードが含まれているようだ、と(それがプログラムのファイル形式を考え出す必要がありますが)あなたはMatlabを持っていない場合は、同じことを行うためにGuIRITを使用することができます。

+0

最終的な実装はルビになければなりません。だからMatlabは本当にオプションではありません。しかし問題は実際にはXY平面内の矩形についてです。 – tcurdt

+0

私はRubyを一度も使用しませんでしたが、ベジエ/ Bsplineパッケージがあると確信しています。 – user1071136

4

これは、線形近似を行うアプローチのあいまいな説明です。

  1. あなたのポイントのVoronoi diagram(平面内のすべてのポイントのために、最寄りの(x_i,y_i)を見つける。)
  2. Delaunay triangulationを得るために、この二重のを取る決定します。ポイントの線分がある場合(x_i,y_i)(x_j,y_j)を接続(x_i,y_i)(x_j,y_j)は等距離(他のどのペアよりも近く)です。
  3. 各三角形について、3つの頂点を通る平面を見つけます。これは必要な線形補間です。

以下は、Pythonの最初の2つのステップを実行します。あなたの グリッドの規則性は、物事をスピードアップさせるかもしれません(三角測量を台無しにするかもしれません)。

import itertools 

""" Based on http://stackoverflow.com/a/1165943/2336725 """ 
def is_ccw(tri): 
    return ((tri[1][0]-tri[0][0])*(tri[1][1]+tri[0][1]) 
      + (tri[2][0]-tri[1][0])*(tri[2][1]+tri[1][1]) 
      + (tri[0][0]-tri[2][0])*(tri[0][1]+tri[2][1])) < 0 

def circumcircle_contains_point(triangle,point): 
    import numpy as np 
    matrix = np.array([ [p[0],p[1],p[0]**2+p[1]**2,1] for p in triangle+point ]) 
    return is_ccw(triangle) == (np.linalg.det(matrix) > 0) 

triangulation = set() 
""" 
A triangle is in the Delaunay triangulation if and only if its circumscribing 
circle contains no other point. This implementation is O(n^4). Faster methods 
are at http://en.wikipedia.org/wiki/Delaunay_triangulation 
""" 
for triangle in itertools.combinations(points,3): 
    triangle_empty = True 
    for point in points: 
     if point in triangle: 
      next 
     if circumcircle_contains_point(triangle,point): 
      triangle_empty = False 
      break 
    if triangle_empty: 
     triangulation.add(triangle) 
2

不規則な2Dデータの補間はそれほど簡単ではありません。私は不規則な2Dへの真のスプラインの一般化を知らない。

三角測量ベースのアプローチに加えて、あなたはバーンズ(http://en.wikipedia.org/wiki/Barnes_interpolation)と逆距離加重(http://en.wikipedia.org/wiki/Inverse_distance_weighting)、またはより一般的に、RBF(http://en.wikipedia.org/wiki/Radial_basis_functions)を見てすることができます。

ポイントが強く不均一に広がっている(密度の高いクラスター)場合は、関数のサイズを適応させるか、補間ではなく近似にする必要があります。

+0

現実的にはそれほど普及していません。最悪の場合、私はおそらく線形補間で生きているかもしれませんが、滑らかな表面を好むでしょう。 – tcurdt

+0

近似は面白い角度のように聞こえる。 – tcurdt

+0

+1ラジアル基底関数。私は数年前にマニフォールドで機能するように一般化されたこれらのオブジェクトを使って論文を書いた。あなたが密度の高いクラスターを持たず、ポイント数nがあまりにも大きくならない限り、彼らは素晴らしい仕事をします。 (nが大きくなると、RBFのコンパクトなサポートが必要なので、関連する行列は疎ですが、スパース線形代数を使用してスケーリングを容認できるようにする必要があります)。 –

関連する問題