在类似3D十六进制的平铺贴图上进行光线跟踪(LoS)

时间:2010-04-17 14:41:50

标签: algorithm language-agnostic geometry raytracing hexagonal-tiles

问候,

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

(我突出显示了一个任意的瓷砖(绿色)及其相邻的瓷砖(黄色),以帮助描述整个事情应该如何工作;但邻接功能问题,那已经解决了。)

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

这是足够的背景;我的问题是:
给定两个点AB的坐标,如何生成A和{之间的直线的切片列表(或者更确切地说,就是它们的坐标) {1}}会越过?

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

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

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

提前感谢您的回答

2 个答案:

答案 0 :(得分: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个维度。

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

答案 1 :(得分:1)

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

我看到你只是沿着第一个轴将块(交替)移动了一半块大小。如果沿着此轴分割块,上面的示例将变为(带有移位)(9x4x4)简单笛卡尔坐标系统和常规堆叠块。现在,光线跟踪变得更加简单,不易出错。