Centroid of convex polyhedron

醉酒当歌 提交于 2019-12-05 05:10:18
Andrei

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.

For the solid case, there's a much simpler method than trying to tetrahedralize the polyhedron (which has pitfalls).

Here's pseudo-ish java-ish code (assuming decent Vector3 implementation):

// running sum for total volume
double vol = 0;
// running sum for centroid
Vector3 centroid = (0, 0, 0);
for each triangle (a,b,c)
{
  // Compute area-magnitude normal
  Vector3 n = (b-a).cross(c-a);
  vol += a.dot(n)/6.;
  // Compute contribution to centroid integral for each dimension
  for(int d = 0;d<3;d++)
    centroid[d] += n[d] * ((a[d]+b[d])^2 + (b[d]+c[d])^2 + (c[d]+a[d])^2);
}
// final scale by inverse volume
centroid *= 1./(24.*2.*vol);

Note, if you have higher degree faces than triangles you can trivially triangulate with a fan and this will still work.

This conveniently works even if the polyhedron is not convex.

I've also posted matlab code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!