Ho un poliedro convesso chiuso che è definito da una matrice di poligoni convessi (facce) che sono definiti da matrici di vertici nello spazio 3D. Sto cercando di trovare il centroide del poliedro, assumendo una densità uniforme. Al momento lo calcolo con l'algoritmo in questo pseudo-codice.Centroide di poliedro convesso
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;
}
prende questo essenzialmente la media ponderata dei centroidi delle facce. Non sono sicuro al 100% che ciò sia corretto in quanto non sono stato in grado di trovare un algoritmo corretto online. Se qualcuno potesse confermare il mio algoritmo o farmi riferimento a uno corretto, lo apprezzerei.
Grazie.
[EDIT]
ecco il codice Java vero e proprio che sto usando per trovare il baricentro. Rompe il poliedro in piramidi che convergono su un punto arbitrario all'interno del poliedro. La media ponderata per i centroidi piramidali si basa sulla seguente formula.
C tutti = SUM tutte le piramidi (C piramide * Volume piramide)/Volume tutti
Ecco la (pesantemente commentato codice):
// 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);
Non esitate a farmi tutte le domande che potreste avere fuori o segnalare eventuali errori che vedi.
non posso garantire per esso, ma http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html forse vale la pena dare un'occhiata. – dmuir
Il bit dopo "' [Modifica] '" di [questa risposta] (http://stackoverflow.com/a/4824248/71059) a una domanda simile sembra buono. – AakashM
Nel codice, è stato inizializzato un centroide ma non lo si è mai utilizzato all'interno del ciclo. Secondo la tua formula, la dividi per la somma di tutti i volumi alla fine. Il centroide non dovrebbe sommare tutti i valori di avgToCentroid (centroid.add (avgToCentroid))? come il volume è la somma di tutti i volumi piramidali? –