我有一个 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]
。每个真实的单元格坐标都可以使用线性变换标准化为上述范围(减去左下角坐标,除以大小)。
要获得质心坐标,我们必须应用下一个公式
实际上:对于 2D 情况,我们将分母(“质量”)计算为 density(x,y)
的定双积分。超过x=0..1
和y=0..1
范围和两个分子(向量分量)作为 density(x,y)*x
的积分和density(x,y)*y
。 (矢量形式的 3D(和 nD)情况看起来相似,但公式变得更加复杂。)
使用 Maple 评估这些积分给出下一个结果:
可以很容易地用 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/