После долгих размышлений и экспериментов у меня есть ответ!
Сначала мы добавляем 4-ю точку к каждому треугольнику, чтобы превратить их в тетраэдры с объемным центроидом. Мы рассчитываем объемы и центры масс и умножаем их друг на друга, чтобы получить наши моменты. Мы суммируем моменты и делим на общий объем, чтобы получить наш общий центроид.
Мы рассчитываем объемы, используя определенный метод, показанный здесь (уравнение 32): http://mathworld.wolfram.com/Tetrahedron.html
Центроиды каждого из тетраэдров - это просто среднее значение 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.