Math 如何计算曲面由三角形组成的三维网格对象的体积

Math 如何计算曲面由三角形组成的三维网格对象的体积,math,geometry,volume,Math,Geometry,Volume,我想计算具有由三角形组成的曲面的三维网格对象的体积。。请记住,曲面必须闭合。对于相当多的3D模型来说,情况并非如此 如果你想自己实现它,你可以先看看他们的代码。,这实际上是一个非常简单的计算 诀窍是计算一个四面体的有符号体积——基于你的三角形,并在原点结束。体积的符号来自三角形是否指向原点的方向。(三角形的法线本身取决于顶点的顺序,这就是为什么您看不到它在下面被明确引用的原因。) 这一切归结为以下简单函数: public float SignedVolumeOfTriangle(Vector p

我想计算具有由三角形组成的曲面的三维网格对象的体积。

。请记住,曲面必须闭合。对于相当多的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());
}

Yip Frank Kruegers的答案在+1的情况下效果很好。如果您有可用的向量函数,也可以使用:

    public static float SignedVolumeOfTriangle(Vector p1, Vector p2, Vector p3)
    {
        return p1.Dot(p2.Cross(p3)) / 6.0f;
    }
编辑。。添加了impl。对于点()和叉(),如果您不确定。大多数数学库都会有这些。如果您使用的是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
            );
        }
        ...
    }

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

我没有时间给你提供更多信息,可能是其他人,但请看一看:问题1410525显得多余。如果你重新实现这个,请小心-GTS库是LGPL,所以任何衍生作品都必须是LGPL或GPL。可能是Dot()和Cross()的post代码?(这两种方法都很容易实现,但为了完整性)。顺便说一句,@Frank Kruegers的答案是,如果你简化p1.Dot(p2.Cross(p3))/6.0fq,你会得到一个优雅的解决方案。我想知道为什么在2001年之前没有发现这个问题。1984年10月,发表了一篇论文“计算任意非凸多面体积分性质的符号方法”,并描述了这种计算体积的方法。这或多或少也是一个很简单的方法,所以你需要的不仅仅是这些信息来发表一篇论文。“在原点加满”不是强制性的,你可以选择任何固定点。如果物体离原点很远,就会导致数值不稳定。最好从网格中选择任意点,然后根据相同的几何图形计算体积。首先,我从实体网格中获取体积。然后根据该算法提取曲面并计算体积。结果是不同的。前者为16.46584046,后者为16.46596493如果卷已签名,则不需要将中心置于内部错误答案。所描述的方法适用于任意复杂的闭合对象,没有相交/重叠三角形,并且对中心点的位置没有要求。这是因为四面体“体积”是有符号的,并且是代数相加的。@galinette是的,你是对的。所谓“简单”对象,我指的是没有相交/重叠三角形的对象。此外,网格的中心可以位于外部。使用三维布尔运算进行剪切