凸多面体的质心

nul*_*ter 7 java math geometry physics physics-engine

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

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;
}
Run Code Online (Sandbox Code Playgroud)

这基本上取面的质心的加权平均值.我不是100%确定这是正确的,因为我无法在线找到正确的算法.如果有人可以确认我的算法或引用我一个正确的算法我会很感激.

谢谢.


[编辑]

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

C all = SUM 所有金字塔(C 金字塔*体积金字塔)/体积全部

这里是(大量注释的代码):

    // 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);
Run Code Online (Sandbox Code Playgroud)

如果您有任何问题,请随时向我询问或指出您看到的任何错误.

And*_*rei 7

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

  • 只有顶点有权重,即你的多面体是点系统.然后你可以计算所有点的加权和的平均值:

    r_c = sum(r_i * m_i) / sum(m_i)
    
    Run Code Online (Sandbox Code Playgroud)

    r_i是表示第i个顶点的向量m_i- 其质量.同等群众的情况给我们留下了更简单的公式:

    r_c = sum(r_i) / n
    
    Run Code Online (Sandbox Code Playgroud)

    n顶点的数量在哪里.请注意,两个总和都是矢量化的.

  • 只有边缘有重量,多面体基本上是一个胴体.通过用位于边缘中间的顶点替换每个边缘并且具有整个边缘的权重,可以将这种情况简化为前一个边缘.

  • 只有脸有重量.这种情况也可以减少到第一种情况.每个面都是2D凸面图,其中可以找到质心.用它的质心代替每个面将这种情况带到第一个面.

  • 实心多面体(您的情况,从"假设均匀密度"推断).这个问题需要更复杂的方法.第一步是将多面体分割成四面体.以下是如何执行此操作的简短说明.对于四面体质心位于其所有中位数相交的点.(四面体的中位数是连接其顶点和相对面的质心的线.)下一步是用分区中心替换分区中的每个四面体.最后一步是找到所得加权点集的质心,这正是第一种情况.