我目前正在编写程序,以使用C++和Opengl实现Marching Cube。
但是,我最好的引用仅来自http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/
在网上,提供的代码用C编写。
我的问题是我不了解triTable和edgeTable
以及它们之间的关系。
谁能帮助我解释一下或指导我将算法转换成代码?
最佳答案
这些表用于找出如何对表面进行镶嵌的方法:
第一张表为您提供了必要的插值边。
第二张表为您提供了 segmentation 方法,这意味着
您必须在立方体内制作哪些三角形。
一个小例子:
假设顶点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],笑容就会在您的脸上蔓延:)
注释中残留困惑的陈述之后添加:;-)
行进立方体的作用:
想象一下,您有一间暗室,里面有一个点光源。
它是标量强度值的体积光强度场的中心。
您可以转到(x,y,z)点并在那里测量强度,例如3坎德拉。
现在,您希望通过具有一定光强度的所有点渲染表面。
您可以想象,该等值面看起来像点光源周围的球体。这就是我们希望Marching多维数据集能够为我们提供的东西。
现在遍历房间中的所有点并将每个点标记为具有大致iso值的顶点,这在算法上将非常复杂,并且将导致大量顶点。然后,我们将不得不以某种方式修饰。
因此:First Marching多维数据集将整个体积分解为相等大小的多维数据集。
如果基础数据具有某种基础离散性,则使用其倍数。我不会讨论其他情况,因为那是罕见的。
例如,我们将密度为1mm的网格放入2mx5mx5m的房间
我们使用5mmx5mmx5mm的立方体。通过它们运行应该便宜得多。
您现在可以想象,某些立方体的边缘与等值面相交。
这些是有趣的。此代码标识它们:
cubeindex = 0;
如果(grid.val [0]
如果cubeindex保持为零,则该特定立方体不与等值面相交。
如果cubeindex> 0,您现在知道等值面通过该立方体
并且您要渲染其中的等值面。
请想象一下。
看
http://en.wikipedia.org/wiki/Marching_cubes
有关相交立方体的示例。
您可以轻松获得的顶点是位于立方体边缘的那些顶点。
只需在2个角点之间线性插值即可找到位置
等值并在此处放置一个顶点。但是哪些边缘相交???
这是edgeTable [cubeindex]中的信息。
那是所有if的大段代码,用于存储插值后的结果
点在xyz点数组中作为顶点:vertlist []。
该段内容如下:
获取位域= edgeTable [cubeindex]
如果边缘1在位域中被标记(位1在位域中设置为1)
vertlist [0] =插补点,在边1上
... 等等。
现在您有了一个充满顶点的数组,但是如何将它们连接到三角形呢?
那是tritable提供的信息。
其余的几乎就是我上面解释的。
好吧,如果仍然有问题,请具体说明会给您带来麻烦的那段代码。