Mam zamknięty wielościan wypukły, który jest zdefiniowany przez tablicę wypukłych wielokątów (płaszczyzn), które są zdefiniowane przez tablice wierzchołków w przestrzeni 3D. Próbuję znaleźć środek ciężkości wielościanu, zakładając jednolitą gęstość. W tej chwili kalkuluję to algorytmem w tym pseudokodzie.Środek wypukłego wielościanu
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;
}
To zasadniczo przyjmuje średnią ważoną centroidów twarzy. Nie jestem w 100% pewien, czy to prawda, ponieważ nie udało mi się znaleźć prawidłowego algorytmu w Internecie. Jeśli ktoś mógłby potwierdzić mój algorytm lub skierować mnie na prawidłowy, byłbym wdzięczny.
Dzięki.
[EDIT]
Więc tutaj jest rzeczywisty kod Java używam znaleźć ciężkości. Łamie wielościan w piramidy zbiegające się w dowolnym punkcie wewnątrz wielościanu. Średnia ważona dla centroidów piramidy opiera się na następującej formule.
C wszystkie = suma wszystkie piramidy (C piramidy * objętość piramidy)/objętość wszystkie
Oto (silnie komentuje kodu):
// 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);
Proszę, zadaj mi jakiekolwiek pytania, które możesz mieć ab lub wskaż błędy, które widzisz.
nie mogę ręczyć za to, ale http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html może być warta obejrzenia. – dmuir
Bit po "' [Edytuj] '" z [tej odpowiedzi] (http://stackoverflow.com/a/4824248/71059) na podobne pytanie wygląda dobrze. – AakashM
W twoim kodzie zainicjowałeś środek ciężkości, ale nigdy nie używał go wewnątrz pętli. Zgodnie z Twoją formułą podzielisz ją na sumę wszystkich woluminów na końcu. Nie należy centroid sumować wszystkich avgToCentroid's (centroid.add (avgToCentroid))? tak samo jak objętość jest sumą wszystkich objętości piramidy? –