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)
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)