7

问候,

我正在开发一个使用 3D 六边形瓷砖地图变体的游戏项目。瓷砖实际上是立方体,而不是六边形,但布局就像六边形一样(因为可以将正方形变成立方体以从 2D 外推到 3D,但没有 3D 版本的十六进制)。这里没有详细的描述,而是一个 4x4x4 地图的示例:

(我已经突出显示了一个任意图块(绿色)及其相邻的图块(黄色),以帮助描述整个事情应该如何工作;但邻接函数不是问题,这已经解决了。)

我有一个结构类型来表示瓦片,地图表示为瓦片的 3D 数组(包装在一个Map类中以添加一些实用方法,但这不是很相关)。每个图块都应该代表一个完美的立方空间,并且它们的大小完全相同。此外,相邻“行”之间的偏移量正好是图块大小的一半。

这已经足够了。我的问题是:
给定两个点的坐标A和,我如何生成一个瓷砖列表(或者,更确切地说,它们的坐标),它们之间的B直线会交叉?AB

这稍后将用于各种目的,例如确定视线、充电路径合法性等。

顺便说一句,这可能很有用:我的地图使用 (0,0,0) 作为参考位置。地图的“锯齿状”可以定义为将每个图块((y+z) mod 2) * tileSize/2.0从其在“正常”笛卡尔系统上的位置向右偏移。对于非锯齿行,产生 0;对于(y+z) mod 2为 1 的行,它会产生 0.5 个图块。

我正在开发针对 .Net Framework 4.0 的 C#4;但我真的不需要特定的代码,只需要解决奇怪的几何/数学问题的算法。我已经尝试了几天来解决这个问题,但无济于事;并试图在纸上画出整个东西以“可视化”它也无济于事:(。

提前感谢您的任何回答

4

2 回答 2

3

在一个聪明的 SOers 出现之前,这是我的愚蠢解决方案。我将用 2D'cos 解释它,这样更容易解释,但它很容易推广到 3D。我认为任何尝试完全在单元格索引空间中工作的尝试都注定要失败(尽管我承认这正是我的想法,我期待被证明是错误的)。

所以你需要定义一个函数来从笛卡尔坐标映射到单元格索引。这很简单,虽然有点棘手。首先,确定point(0,0)是左下角cell(0,0)还是中心,还是其他点。由于它使解释更容易,我将使用左下角。观察任何point(x,floor(y)==0)映射到cell(floor(x),0). 事实上,任何point(x,even(floor(y)))映射到cell(floor(x),floor(y)).

在这里,我发明了一个布尔函数even,如果它的参数是偶数则返回 True。我将使用odd下一个:任何点point(x,odd(floor(y))映射到cell(floor(x-0.5),floor(y)).

现在您已经掌握了确定视线的基本方法。

您还需要一个函数来从cell(m,n)回映射到笛卡尔空间中的一个点。一旦你决定了原点在哪里,这应该很简单。

现在,除非我放错了一些括号,否则我认为您正在路上。您需要:

  • 决定cell(0,0)你的位置point(0,0);并相应调整功能;
  • 决定沿单元格边界的点落在哪里;和
  • 将其概括为 3 个维度。

根据比赛场地的大小,您可以将单元格边界的笛卡尔坐标存储在查找表(或其他数据结构)中,这可能会加快速度。

于 2010-04-17T15:41:40.053 回答
1

如果您以另一种方式看待您的问题,也许您可​​以避免所有复杂的数学:

我看到您仅将块(交替)沿第一个轴移动块大小的一半。如果你沿着这个轴分割你的块,上面的例子将变成(有移位)一个(9x4x4)简单的笛卡尔坐标系,带有规则的堆叠块。现在进行光线追踪变得更加简单且不易出错。

于 2010-04-18T19:19:54.187 回答