行进立方体问题

发布于 2024-07-17 10:36:49 字数 339 浏览 3 评论 0原文

我目前正在编写一个程序来使用 C++ 和 Opengl 实现 Marching Cube。

但是,我最好的参考仅来自 http://local.wasp.uwa .edu.au/~pbourke/geometry/polygonise/

网络中的 ,提供的代码是用C编写的。
我的问题是我不理解 triTable 和 edgeTable
以及它们之间的关系。

谁能帮助我解释或指导我将算法转换为代码?

i currently writing a program to implement Marching Cube using C++ and Opengl.

However, my best reference is only from http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/

in the web, the provided codes are written in C.
my problem here is that i don't understand the triTable and edgeTable
and how they are related.

can anyone help me on the explanation or guide me on converting the algorithm into codes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请别遗忘我 2024-07-24 10:36:49

这些表用于了解如何对表面进行细分:

第一个表为您提供了插值所需的边。
第二个表为您提供了镶嵌的方式,这意味着,
你必须在立方体内部制作哪些三角形。

举个小例子:

假设,顶点 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
相交立方体的示例。

您可以轻松获得的顶点是立方体边缘上的顶点。
只需在 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 提供的信息。

剩下的就和我上面解释的差不多了。

如果仍然存在问题,请具体说明给您带来麻烦的代码段。

These Tables are used for finding out how to tesselate the surface:

The first table gives you the necessary edges to interpolate.
The second table gives you the way you have to tesselate, meaning,
which triangles you have to make inside the cube.

A little example:

let's assume, vertex one and 2 are below the iso level,
the cubeindex should be 3.

The whole intersection should look like
a wedge.

If you think about it, you have to interpolate values on the edges:
0 and 9 , and 2 and 10.
If you enter this into a bitfield, each bit corresponding to "is edge intersected?" you would end up with something like this:

10 9 8 7 6 5 4 3 2 1  edge
 1 1 0 0 0 0 1 0 1 0  intersected?

wouldn't you?

Which is exactly the value from edgeTable[3] in binary ;) 0x30A = 1100001010

Now you can write a function that linearly interpolates the points on those edges
to fit your isolevel. These points will become your surface inside this cell.

But how to tesselate this cell/surface?

if you look into triTable[3] a smile should creep over your face :)

Addit after statement of residual puzzlement in comment: ;-)

What Marching Cubes does:
Imagine you have a dark room with one point light source in it.
It is the center of a volumetric light intensity field of scalar intensity values.
You can go to point (x,y,z) and measure the intensity there, e.g. 3 candela.

You now want to render a surface through all points that have a certain light intensity.
You can Imagine that this Isosurface would look like a sphere around the point light source. That is what we hope that Marching cubes will provide us with.

Now running through all points in the room and marking every point as a vertex that has roughly the iso value, will be algorithmically very complex and would result in a hughe number of vertices. Which we would then have to tesselate somehow.

So: First Marching cubes disects the whole volume into cubes of equal size.
If the underlying data has some kind of underlying discreteness, multiples of that are used. I will not go into the other case, since that is rare.
For instance we put a grid with the density of 1mm into a 2mx5mx5m room

We use cubes of 5mmx5mmx5mm. Running through them should be much cheaper.

You can imagine now, that the edges of some of the cubes intersect the isosurface.
These are the interesting ones. This code identifies them:

cubeindex = 0;
   if (grid.val[0] 

if cubeindex stays zero, this particular cube is not intersected by the isosurface.
If cubeindex is > 0 you now know that the isosurface goes through this cube
and you want to render the piece of the isosurface that is inside it.

Please picture this in your mind.
See
http://en.wikipedia.org/wiki/Marching_cubes
for examples of intersected cubes.

The vertices that you could get easily are those on the edges of the cube.
Just interpolate linearly between 2 corner points to find the position
of the isovalue and put a vertex there. But which edges are intersected???
That is the information in edgeTable[cubeindex].
That is the big piece of code with all the ifs, that stores the interpolated
points as vertices in an array of xyz points: vertlist[].
This piece reads as follows:

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.

You now have an array full of vertices, but how to connect them to triangles?
That's an info that tritable provides.

The rest is pretty much what I explained above.

Well should there still be problems, please be specific about the piece of code that gives you trouble.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文