Tengo un poliedro convexo cerrado que se define mediante una matriz de polígonos (caras) convexos que se definen mediante matrices de vértices en el espacio 3D. Estoy tratando de encontrar el centroide del poliedro, suponiendo una densidad uniforme. Por el momento lo calculo con el algoritmo en este pseudo-código.Centroide de poliedro convexo
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;
}
Esto esencialmente toma el promedio ponderado de los centroides de las caras. No estoy 100% seguro de que esto sea correcto ya que no he podido encontrar un algoritmo correcto en línea. Si alguien pudiera confirmar mi algoritmo o referirme a uno correcto, lo agradecería.
Gracias.
[EDIT]
Así que aquí es el código Java real que estoy utilizando para encontrar el centro de gravedad. Rompe el poliedro en pirámides que convergen en un punto arbitrario dentro del poliedro. El promedio ponderado para los centroides de la pirámide se basa en la siguiente fórmula.
C todo = SUM todas las pirámides (C pirámide * volumen pirámide)/volumen todo
Aquí está el (fuertemente código comentado):
// 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);
No dude en hacerme cualquier pregunta que pueda tener ab sacarlo o señalar cualquier error que vea.
No puedo responder por él, pero http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html podría valer la pena un vistazo. – dmuir
El bit después de "' [Editar] '" de [esta respuesta] (http://stackoverflow.com/a/4824248/71059) a una pregunta similar se ve bien. – AakashM
En su código, ha inicializado un centroide pero nunca lo ha utilizado dentro del ciclo. De acuerdo con su fórmula, la divide por la suma de todos los volúmenes al final. ¿No debería el centroide resumir todos los de avgToCentroid (centroid.add (avgToCentroid))? lo mismo que el volumen es la suma de todos los volúmenes de la pirámide? –