Метод расчета центра масс из файла .stl (стерео литография)? - PullRequest
7 голосов
/ 18 января 2010

Я пытаюсь вычислить координаты центра масс (x, y, z) объекта, определенного в файле STL (стерео литография, не путать со стандартной библиотекой шаблонов). Файл STL содержит замкнутый объект (или объекты), ограниченный границей из треугольников. Сами треугольники не обязательно расположены в любом порядке, файл представляет собой просто координаты 3 вершин каждого треугольника, плавающего в трехмерном пространстве, плюс вектор нормали к треугольнику (нормаль должна игнорироваться, так как это не всегда делается правильно). Ничто не связывает каждый треугольник друг с другом, предполагается, что объект закрыт.

Один простой подход состоит в том, чтобы разделить объем (в данном случае прямоугольник) на миллионы элементов и определить, находится ли каждый элемент внутри объекта, определенного в файле STL, или нет, затем суммировать моменты и вычислить центр массы Это будет работать, но далеко не элегантно и крайне медленно.

Другим методом было бы преобразование граничного представления в число упакованных твердых тел тетраэдра. Сформируйте, чтобы я мог рассчитать центр масс каждого тетраэдра, его объем и результирующий момент и, таким образом, рассчитать общий центр масс из суммы всех тетраэдров. Проблема в том, что я не знаю, как преобразовать поверхностное представление треугольников в объемное представление тетраэдров (я предполагаю, что это довольно нетривиальная задача).

Кто-нибудь знает какие-нибудь методы или может придумать какие-нибудь методы, которые я мог бы попробовать? Или, может быть, какой-либо справочный материал, который говорит об этом?

Для получения дополнительной информации о файлах STL (важны только первые 2 раздела, все остальное бесполезно): http://en.wikipedia.org/wiki/STL_%28file_format%29

Ответы [ 2 ]

12 голосов
/ 18 января 2010

После долгих размышлений и экспериментов у меня есть ответ!

Сначала мы добавляем 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.

1 голос
/ 18 января 2010

РЕДАКТИРОВАТЬ: Посмотрите "алгоритм числа обмоток" или "алгоритм числа пересечения" - ниже я пытаюсь описать алгоритм пересечения 3-го числа.

У меня такое ощущение, что что-то подобное будет работать, но у меня нет возможности проверить это прямо сейчас:

Построить заполненную трехмерную структуру из треугольников в файле STL итеративно. Начните с выбора одной точки для использования в качестве основы для 3-й структуры. Затем начните свою структуру с создания треугольной пирамиды с основанием, определенным первым треугольником в файле STL, и вершины выбранной точки. Каждый такой компонент вашего итеративно построенного тома также будет содержать «четность пересечения» - инициализируйте его значением 0.

Для каждого последующего треугольника в файле STL создайте подобную пирамиду и посмотрите, не пересекается ли она с трехмерной структурой, которую вы построили до сих пор. Если это так, вычислите пересечение и сегментируйте существующую структуру и новую пирамиду так, чтобы никакие два компонента не перекрывались. Сохраняйте «четность пересечения» самой внешней части нового многогранника 0, но переключайте его на все внутренние части пересечения - если это было 0, сделайте это 1, если это было 1, сделайте это 0.

В конце концов, у вас будет замкнутый многогранник, определяемый всеми частями вашей структуры, имеющими четность пересечения 0. Вычислите моменты всех этих многогранников и усредните их вместе, чтобы получить свой центр масс. Я думаю, что сложность была бы что-то вроде O (n ^ 2).

...