如何计算表面由三角形组成的3D网格对象的体积

49 math geometry volume

我想计算具有由三角形构成的表面的3D网格对象的体积.

Fra*_*ger 85

阅读本文,它实际上是一个非常简单的计算.

诀窍是计算四面体的有符号体积 - 基于您的三角形并在原点处加满.音量的符号来自您的三角形是否指向原点方向.(三角形的法线本身取决于顶点的顺序,这就是为什么你没有看到它在下面明确引用的原因.)

这一切归结为以下简单功能:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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());
}
Run Code Online (Sandbox Code Playgroud)

  • "在原点处加满"不是强制性的,您可以选择任何固定点.如果物体离原点很远,这将导致数值不稳定.最好从网格中选择一个任意点 (3认同)
  • 1984年10月,发表了论文"计算任意非凸多面体积分性质的符号方法",并描述了这种计算体积的方法.它也或多或少是一种微不足道的方法,因此您需要的不仅仅是这些信息来发表论文. (2认同)
  • @KaranAhuja 在二维中,这是格林定理的简单计算机应用(参见例如面积计):您可以通过曲线上的线积分来计算曲线所包围的面积。在 3D 中,它是散度定理(高斯定理)的应用:您可以通过边界上的通量积分来计算边界表面所包围的体积(对于散度为 1 的矢量场)。边界不需要是凸的,但它们需要是封闭的。 (2认同)

Ros*_*ver 22

Yip Frank Kruegers的回答很有效.如果你有可用的向量函数,你也可以使用它:

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

编辑..添加了impl.如果您不确定,请使用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
            );
        }
        ...
    }
Run Code Online (Sandbox Code Playgroud)


Jay*_*nek 4

GNU三角曲面库 可以为您做到这一点。请记住,曲面必须是封闭的。对于相当多的 3D 模型来说,情况并非如此。

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

  • 如果您确实重新实现此功能,请小心 - GTS 库是 LGPL,因此任何衍生作品都必须是 LGPL 或 GPL。 (8认同)