我有一个封闭的凸多面体,它由一组凸多边形(面)定义,这些多边形由 3D 空间中的顶点数组定义。我试图找到多面体的质心,假设密度均匀。目前我用这个伪代码中的算法计算它。

public Vector3 getCentroid() {
    Vector3 centroid = (0, 0, 0);
    for (face in faces) {
        Vector3 point = face.centroid;
        point.multiply(face.area());
        centroid.add(point);
    }
    centroid.divide(faces.size());
    return centroid;
}

这本质上是取人脸质心的加权平均值。我不是 100% 确定这是正确的,因为我无法在网上找到正确的算法。如果有人可以确认我的算法或向我推荐正确的算法,我将不胜感激。

谢谢。

[编辑]

所以这是我用来查找质心的实际 Java 代码。它将多面体分解为会聚在多面体内部任意点上的金字塔。金字塔质心的加权平均值基于以下公式。

Call = SUMall pyramids(Cpyramid * volumepyramid)/volumeall

这是(大量注释的代码):
    // Compute the average of the facial centroids.
    // This gives an arbitrary point inside the polyhedron.
    Vector3 avgPoint = new Vector3(0, 0, 0);
    for (int i = 0; i < faces.size(); i++) {
        avgPoint.add(faces.get(i).centroid);
    }
    avgPoint.divide(faces.size());

    // Initialise the centroid and the volume.
    centroid = new Vector3(0, 0, 0);
    volume = 0;

    // Loop through each face.
    for (int i = 0; i < faces.size(); i++) {
        Face face = faces.get(i);

        // Find a vector from avgPoint to the centroid of the face.
        Vector3 avgToCentroid = face.centroid.clone();
        avgToCentroid.sub(avgPoint);

        // Gives the unsigned minimum distance between the face and a parallel plane on avgPoint.
        float distance = avgToCentroid.scalarProjection(face.getNormal());

        // Finds the volume of the pyramid using V = 1/3 * B * h
        // where:   B = area of the pyramid base.
        //          h = pyramid height.
        float pyramidVolume = face.getArea() * distance / 3;

        // Centroid of a pyramid is 1/4 of the height up from the base.
        // Using 3/4 here because vector is travelling 'down' the pyramid.
        avgToCentroid.multiply(0.75f);
        avgToCentroid.add(avgPoint);
        // avgToCentroid is now the centroid of the pyramid.

        // Weight it by the volume of the pyramid.
        avgToCentroid.multiply(pyramidVolume);

        volume += pyramidVolume;
    }

    // Average the weighted sum of pyramid centroids.
    centroid.divide(volume);

请随时问我您对此的任何问题或指出您看到的任何错误。

最佳答案

通常,这取决于多面体的结构。有4种可能的情况:

  • 只有顶点才有权重,即你的多面体是点系统。然后你可以计算所有点的加权和的平均值:
    r_c = sum(r_i * m_i) / sum(m_i)
    

    这里 r_i 是表示第 i 个顶点的 vector ,m_i - 它的质量。质量相等的情况给我们留下了更简单的公式:
    r_c = sum(r_i) / n
    

    其中 n 是顶点数。请注意,两个总和都是矢量化的。
  • 只有边有重量,多面体本质上是一个骨架。这种情况可以通过将每条边替换为位于边中间的顶点并具有整个边的权重来减少到前一种情况。
  • 只有面有重量。这种情况也可以简化为第一种情况。每个面都是一个二维凸图,可以找到其中的质心。用其质心替换每个面将这个案例带到第一个。
  • 固体多面体(你的情况,从“假设均匀密度”推断)。这个问题需要更复杂的方法。第一步是将多面体分成四面体。这是关于如何执行此操作的 short description。对于四面体质心位于其所有中线相交的点。 (四面体的中位数是连接其顶点和相对面质心的线。)下一步是用其质心替换分区中的每个四面体。最后一步是找到结果加权点集的质心,这正是第一种情况。
  • 10-06 06:03