这些表格用于找出如何镶嵌表面:
第一个表格给出了插值所需的边缘。
第二个表格告诉你如何进行细分,也就是说,你需要在立方体内制作哪些三角形。
举个例子:
假设顶点1和2都在等值线以下,那么cubeindex应该为3。
整个交汇处应该看起来像楔形。
如果仔细想一下,你需要在边缘上插值:
0和9,以及2和10。
如果你把这些输入到一个位域中,每个位对应“边界是否相交?”,你最终会得到类似于这样的结果:
10 9 8 7 6 5 4 3 2 1 边缘
1 1 0 0 0 0 1 0 1 0 是否相交?
不是吗?
这正是二进制下edgeTable[3]的值;) 0x30A = 1100001010
现在你可以编写一个函数,在这些边缘上进行线性插值,以适应你的等值面。
这些点将成为你在此单元格内的表面。
但如何细分这个单元格/表面呢?
如果你查看triTable [3],你会发现自己露出了微笑的脸:)
在评论中表示困惑后,附加说明:;-)
Marching Cubes是做什么的:
想象一下,你有一个黑暗的房间,里面只有一个点光源。
它是标量强度值的体积光强场的中心。
你可以到达点(x,y,z)并测量那里的强度,例如3坎德拉。
现在,您想要渲染通过所有具有特定光强度的点的表面。
您可以想象这个等值面看起来像点光源周围的球体。这就是我们希望Marching cubes能够提供的。
现在,在房间中运行并标记每个具有大致等值的点作为顶点将是算法上非常复杂的,并且会导致巨大数量的顶点。然后我们必须以某种方式细分它们。
所以:首先,Marching cubes将整个体积划分为相等大小的立方体。
如果基础数据具有某种基础离散性,则使用其倍数。我不会讨论另一种情况,因为那是罕见的。
例如,我们将具有1mm密度的网格放入2mx5mx5m的房间中。
我们使用5mmx5mmx5mm的立方体。运行它们应该更便宜。
你现在可以想象一下,一些立方体的边缘与等值面相交。
这些是有趣的。此代码识别它们:
cubeindex = 0;
if (grid.val[0]
如果cubeindex保持为零,则此特定的立方体未被等值面相交。
如果cubeindex> 0,则现在您知道等值面通过此立方体
并且您想要渲染其中的等值面片段。
请在脑海中想象一下。查看
http://en.wikipedia.org/wiki/Marching_cubes以获取相交立方体的示例。
您可以轻松获得的顶点是立方体边缘上的顶点。只需在两个角点之间进行线性插值,以找到等值面的位置并在那里放置一个顶点。但是哪些边相交?这就是edgeTable[cubeindex]中的信息。那是带有所有if语句的大块代码,将插值点作为xyz点的顶点存储在vertlist[]数组中。此部分如下所示:
获取位域= edgeTable[cubeindex]
如果在位域中标记了边缘1(位域中设置了位1)
vertlist [0] = 插值点,在边缘1的某个地方
...等等。
现在您有一个充满顶点的数组,但是如何将它们连接到三角形?这是tritable提供的信息。
其余部分基本上就是我上面解释的内容。
如果仍然有问题,请具体说明给您带来麻烦的代码部分。