样条曲面插值

时间:2012-03-11 15:51:20

标签: algorithm math 3d spline

假设我在z轴上有n个定义曲面的点

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

现在我希望能够近似f(x,y)。我正在寻找一种线性算法,尤其是样条逼近算法。一个示例算法或至少一些指针会很棒。

3 个答案:

答案 0 :(得分:4)

这是对线性近似方法的模糊描述。

  1. 确定点的Voronoi diagram(对于飞机中的每个点,找到最近的(x_i,y_i)
  2. 如果有一个点的线段,则(x_i,y_i)(x_j,y_j)取得Delaunay triangulation:连接(x_i,y_i)(x_j,y_j)。是等距的(并且比任何其他对更近)。
  3. 在每个三角形上,找到穿过三个顶点的平面。这是您需要的线性插值。

  4. 以下实现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)
    

答案 1 :(得分:2)

对不规则2D数据的插值并不容易。我知道对不规则2D没有真正的样条推广。

除了基于三角测量的方法之外,您还可以查看Barnes(http://en.wikipedia.org/wiki/Barnes_interpolation)和反距离加权(http://en.wikipedia.org/wiki/Inverse_distance_weighting),或者更一般地看看RBF(http://en.wikipedia.org/wiki/Radial_basis_functions)。< / p>

如果你的点非均匀扩散(密集簇),可能需要使函数的大小自适应,或者采用近似而不是插值。

答案 2 :(得分:1)

您可以将点用作Bezier(或Bspline)曲面的控制点,尤其是(xi, yi)XY平面中采样矩形时。在这方面,没有涉及适合。

您将获得的曲面将位于您的点的凸包中,并将在{xi, yi}的边界处相交(插值)点。

如果您想要进行实验,This forums posting似乎包含Matlab中的简单代码,如果您没有Matlab,则可以使用GuIRIT执行相同操作(虽然它需要弄清楚程序的文件格式)。