scipy 计算不规则表面下的体积

2uluyalo  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(145)

我有一组非参数的data points,我需要计算它们下面的体积,我现在要做的是,首先使用线性插值来增加点,然后基本上实现离散积分。

所有的点都应该放置在半径为radius的圆柱体内,所以我删除了阈值之外的所有点。真实的体积为5485立方米,但我的函数返回6380。我有两个问题:
1.为什么n_points(插值点数)不改变函数的输出?我尝试了(10,10)(50,50)(100,100)网格,结果几乎没有变化。
1.为什么结果中会有这么大的误差呢,就像我说的,我基本上只是在积分,就我所知,我在积分的过程中没有犯任何错误。

def calculate_volume2(x, y, z, radius, n_points):
    x_points = n_points
    y_points = n_points
    # creating sample points for integral
    X = np.linspace(-radius, radius, x_points)
    Y = np.linspace(-radius, radius, y_points)
    X, Y = np.meshgrid(X, Y)

    # Interpolating object
    # l = list(zip(x, y))
    interp1 = scipy.interpolate.LinearNDInterpolator(
        list(zip(x, y)), z, rescale=True)

    # Interpolating sample point
    Z0 = interp1(X, Y)

    # Integral
    sum_of_z = 0
    num_of_valid_sample = 0
    interp_points = np.zeros((1, 3))
    for i in range(len(Z0)):
        for j in range(len(Z0[i])):
            # checking if sample point is in cylinder boundary and interpolating value is valid
            if (not isnan(Z0[i][j])) and sqrt((X[i][j]) ** 2 + (Y[i][j]) ** 2) <= radius:
                num_of_valid_sample = num_of_valid_sample + 1
                sum_of_z += Z0[i][j]
                point = np.array([X[i][j], Y[i][j], Z0[i][j]])
                point = point.reshape(1, 3)
                interp_points = np.concatenate((interp_points, point), axis=0)
    # calculating surface of each sample tile: surface of cylinder base / number of samples
    surface_of_each_sample = pi * (radius ** 2) / num_of_valid_sample

    volume = sum_of_z * surface_of_each_sample
    height_avg = volume / (pi * (radius ** 2))
    return volume, interp_points, height_avg, surface_of_each_sample

编辑:radius在这种情况下是11. 82米。

vvppvyoh

vvppvyoh1#

正如在评论中提到的,LinearNDInterpolator不是在规则网格上插值数据的最佳工具,因为它通过the QHull library使用三角测量,所以它是针对分散的数据设计的。
对于规则网格上的数据,首选RegularGridInterpolator(...., method="linear")
然而,在计算分段线性曲面下的体积时,实际上并不需要这些公式,给定由xyz数组定义的网格上的数据,双线性插值--本质上是一个二维梯形公式--的积分为

trpz = .25*(diff(x)[:, None]*diff(y)[None, :]
             * (z[:-1, :-1] + z[1:, :-1] + z[:-1, 1:] + z[1:, 1:])).sum()

公式来自scipy tests,我记得至少检查过一次,但您可能需要根据您的定义调整它(例如,z数组是1D还是2D等)。

相关问题