凸多面体的质心 [英] Centroid of convex polyhedron

查看:622
本文介绍了凸多面体的质心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  public Vector3 getCentroid(){
Vector3质心=(0,0,0);
(face in face){
Vector3 point = face.centroid;
point.multiply(face.area());
centroid.add(point);
}
centroid.divide(faces.size());
返回质心;
}

这基本上取了面的质心的加权平均值。我不是100%确定这是正确的,因为我没有能够在网上找到正确的算法。如果有人可以确认我的算法,或者将我引荐给正确的算法,我将不胜感激。



谢谢。








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

C all = SUM all pyramids ( C pyramid * volume pyramid )/ volume all



em> heavy 评论代码):

  //计算面部质心的平均值。 
//这给了多面体内的一个任意点。
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());

//初始化质心和音量。
centroid = new Vector3(0,0,0);
volume = 0;

//循环播放每张脸。
for(int i = 0; i< faces.size(); i ++){
Face face = faces.get(i);

//从avgPoint查找面向质心的向量。
Vector3 avgToCentroid = face.centroid.clone();
avgToCentroid.sub(avgPoint);

//在avgPoint上给出面和平行平面之间的无符号最小距离。
float distance = avgToCentroid.scalarProjection(face.getNormal());

//使用V = 1/3 * B * h
//找到金字塔的体积,其中:B =金字塔底部的面积。
// h =金字塔高度。
float pyramidVolume = face.getArea()* distance / 3;

//金字塔的质心是基地高度的1/4。
//在这里使用3/4是因为矢量在金字塔的下方行进。
avgToCentroid.multiply(0.75f);
avgToCentroid.add(avgPoint);
// avgToCentroid现在是金字塔的质心。

//用金字塔的体积来衡量它。
avgToCentroid.multiply(pyramidVolume);

音量+ = pyramidVolume;
}

//平均金字塔质心的加权和。
centroid.divide(volume);

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

解决方案

一般来说,这取决于多面体的结构。有4种可能的情况:


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

    $ $ $ $ $ $ $ $ $ r_c = sum(r_i * m_i)/ sum(m_i)

    这里 r_i 是代表第i个顶点的矢量, m_i - 它的质量。等同质量的案例给我们留下了更简单的公式:

      r_c = sum(r_i)/ n 

    其中 n 是顶点的数量。请注意,两个总和都是向量化的。


  • 只有边有重量,多面体本质上是一个尸体。这种情况可以通过用位于边缘正中间的顶点代替每个边并且具有整个边的权重来减少到前一个。

  • 只有面部有重量。这种情况也可以归结为第一种情况。每个面都是2D凸面图形,其中心可以找到。 固体多面体(您的情况,从假设均匀密度的推断出来的)。这个问题需要更复杂的方法。第一步是将多面体分成四面体。以下是关于如何执行此操作的简短说明。对于四面体质心位于所有中位数相交的点。 (四面体的中值是连接其顶点和相对面的质心的线。)下一步是用该质心替换分区中的每个四面体。最后一步是找到所得加权点集合的质心,这正是第一种情况。

I have a closed convex polyhedron which is defined by an array of convex polygons (faces) which are defined by arrays of vertices in 3D space. I'm trying to find the centroid of the polyhedron, assuming uniform density. At the moment I calculate it with the algorithm in this pseudo-code.

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;
}

This essentially takes the weighted average of the centroids of the faces. I'm not 100% sure this is correct as I haven't been able to find a correct algorithm online. If someone could either confirm my algorithm or refer me to a correct one I would appreciate it.

Thanks.


[EDIT]

So here is the actual Java code I am using to find the centroid. It breaks the polyhedron into pyramids converging on an arbitrary point inside the polyhedron. The weighted average for the pyramid centroids is based on the following formula.

Call = SUMall pyramids(Cpyramid * volumepyramid) / volumeall

Here is the (heavily commented code):

    // 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);

Please feel free to ask me any questions you may have about it or point out any errors you see.

解决方案

Generally that depends on the structure of your polyhedron. There are 4 possible cases:

  • Only vertices have weight, i.e. your polyhedron is the system of points. Then you can just calculate the mean value of the weighted sum of all the points:

    r_c = sum(r_i * m_i) / sum(m_i)
    

    Here r_i is the vector representing the i-th vertex, m_i - its mass. Case of equal masses leaves us with the simpler formula:

    r_c = sum(r_i) / n
    

    Where n is the number of vertices. Note that both sums are vectorized.

  • Only edges have weight, and polyhedron is essentially a carcass. This case can be reduced to the previous one by substituting each edge with vertex situated right in the middle of the edge and have the weight of the whole edge.

  • Only faces have weight. This case can be reduced to the first one as well. Each face is a 2D convex figure, of which the centroid can be found. Substituting each face with its centroid brings this case to the first one.

  • Solid polyhedron (your case, inferring from the "assuming uniform density"). This problem requires a more complicated approach. First step is to split polyhedron into tetrahedrons. Here is the short description on how to do this. For a tetrahedron centroid is situated in the point where all its medians intersect. (Median of a tetrahedron is the line that connects its vertex and the centroid of the opposite face.) The next step is to substitute each tetrahedron in the partition with its centroid. And the last step is to find the centroid of the resulting set of weighted points, which is exactly the first case.

这篇关于凸多面体的质心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆