如何找到被移动的圆圈扫过的2D网格单元?


9

我正在基于2D网格制作游戏,其中有些单元格可以通过,有些则不能。动态对象可以独立于网格连续移动,但需要与不可逾越的单元碰撞。

我编写了一种算法来追踪射线对着网格,从而为我提供了所有与射线相交的单元。但是,实际对象不是点大小的。我目前将他们表示为圈子。但是我无法找到有效的算法来追踪运动的圆。这是我需要的图片: 在此处输入图片说明

数字显示圆与网格单元碰撞的顺序。有人知道找到这些冲突的算法吗?最好使用C#。

更新可以大于单个网格单元。


mmh为什么3在4之前碰撞?
FxIII 2011年

@FxIII我实际上在图片中移动了圆圈,它在4之前命中3。
没关系,

Answers:


6

我认为您的绘制有点误导,因为您选择从与运动方向相切的圆上的点绘制笔触。我可以看到,当圆的TOP和LEFT点接触边缘时,会发生与网格边缘的碰撞。

C为中心,r为半径,因此P' = C +(r,0)和P“ = C +(0,r)。

如果D是您的方向向量(方向向量),则有两行:

R'= D · t + P'

R“ = D · t + P”

您只需找到这些线与方程式的线的交点即可:

y = i和y = i 就是网格的边缘!

该解决方案很简单,因为您只需要考虑R'和R“的x或y分量即可。您将找到每个插入部分的t s值,以及t ts的点,只需将这些点按t排序即可,完成。

我相信,如果您知道交叉点,就可以轻松说出要击中哪个单元格。

如果r <1(像元宽度和高度),则此方法有效。

它也适用于其他情况,只需考虑P'P“。由于方向而选择TOP和LEFT,应将BOTTOM和RIGHT视为相反的方向,您明白为什么。

现在看这张图片: 大圈

圆大于单个单元格,我们认为它的方向与您的绘图相同。P1是要触摸的第一个点,P2是第二个点,P3无用,因为在下半部分。您需要做的是像我们之前看到的那样投射P1和P2的光线,并对垂直线进行相同的处理。

通常,从顶部开始拍摄时,您将拥有其他起点和左边,而您的圆圈越大,投射的光线就越多。

老实说,您可以避免出于某些几何考虑而拍摄所有光线,但这会使事情变得更难以理解。


是的,我自己想到了P'和P“点,但无法弄清楚当圆大于单个单元格时该怎么做。其他点确实有意义(而且我显然只需要 P'和P” 之间添加光线P“)
没关系,

可以做一些几何上的考虑来简化计算,但是使用实现可以使您凭经验获得相同的结果。
FxIII 2011年

是否清楚您必须分别测试水平和垂直网格线?
FxIII 2011年

我认为您还必须检查圆弧何时覆盖网格顶点,因为圆弧将与对角线相邻的单元格碰撞,但不一定是圆环上最先接触它的顶部/左侧/底部/最右边的点(而且您将发现碰撞还为时过早。)示例:问题示例图中的3、4、5正方形。他们被击中顺序(3,然后4,然后5),但您的算法将同时检测4和5。
finnw 2011年

@finnw只有在冰柱正好沿等分线的方向移动时,它们才会同时接触。
FxIII 2011年

1

如果要使用射线碰撞算法,则可以在每个圆上选择八个点(以45度为增量,与正方形网格对齐),并在相应点之间使用射线碰撞(例如,从一个点的顶部开始)圈到另一个的顶部)。所有这些射线碰撞的并集是相交的整个单元集。

您可能会对此有所改进-例如,使用从一个圆的中心到另一个圆的中心的线段,但在任一侧均以圆的半径延伸,以及在圈子的两端。


8条光线可能会确保所有相交,但是它们不会以正确的顺序给出它们。对于碰撞,我需要命令,而不仅仅是单元列表。
没关系,

增强光线碰撞算法,以为每次碰撞保留一个t值。当得到单元的并集时,可以对t值进行排序以获得正确的顺序。
2011年

但是,如何比较不同光线的t值呢?
没关系,

如果您始终来自同一圆,则您的交点将是与该圆的距离。来到已经看到的单元格时,如果当前碰撞的t值小于前一个碰撞的t值,请使用它...否则,丢弃相交点(保留原始点)。
2011年

1
您可能只需要在垂直于机芯的圆的侧面上绕开两条光线就可以逃脱,然后可以看到哪些瓷砖受到了光线的撞击,还可以检查其余部分以查看其中心是否落在两条光线之间。唯一应该错过的东西是在开始或结束时发生碰撞的事物,但这仅仅是两个圆圈,并且可以轻松处理。我不确定,它可能比八射线慢一些。但您无需根据圆圈的大小缩放数字。
鲁宁

1

我并不是说这是一个完美的类比,但您可能会想到布雷森汉姆的直线算法。对该算法或其扩展之一进行修改可能会有所帮助,特别是如果您将其与其他一些帖子和评论相结合。通常,此算法与排序无关,但是我认为您可以相当轻松地添加它。


我也在考虑这个问题,但是我认为这不是正确的算法。布雷森纳姆只选择一个像素,他需要全部。很难使布雷森汉姆适应仅安装一个像素的圆形。
zacharmarz 2011年

我使用的光线跟踪器实际上是基于Bresenham算法的一种。我很难将其从细线概括为“胖”线,尤其是绕圈扫线。
没关系
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.