我正在编写一个模拟,该模拟作用于映射到球体表面的网格上。网格本身是 segmentation 的Icosahedron(但是事先不知道 segmentation 的级别)
使用正方形网格,很容易找到相邻的单元格,因为它们沿x或y轴为正或负1。但是这些三角形根本不是这种情况,我的想法是很难想象如何索引单元格。
我是否可以使用任何坐标系来解决二十面体的面,至少可以轻松地使3个单元格与二十面体中的任意单元相邻?
最佳答案
对于二十面体的每一侧,您都可以将三角形映射到一个网格,每个网格正方形都分为两部分,例如(为了方便格式化,索引的十六进制编号):
A
+
|\
|0\
+--+
|\2|\
|1\|3\
+--+--+
|\5|\7|\
|4\|6\|8\
+--+--+--+
|\A|\C|\E|\
|9\|B\|D\|F\
+--+--+--+--+
B C
对于 segmentation 为n次的侧面,该侧面中有4n个三角形,因此您可以为二十面体的每一侧创建一个具有该大小的数组,以存储用于仿真的任何每个三角形的数据。
对三角形的引用可以存储为(边,行,列)
行和列索引从0开始。列索引基于行中三角形的数量(即每个网格正方形2个)。
如果具有侧面,行和列,则可以像这样计算侧面数组中的索引:
index = (row * row) + column
因此,您可以将数据存储在2d数组中,并按以下方式访问它:
value = data[side][(row * row) + column]
具有偶数列的三角形的相邻三角形:
(side, row, column - 1)
(side, row, column + 1)
(side, row + 1, column + 1)
带有奇数列的三角形的相邻三角形:
(side, row, column - 1)
(side, row, column + 1)
(side, row - 1, column - 1)
这使您可以轻松地在 segmentation 的三角形网格中引用三角形,而无需显式存储邻接信息。
关键在于将其组织成二十面体。计算对相邻三角形的引用后,您需要验证新引用是否在边的范围内:
int rows = 1 << subdivision_count;
if(row >= rows)
{
// compute (side, row, column) in adjacent side of icosahedron to B-C edge
}
else if(column < 0)
{
// compute (side, row, column) in adjacent side of icosahedron to A-B edge
}
else if(column >= ((row * 2) + 1))
{
// compute (side, row, column) in adjacent side of icosahedron to A-C edge
}
您必须存储每一侧的邻接信息以及它的哪种类型的边(AB,BC,AC)。
您将必须找出9种不同的可能映射,每种类型的边线类型都对应一种。例如,如果相邻的三角形与AC边相交,并且该边与相邻边的AB边相匹配,则
side = adjacent side (from table)
row = row
column = column - ((row * 2) + 1)
等等
在某些方面这是一种更复杂的方法,而在其他方面则更简单。所有这些的优点是: