一种从 .stl(立体光刻)文件计算质心的方法? [英] A method to calculate the centre of mass from a .stl (stereo lithography) file?

查看:55
本文介绍了一种从 .stl(立体光刻)文件计算质心的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试计算 STL 文件(立体光刻,不要与标准模板库混淆)中定义的对象的质心 (x,y,z) 坐标.STL 文件包含由三角形组成的边界定义的封闭对象(或多个对象).三角形本身不一定按任何顺序排列,文件只是漂浮在 3D 空间中的每个三角形的 3 个顶点的坐标加上三角形的法线向量(法线应该被忽略,因为它并不总是正确完成).没有任何东西将每个三角形相互联系起来,假设对象是封闭的.

I am trying to calculate the centre of mass (x,y,z) coordinates of an object defined in an STL file (stereo lithography, not to be confused with the standard template library). The STL file contains a closed object (or objects) defined by a boundary made of triangles. The triangles themselves are not necessarily in any order, the file is simply the coordinates 3 vertices of each triangle floating in 3D space plus a normal vector to the triangle (the normal should be disregarded as it is not always done properly). There is nothing that links each triangle to one another, it is assumed that the object is closed.

一种简单的方法是将一个体积(在这种情况下,一个盒子)分成数百万个元素,并确定每个元素是否在 STL 文件中定义的对象内部,然后总结矩并计算中心质量.这会起作用,但它远非优雅且极其缓慢.

One simple approach would be to divide a volume (in this case, a box) into millions of elements and determine if each element is inside the object defined in the STL file or not, then sum up the moments and calculate the centre of mass. This would work but its far from elegant and extremely slow.

另一种方法是将边界表示转换为多个堆积的四面体实体.形成我可以计算每个四面体的质心、体积和产生的力矩,从而从所有四面体的总和计算整体质心的形式.问题在于我不知道如何将三角形的表面表示转换为四面体的体积表示(我假设这是一项相当重要的任务).

Another method would be to convert the boundary representation into a number of packed tetrahedron solids. Form that I could calculate the centre of mass of each tetrahedron, its volume, and resulting moment and thus calculate the overall centre of mass from the sum of all tetrahedrons. The problem with this is that I don't know how to convert a surface representation of triangles into a volume representation of tetrahedrons (I'm assuming its a fairly non trivial task).

有谁知道任何方法或能想到我可以尝试的任何方法?或者甚至可能有任何关于此的参考资料?

Dose anyone know of any methods or can think up of any methods that I could try? Or maybe even any reference material that talks about this?

关于 STL 文件的更多信息(只有前 2 部分很重要,其他一切都没用):http://en.wikipedia.org/wiki/STL_%28file_format%29

For more information about STL files (only the first 2 sections are important, everything else is useless): http://en.wikipedia.org/wiki/STL_%28file_format%29

推荐答案

经过大量思考和实验,我有了答案!

After a lot of thinking and experimentation I have the answer!

首先,我们为每个三角形添加第 4 个点,使它们成为具有体积质心的四面体.我们计算体积和质量中心,并将它们相互乘以得到我们的时刻.我们将矩求和并除以总体积以获得整体质心.

First we add a 4th point to each triangle in to make them into tetrahedrons with a volume centroid. We calculate the volumes and centres of masses and multiply them by each other to get our moments. We sum the moments and divide by total volume to get our overall centroid.

我们使用此处显示的确定方法(方程 32)计算体积:http://mathworld.wolfram.com/四面体.html

We calculate volumes using the determinate method shown here (equation 32): http://mathworld.wolfram.com/Tetrahedron.html

每个四面体的质心只是 4 个点的平均值.

The centroids of each of the tetrahedrons is simply the average of the 4 points.

这里的技巧是,由于 STL 文件的创建方式,三角形的法线从零件表面向外指向,遵循用于创建三角形的 3 个顶点的右手定则.我们可以通过允许我们有一个一致的约定来利用这个优势来确定是否应该从我们的净部分中添加或减去四面体的体积(这是因为我们选择的参考点可能不一定在部分内部并且整体部分不一定是凸面的,而是一个封闭的物体)

The trick here is that due to the way the STL file is created, the triangles have a normal that point outwards from the part surface, following the right hand rule of the 3 verticies used to create the triangle. we can use this to our advantage by allowing us to have a consistent convention in which to determine if a volume of the tetrahedron should be added or subtracted from our net part (this is because the reference point we chose may not necessarily be inside the part and the overall part is not necessarily convex, it is, however a closed object).

使用确定方法计算体积,前三个坐标点将代表我们三角形的三个点.第四点是我们的共同起源.如果三角形创建的法线(遵循从点 1、2、3 开始的右手法则)指向我们的共同参考点,则该体积将被计算为不是我们整体实体的一部分或负体积(通过指向,我的意思是由三角形的法线创建的向量松散地指向与从我们的参考点到四面体质心的向量创建的法线平面的同一侧).如果向量指向远离参考点,则它是正体积或零件内部.如果正常,则体积变为零,因为三角形与参考点在同一平面上.

Using the determine method to calculate the volume, the first three coordinate points will represent the three points of our triangle. The fourth point would be our common origin. If the normal created by the triangle (following the right hand rule going from point 1, 2, 3) points towards our common reference point, that volume will be calculated as not part of our overall solid, or negative volume (by pointing towards, i mean the vector created by the triangle's normal is pointing loosely towards the same side as a normal plane created by the vector from our reference point to the centroid of the tetrahedron). If the vector is pointing away from the reference point, it is then positive volume or inside the part. If it is normal, then the volume goes to zero as the triangle is in the same plane as the reference point.

我们不需要担心实际跟踪任何这些,就好像我们与我们的输入一致(因为三角形遵循右手规则,从零件正常面向外)确定会给我们正确的符号.

We don't need to worry about actually keeping track of any of this as if we are consistent with our inputs (as in the triangles follow the right hand rule with normal facing outwards from the part) the determine will give us the correct sign.

无论如何,这是代码(比解释更简单).

Anyways, heres the code (its even more simple than the explanation).

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 文件的质心非常快.

Extremely fast for calculating centres of mass for STL files.

这篇关于一种从 .stl(立体光刻)文件计算质心的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆