Tôi có một đa diện lồi khép kín được xác định bởi một mảng đa giác lồi (mặt) được xác định bởi mảng các đỉnh trong không gian 3D. Tôi đang cố gắng để tìm thấy trung tâm của đa diện, giả sử mật độ thống nhất. Tại thời điểm này tôi tính toán nó với thuật toán trong mã giả này.Centroid của đa diện lồi
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;
}
Điều này về cơ bản có trọng số trung bình của trọng tâm của khuôn mặt. Tôi không chắc chắn 100% điều này là chính xác vì tôi đã không thể tìm thấy một thuật toán chính xác trực tuyến. Nếu ai đó hoặc có thể xác nhận thuật toán của tôi hoặc giới thiệu tôi đến một chính xác tôi sẽ đánh giá cao nó.
Cảm ơn.
[EDIT]
Vì vậy, đây là mã Java thực tế tôi đang sử dụng để tìm ra trọng tâm. Nó phá vỡ đa diện thành kim tự tháp hội tụ trên một điểm tùy ý bên trong đa diện. Trọng số trung bình cho các kim tự tháp centroid dựa trên công thức sau đây.
C tất cả = SUM tất cả các kim tự tháp (C kim tự tháp * khối lượng kim tự tháp)/khối lượng tất cả
Đây là (nặng nề nhận xét 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);
Vui lòng hỏi tôi bất kỳ câu hỏi nào bạn có thể có hoặc chỉ ra bất kỳ lỗi nào bạn thấy.
tôi không thể xác minh cho nó nhưng http://www.cs.berkeley.edu/~jfc/mirtich/massProps.html có thể là đáng xem. – dmuir
Các bit sau khi "' [Chỉnh sửa] '" của [câu trả lời này] (http://stackoverflow.com/a/4824248/71059) cho một câu hỏi tương tự có vẻ tốt. – AakashM
Trong mã của bạn, bạn đã khởi tạo một centroid nhưng không bao giờ sử dụng nó trong vòng lặp. Theo công thức của bạn, bạn chia nó cho tổng của tất cả các tập ở cuối. Không nên centroid tổng hợp tất cả avgToCentroid's (centroid.add (avgToCentroid))? giống như khối lượng là tổng của tất cả các khối kim tự tháp? –