4

我有 .stl(STL 是 3D Systems 创建的立体光刻 CAD 软件的原生文件格式)文件,我必须从中计算体积。我该怎么做呢?我正在使用下面的计算,但体积不等于其他软件计算的

float x1,y1,z1;
float x2,y2,z2;
float x3,y3,z3;

以上是顶点。triangles只是一个包含每个三角形顶点的对象的数据结构。

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;

您是否还涉及法向量的计算?

4

2 回答 2

6

多面体的体积在维基百科的多面体文章中进行了讨论。任何有效的 STL 镶嵌必须精确地是一个多面体,其中每个面都是一个边,所以这里讨论的公式成立。

假设顶点逆时针方向(向下看向外的法线),以下展开成立: 根据三角形顶点展开

等式 1 只是多面体的散度公式。p[i,j] 是第 i 个三角形的第 j 个顶点(作为来自原点的向量)。

等式 2 通过使用两个三角形边(平行四边形)的叉积是三角形的法向量,其幅值是三角形面积的两倍,对此进行了扩展。

顺便说一句,这就是为什么三角形法线没有出现在你的表情中,即使你的直觉说它应该以某种方式存在。它已经在汤里了!

等式 3 只是使用叉积的分布特性扩展了等式 2,并且向量与自身相交的事实是零向量。

您从等式 3 中得到的体积是根据三角形的方向进行签名的。我已调整我的公式以同意您的代码,但您可能会得到否定的结果。如果是这样,只需取绝对值。

现在用你的符号写出总和(除了我不费心输入重复的三角形[i])我得到:

(-x3 y2 z1 + x2 y3 z1 + x3 y1 z2 - x1 y3 z2 - x2 y1 z3 + x1 y2 z3)/6.;

这与您所写的完全一致(订单除外)!

所以有两种可能:

(1) 也许您的 STL 文件有缺陷,并且三角形的方向不一致。您可以通过验证每个边在正向和相反方向上一次被三角形使用来检查这一点。“边”是指属于同一三角形的一对顶点 (p[r], p[s])。我正在更改符号并使用下标来指示文件中唯一索引的顶点,而不是像上面的双索引符号那样相对于面部的顶点索引)。

如果一个三角形在它的有向边列表中有边 (p[r], p[s]) ,那么其他一些三角形必须在它的列表中有 (p[s], p[r])(相同的顶点,相反的顺序)的定向边缘。

(2) 曲面细分未关闭。这与 1 的测试相同,只是如果只有一个三角形使用边,则无论方向如何,它都是开放的。

(3) 我敢提吗?你确定你初始化了 currentVolume吗?

(4) 你得到了正确的答案,但音量是否定的,你被愚弄认为方法是错误的。请参阅我上面的评论。

于 2011-07-01T22:20:51.357 回答
1

int 与双重问题?

/ 6;也许应该是/6.0;

于 2011-09-29T18:36:26.500 回答