光线追踪(LoS)3D十六进制
问候,
我正在开发一个游戏项目,使用六角形瓷砖地图的3D变体。 瓷砖实际上是立方体,不是六角形,而是像六角形一样布置(因为一个正方形可以转变成一个立方体,从2D推断到3D,但是没有六角形的3D版本)。 而不是一个详细的描述,这里是一个4x4x4地图的例子:
(我已经强调了一个任意的瓦片(绿色)及其相邻的瓦片(黄色)来帮助描述整个事物应该如何工作;但是邻接函数不是问题,已经解决了。)
我有一个struct类型来表示贴图,而贴图被表示为一个三维数组(包裹在一个Map
类中以添加一些实用方法,但这不是很相关)。 每块瓷砖应该表示完美的立方体空间,并且它们的尺寸完全相同。 此外,相邻“行”之间的偏移量恰好是一个图块大小的一半。
这是足够的背景; 我的问题是:
考虑到A
点和B
点的坐标,我如何生成A
和B
之间的直线会交叉的切片列表(或者更确切地说,它们的坐标)?
这将在以后用于各种目的,如确定视线,充电路径合法性等。
顺便说一句,这可能是有用的:我的地图使用(0,0,0)作为参考位置。 地图的“锯齿”可以被定义为将每个瓦片((y+z) mod 2) * tileSize/2.0
偏离它在“理智”笛卡尔系统上的位置的右侧。 对于非参差不齐的行,产生0; 对于其中(y+z) mod 2
为1的行,它产生0.5个瓦片。
我正在开发针对.Net Framework 4.0的C#4; 但我并不需要特定的代码,只需要算法来解决奇怪的几何/数学问题。 我一直在努力解决这个问题,但没有任何结果。 并试图在纸上绘制整个“可视化”它也没有帮助:。
预先感谢任何答案
直到其中一个聪明的SOE出现,这是我愚蠢的解决方案。 我将在2D中解释它,因为它更容易解释,但它会很容易地推广到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
它的参数是一个偶数,它even
返回True。 我将使用下一个odd
点:任何点point(x,odd(floor(y))
映射到cell(floor(x-0.5),floor(y))
。
现在您已经掌握了确定视线的基本知识。
你还需要一个函数将cell(m,n)
映射回笛卡尔空间中的一个点。 一旦你确定了原点在哪里,这应该是直截了当的。
现在,除非我放错了一些括号,否则我认为你已经在路上了。 你需要:
cell(0,0)
位置point(0,0)
; 并相应调整功能; 根据游戏场的大小,你可以在查找表(或其他数据结构)中存储单元边界的笛卡尔坐标,这可能会加快速度。
也许你可以避免所有复杂的数学,如果你以另一种方式看待你的问题:
我发现你只能沿着第一个轴移动块(交替)一半的块大小。 如果你沿着这个轴分割你的块,上面的例子将变成(9x4x4)简单的笛卡尔坐标系统,并带有规则的堆积块。 现在做光线追踪变得简单得多,而且容易出错。
链接地址: http://www.djcxy.com/p/45379.html