如何计算由三角形组成的三维网格物体的体积

我想计算一个三维网格物体的体积有一个表面组成的三角形。

73000 次浏览

三角曲面库 可以为你做这些.记住,表面必须是封闭的。对于相当多的3D 模型来说,情况并非如此。

如果您想自己实现它,您可以从查看他们的代码开始。

阅读这篇文章 ,它实际上是一个相当简单的计算。

诀窍是计算一个四面体的 签名本-基于你的三角形和顶部的原点。体积的符号来自于你的三角形是否指向原点的方向。(三角形的法线本身取决于顶点的顺序,这就是为什么下面没有明确引用它的原因。)

这一切都归结为以下简单的函数:

public float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3) {
var v321 = p3.X*p2.Y*p1.Z;
var v231 = p2.X*p3.Y*p1.Z;
var v312 = p3.X*p1.Y*p2.Z;
var v132 = p1.X*p3.Y*p2.Z;
var v213 = p2.X*p1.Y*p3.Z;
var v123 = p1.X*p2.Y*p3.Z;
return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

然后是计算网格体积的驱动程序:

public float VolumeOfMesh(Mesh mesh) {
var vols = from t in mesh.Triangles
select SignedVolumeOfTriangle(t.P1, t.P2, t.P3);
return Math.Abs(vols.Sum());
}

弗兰克 · 克鲁格斯的回答很有效,+ 1。如果你有向量函数可用,你也可以使用这个:

    public static float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3)
{
return p1.Dot(p2.Cross(p3)) / 6.0f;
}

编辑。.附加的影响。如果您不确定,请输入 Dot ()和 Cross ()。大多数数学读物都会有这些。如果您正在使用 WPF,它们将作为 Vector3D 类的静态方法实现。

    public class Vector
{
...


public float Dot(Vector a)
{
return this.X * a.X + this.Y * a.Y + this.Z * a.Z;
}


public Vector Cross(Vector a)
{
return new Vector(
this.Y * a.Z - this.Z * a.Y,
this.Z * a.X - this.X * a.Z,
this.X * a.Y - this.Y * a.X
);
}
...
}

上述方法适用于“简单”物体(没有交叉/重叠的三角形) ,如球面四面体等。对于更复杂的形状,一个好主意是分割网格(关闭它) ,并分别计算每个部分的体积。 希望这个能帮上忙。