我正在编写一个模拟,该模拟作用于映射到球体表面的网格上。网格本身是 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)

等等

在某些方面这是一种更复杂的方法,而在其他方面则更简单。所有这些的优点是:
  • 无需存储单个三角形的邻接信息,只需存储二十面体面
  • 如果您为每个边存储A,B,C的3D位置,则给定(边,行,列)引用的三角形可以计算
  • 的3D三角形坐标,因此,无需在每个三角形中都存储
  • 10-06 07:18