我目前正在编写程序,以使用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提供的信息。

其余的几乎就是我上面解释的。

好吧,如果仍然有问题,请具体说明会给您带来麻烦的那段代码。

07-27 13:21