2012-03-11 100 views
8

比方說,我對Z軸樣條曲面插補

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

現在我希望能夠以接近F(X,Y)定義表面點的n個。我正在尋找一種線性算法,特別是樣條逼近算法。一個示例算法或至少一些指針會很好。

+0

[wikipedia] [1]文章有點令人望而生畏,但至少試着看一下例子部分。 [1]:http://en.wikipedia.org/wiki/Spline_interpolation – 2012-03-11 16:48:25

+1

你是一個常規網格上的x,y控制點嗎? – 2012-03-11 17:41:30

+0

對於形式f(x,y)的函數,更常見的是對基礎數據的形式(度數K的多項式,N個高斯之和等)進行假設,然後用最小二乘法確定係數。在這裏工作?你知道什麼數據代表什麼?如果你真的想要樣條,那麼NURBS http://en.wikipedia.org/wiki/NURBS值得一看。他們有很好的渲染屬性。構造(x,y)點的Delaunay三角剖分以獲得基礎,除非它們位於規則網格上。對於平面擬合,您需要一個標準的最小二乘擬合。 – Gene 2014-05-07 06:04:05

回答

1

您可以使用您的點作爲貝塞爾曲面(或Bspline)曲面的控制點,尤其是如果(xi, yi)XY平面中對矩形進行了樣本點。在這方面,沒有涉及的配件。

您將得到的表面將位於您的點的凸包中,並將相交(插入)在邊界{xi, yi}處的點。

如果您想嘗試,This forums posting似乎包含在Matlab簡單的代碼,並且可以使用GuIRIT做同樣的,如果你沒有做Matlab(儘管它需要搞清楚程序的文件格式) 。

+0

最終的實現必須用ruby - 所以Matlab不是真正的選擇。但這個問題確實是關於XY平面上的一個矩形。 – tcurdt 2012-03-11 21:50:43

+0

我從來沒有使用Ruby,但我確定有一個Bezier/Bspline包。 – user1071136 2012-03-11 21:58:36

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. 在每個三角形上,通過三個頂點找到平面。這是您需要的線性插值。

下實現在Python前兩個步驟。網格的規律性可能會讓你加快速度(這也可能導致三角測量的混亂)。

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沒有真正的樣條泛化。除了基於三角測量的方法,你可以看看巴恩斯(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 2014-05-06 10:14:17

+0

逼近聽起來也像一個有趣的角度。 – tcurdt 2014-05-06 10:15:00

+0

+1用於徑向基函數。我幾年前寫了一篇論文,將這些對象推廣到流形上的函數。只要你沒有密集的團隊,並且點的數量不會太大,他們就能很好地工作。 (如果n確實變大了,那麼你希望你的RBF具有緊湊的支持,這樣所涉及的矩陣是稀疏的,但是你需要使用稀疏線性代數來保持其可擴展性。)好的,平滑的插值。 – 2014-05-11 14:19:22