根据 this answer , 我读了this research paper (very brief) .引用答案:
This all boils down to the following simple function:
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); }
and then a driver to calculate the volume of the mesh:
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()); }
这似乎比用于确定高级 3D 对象体积的基于体素的方法要好得多,但是,在我目前可用的模型中:
- 许多表面并不是完整的 3D 庞大形状,而是包裹在 3D 外观形状中的中空 2D 网格,其中两端实际上并没有汇合形成真正 3D 对象的完整表面。
- 有些表面是完全平坦的二维形状。
- 内部一团糟。
而且我不确定该算法将如何处理不完美的 3D 模型。
我是否需要生成仅由真实、完整、庞大的 3D 对象组成的模型才能使此方法起作用,或者它是否适用于如上所示的常见 3D 模型?
最佳答案
您发现的方法通过遍历所有三角形来工作,对于每个三角形,它将其角与 (0,0,0)
点连接起来,形成一个四面体。然后它计算它的体积并总结所有结果。此处使用的 signed
词意味着某些四面体将具有负体积,基于三角形面。由于这个技巧,重叠的四面体将相互抵消。
如果你有正确的
网格,它就可以工作,但是你的不完美
网格基本上是一个完美
的网格,但缺少几个三角形,所以你在你的最终总和中会错过一些四面体。从统计上讲,其中一些是正量,一些是负量,因此这也会在一定程度上相互抵消。
你缺少的三角形越多和/或它们变得越大,那么你在计算的体积值中得到的误差就越大,但算法不会破坏或爆炸,只是会降低精度。
这种方法还有另一个问题:
当您有两个相互重叠的完全闭合的立方体网格时,此算法将计算它们体积的总和,而不是它们创建的形状的体积。我们对您的模型了解不多,但我认为它比非封闭网格问题更大。
要解决此问题,您需要执行 CSG Union
操作,但它仅适用于闭合网格:/。
关于algorithm - 这种网格体积计算算法可以处理不完美的网格吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48112329/