经过大量的思考和实验,我得到了答案!
首先,我们在每个三角形中添加第4个点,使它们成为具有体积质心的四面体.我们计算质量的体积和中心,并将它们相互乘以得到我们的时刻.我们总结时刻并除以总体积来得到我们的整体质心.
每个四面体的质心仅为4个点的平均值.
这里的技巧是,由于创建STL文件的方式,三角形具有从零件表面向外指向的法线,遵循用于创建三角形的3个顶点的右手规则.我们可以通过允许我们使用一致的约定来确定是否应该从我们的网络部分添加或减去四面体的体积(这是因为我们选择的参考点可能不一定在部分内部)并且整个部分不一定是凸的,但它是一个封闭的物体).
使用确定方法计算体积,前三个坐标点将代表三角形的三个点.第四点是我们的共同起源.如果由三角形创建的法线(遵循右手规则从点1,2,3开始)指向我们的公共参考点,则该体积将被计算为不是我们整体实体或负体积的一部分(通过指向,我的意思是由三角形法线创建的矢量松散地指向与从我们的参考点到四面体的质心的矢量创建的法线平面相同的一侧.如果矢量指向远离参考点,则它是正体积或在部件内部.如果是正常的,则由于三角形与参考点位于同一平面,因此体积变为零.
我们不需要担心实际上跟踪任何这些,就好像我们的输入一致(因为三角形遵循右手规则,正常面向外部),确定将给我们正确的符号.
无论如何,继承人的代码(它比解释更简单).
class data // 3 vertices of each triangle
{
public:
float x1,y1,z1;
float x2,y2,z2;
float x3,y3,z3;
};
int main ()
{
int numTriangles; // pull in the STL file and determine number of triangles
data * triangles = new triangles [numTriangles];
// fill the triangles array with the data in the STL file
double totalVolume = 0, currentVolume;
double xCenter = 0, yCenter = 0, zCenter = 0;
for (int i = 0; i < numTriangles; i++)
{
totalVolume += currentVolume = (triangles[i].x1*triangles[i].y2*triangles[i].z3 - triangles[i].x1*triangles[i].y3*triangles[i].z2 - triangles[i].x2*triangles[i].y1*triangles[i].z3 + triangles[i].x2*triangles[i].y3*triangles[i].z1 + triangles[i].x3*triangles[i].y1*triangles[i].z2 - triangles[i].x3*triangles[i].y2*triangles[i].z1) / 6;
xCenter += ((triangles[i].x1 + triangles[i].x2 + triangles[i].x3) / 4) * currentVolume;
yCenter += ((triangles[i].y1 + triangles[i].y2 + triangles[i].y3) / 4) * currentVolume;
zCenter += ((triangles[i].z1 + triangles[i].z2 + triangles[i].z3) / 4) * currentVolume;
}
cout << endl << "Total Volume = " << totalVolume << endl;
cout << endl << "X center = " << xCenter/totalVolume << endl;
cout << endl << "Y center = " << yCenter/totalVolume << endl;
cout << endl << "Z center = " << zCenter/totalVolume << endl;
}
计算STL文件的质心非常快.