如何生成 marching cubes 三角形表?我知道可以使用预先计算好的表,但我想知道这些表是如何生成的。
似乎最初的作者是通过手工绘制来进行三角剖分的,但是否有一种方法可以在代码中生成呢?
边缘表很简单,但我看不出是否有一种简单的方法来获取三角形表,即使忽略模糊的情况。
如何生成 marching cubes 三角形表?我知道可以使用预先计算好的表,但我想知道这些表是如何生成的。
似乎最初的作者是通过手工绘制来进行三角剖分的,但是否有一种方法可以在代码中生成呢?
边缘表很简单,但我看不出是否有一种简单的方法来获取三角形表,即使忽略模糊的情况。
这里有一种方法:
从顶点和边点开始。现在,如果一个顶点被选中,则将三个相邻的边点放置在该顶点旁边。对于每个顶点都要这样做。
现在,注意连接选中顶点的边缘。删除位于它们上面的边点。
利用这些边点制作一个三角形数组。
通过使用循环256次来制作三角形表,实际上,使用此方法,您甚至可能不需要循环。
为了测试它:
你可以在谷歌上搜索“Marching Cubes Combination”,
试试我告诉你的方法。它是有效的。 只有一件事,当我测试时,由于绘制方式,我有些困惑。无论如何,享受吧! :)
编辑:使用这种方法,您可以使用任何三角形渲染方式。 人们使用不同的三角形表格。 使用这种方法,您不必弄清楚边缘点的编号是什么。您可以按照自己的方式使用它,以便您不必浪费时间弄清楚。
另一种解决方案 (在我告诉你之前不要看这个) (否则你会看到我的未完成的混乱,因为我没有时间完成它)
我不会真正引用代码。
Marching Cube Triangle List从一个立方体开始。
如果您有一个立方体,或者可以制作一个立方体,我建议您使用一个立方体,仅出于方便。使用笔或标记器整齐地编号其角落和边缘。 请不要不规则地计数。使计数“可编程”。
一个立方体有8个角。让我们将每个角想象成一个灯泡。 因此,三角形列表为打开和关闭的每个灯泡组合生成三角形。 也就是说,256种组合。((2个灯泡条件)^(8个灯泡)= 256种组合) 但是如何生成三角形列表?
对于每个组合,我们都有一个独特的立方体。 让我们从这样的组合开始
/7.on-----8.off
/ | /|
3.off----4.on/ |
| 5.on ------| 6.off
| / | /
|/ |/
1.on------2.off
我们可以制作一个角落或灯泡的列表。
灯泡1,灯泡2,灯泡3-灯泡8
然后告诉它们是开着还是关着
开,关,关...关
你编号的方式取决于你想要什么。虽然我建议有组织地进行。有40,320种点序的组合。
对于这个例子,我使用我习惯的顺序。
我们可以将这个灯泡状态列表转换为二进制数。关闭表示0,打开表示1。
10011010在二进制中=表格的第154个索引
可能你都知道这些:P
2. 创建一个12元素的边缘点数组。 对于新手(没有冒犯),边缘点->位于边缘上的点。
int[] edgePoints = new int[12] {0,0,0,0,0,0,0,0,0,0,0,0} //12 elements
然后我们启用边缘点。对于每个角点,启用其相邻的边缘点。 如果完成此迭代,请检查某个点是否已启用多次。如果是,则禁用它。如果没有启用,则禁用它。
现在您有了有效的边缘点。将其存储在数组或列表中。现在让我们制作三角形。
这里有一些我们可以使用的数组。
List<int> validVertexIndices = new List<int>(); //add the valids
List<int> usedVertices = new List<int>();
List<int> oldVertices = new List<int>();
List<int[]> usedTris = new List<int[]>();
让我们先画一个三角形。 程序并不知道如何连接这些点(以形成三角形)。所以,我们从一个随机点开始。(最好从最低的索引开始)
usedVertices.Add(your random point index);
然后检查距离起点最近的点。 为此,遍历除了起始点以外的所有点。检查起点和每个其他点之间的距离。(假设每个点的x、y、z位置是0.5的完美倍数)(例如0、0.5、1.0)
如果起点和另一个点之间的距离是所有其他距离中最短的,则这两个点是第一个三角形的前两个点。
usedVertices.Add(That second point to be used);
然后获取离第二个点最近的不是第一个点也不是第二个点的点。那就是第三个点。
usedVertices.Add(The third point);
然后您可以注册三角形。
usedTris.Add(usedVertices.ToArray());
oldVertices.Add(usedVertices);
usedVertices = new List<int>();
哈哈,另外,请不要制作和训练神经网络来制造这样的事情,那只是折磨。
0,1,2,1,3,2,2,3,4,3,5,4,4,5,6,5,7,6
其中每个数字表示点或边号。 然后你就有了它。 但什么是有效点?如果一个点只被计算一次,则它是有效点。 如果至少两个,则无效。 - Kino Bacaltos