python - N 维直线网格每个单元的质心

标签 python math geometry numerical-methods

我有一个 n 维直线网格,每个维度 i 的边缘由 x_i = {x[i, 0], x[i,1], ..., x[i, Ni-1], x[i, Ni]} 给出,与 N_i该维度中的边缘。然后我有一些密度y ,形状 (N0, N1, ... Ni, ... Nn-1)在每个网格顶点定义。我们可以假设密度平滑变化,并且可以通过在顶点之间平滑(线性)插值来计算顶点之间(即单元内)的密度。如何找到每个单元/箱的每个维度的质心?

请注意,答案不仅仅是每个箱边缘的 y 加权平均值。例如,考虑 x 坐标为 [0.0, 1.0] 的 2D 网格。 ,和密度[[0.0, 0.0], [1.0, 2.0]] 。顶点的 y 加权 x 位置为 1.0,但显然质心需要位于边缘之间的中间位置,而不是靠着边缘:

0.0--------2.0  -y2
 |          |
 |        * |
 |          |
 |          |
 |          |
0.0--------1.0  -y1

 |        |
 x1=0.0   x2=1.0

其中 * 近似于质心。

最佳答案

让我们假设密度分布在单元上,使用 bilinear interpolation具有归一化的单元格坐标 0..1和顶点值 f[ij] 。每个真实的单元格坐标都可以使用线性变换标准化为上述范围(减去左下角坐标,除以大小)。

要获得质心坐标,我们必须应用下一个公式

enter image description here

enter image description here

实际上:对于 2D 情况,我们将分母(“质量”)计算为 density(x,y) 的定双积分。超过x=0..1y=0..1范围和两个分子(向量分量)作为 density(x,y)*x 的积分和density(x,y)*y 。 (矢量形式的 3D(和 nD)情况看起来相似,但公式变得更加复杂。)

使用 Maple 评估这些积分给出下一个结果:

enter image description here

可以很容易地用 Python 实现,代码如下:

def mass_center_bilinear(f00, f10, f01, f11):
    mass = 1/4*f00+1/4*f10+1/4*f01+1/4*f11
    if mass == 0:
        return None
    x_int = 1/12*f00+1/6*f10+1/12*f01+1/6*f11
    y_int = 1/12*f00+1/12*f10+1/6*f01+1/6*f11
    return (x_int/mass, y_int/mass)

print(mass_center_bilinear(1,1,1,1))
print(mass_center_bilinear(0,0,0,1))
print(mass_center_bilinear(0,0,1,1))
print(mass_center_bilinear(0,1,2,3))
print(mass_center_bilinear(0,1,0,2))

(0.5, 0.5)
(0.6666666666666666, 0.6666666666666666)
(0.5, 0.6666666666666666)
(0.5555555555555555, 0.611111111111111)
(0.6666666666666666, 0.5555555555555555)  #mass center for your example

关于python - N 维直线网格每个单元的质心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72222161/

相关文章:

python - 如何通过向交叉熵添加负熵来创建自定义损失函数?

python - XOR bin 值时缺少 0

python - 需要有关加入 sqlalchemy 的帮助

ios - 从屏幕中心展开一个圆圈

swift - 在圆形 CGPath Swift 上添加 Sprite

python - urllib progresshook 不准确?

c++ - 确定两条线段是否相交的代码有什么问题?

matlab - 查找直线上某个点的坐标

xml - 带绝对值的 XSLT 条件测试

c# - 在 Entity Framework 中使用 Postgis 的几何类型