我宁愿投下阴影射线而不是视线射线。
假设这是您的查看区域(潜在的可见区域)
######################
#####.............####
###................###
##..................##
#....................#
#....................#
#..........@.........#
#....................#
#....................#
##..................##
###................###
#####.............####
######################
#块不可见,而#块不可见。可见
让我们设置一些障碍X:
######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXXX...........#
##..................##
###....X...........###
#####.............####
######################
您在视图区域中有一个X列表,然后将每个障碍物后面的每个图块都标记为隐藏:将障碍物标记为隐藏时,将其从列表中删除。
######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXX*...........#
##......##..........##
###....*#..........###
#####.###.........####
######################
在上面的示例中,您可以看到底墙最右边投射的阴影以及该阴影如何从您必须检查的障碍物列表中删除隐藏的障碍物(X必须检查; *已检查)。
如果您使用一些二进制分区对列表进行排序,那么首先检查Cosest X,则可能会稍微加快检查速度。
您可以使用一种“ Naval Battles”算法来一次检查X块(基本上是在寻找可以使卷影锥变宽的方向的正切X)。
[编辑]
需要两条光线才能正确投射阴影,并且由于图块是矩形的,因此可以使用可用的对称性进行很多假设。
可以使用障碍砖周围的简单空间分区来计算射线坐标:
每个矩形区域构成了一个选择,即应选择将瓷砖的哪个角作为阴影锥边缘。
可以进一步推动这种推理,以连接多个相邻的图块,并让它们按如下方式投射单个更宽的圆锥体。
第一步是确保没有障碍物朝向观察者方向,在这种情况下,应考虑使用最近的障碍物:
如果黄色图块是障碍,则该图块将变为新的红色图块。
现在让我们考虑圆锥的上边缘:
蓝色瓷砖都是使阴影锥变宽的所有可能的候选方法:如果其中至少一个是障碍物,可以使用围绕瓷砖的空间分配来移动射线,如前所示。
仅当观察者在随后的橙色线上方时,绿色方块才是候选者:
相同的代表另一条射线以及观察者围绕红色障碍物的其他位置。
基本思想是为每个圆锥形铸件覆盖尽可能多的区域,并尽可能快地缩短要检查的障碍物清单。