这些表用于了解如何对表面进行细分:
第一个表为您提供了插值所需的边。
第二个表为您提供了镶嵌的方式,这意味着,
你必须在立方体内部制作哪些三角形。
一个小例子:
假设,顶点 1 和 2 低于 iso 级别,
立方体索引应为 3。
整个路口应该是这样的
一个楔子。
如果您考虑一下,您必须在边缘上插入值:
0 和 9 以及 2 和 10。
如果将其输入位字段,则每个位对应于“边是否相交?”你最终会得到这样的结果:
10 9 8 7 6 5 4 3 2 1 edge
1 1 0 0 0 0 1 0 1 0 intersected?
你不会吗?
这正是 EdgeTable[3] 的二进制值;) 0x30A = 1100001010
现在您可以编写一个函数来线性插值这些边缘上的点
以适合您的等水平。这些点将成为该细胞内的表面。
但如何对这个细胞/表面进行镶嵌呢?
如果您查看 triTable[3],您的脸上应该会露出微笑:)
在评论中残留困惑的陈述后添加:;-)
Marching Cubes 的作用:
想象一下你有一个黑暗的房间,里面有一个点光源。
它是标量强度值的体积光强度场的中心。
您可以转到点 (x,y,z) 并测量那里的强度,例如3坎德拉。
您现在想要通过具有特定光强度的所有点渲染表面。
您可以想象这个等值面看起来像点光源周围的球体。这就是我们希望 Marching 立方体能够为我们提供的。
现在,遍历房间中的所有点并将每个点标记为具有大致 iso 值的顶点,在算法上将非常复杂,并且会导致大量顶点。然后我们必须以某种方式对其进行细分。
因此:首先行进的立方体将整个体积分割成大小相等的立方体。
如果基础数据具有某种基础离散性,则使用其倍数。我不会讨论另一种情况,因为这种情况很少见。
例如我们将密度为1mm的网格放入2mx5mx5m的房间中
我们使用 5mmx5mmx5mm 的立方体。通过它们运行应该便宜得多。
现在您可以想象,一些立方体的边缘与等值面相交。
这些是有趣的。此代码识别它们:
cubeindex = 0;
if (grid.val[0]
如果立方体索引保持为零,则该特定立方体不与等值面相交。
如果cubeindex > 0,你现在知道等值面穿过这个立方体
并且您想要渲染其中的等值面部分。
请在脑海中想象一下这一点。
看http://en.wikipedia.org/wiki/Marching_cubes http://en.wikipedia.org/wiki/Marching_cubes相交立方体的示例。
您可以轻松获得的顶点是立方体边缘上的顶点。
只需在 2 个角点之间线性插值即可找到位置
的等值并在那里放置一个顶点。但哪些边相交???
这就是edgeTable[cubeindex]中的信息。
这是包含所有 if 的一大段代码,用于存储插值
点作为 xyz 点数组中的顶点:vertlist[]。
这篇文章内容如下:
get the bitfield = edgeTable[cubeindex]
if edge 1 is marked in bitfield (bit 1 set to 1 in bitfield)
vertlist[0] = interpolated point, somewhere on edge 1
... and so on.
现在你有了一个充满顶点的数组,但是如何将它们连接到三角形呢?
这是 tritable 提供的信息。
剩下的就和我上面解释的差不多了。
如果仍然存在问题,请具体说明给您带来麻烦的代码段。