むしろ、視線光線ではなく影光線を投じたいと思います。
これがあなたのビューエリア(潜在的に見えるエリア)だとしましょう
######################
#####.............####
###................###
##..................##
#....................#
#....................#
#..........@.........#
#....................#
#....................#
##..................##
###................###
#####.............####
######################
#ブロックは表示されませんが、。見える
障害物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が最初にチェックされる場合、チェックを少し高速化できます。
ある種の「海戦」アルゴリズムを使用して、Xのブロックを一度に確認できます(基本的に、シャドウコーンをより広くすることができる方向にある放射状のXを探します)
[編集]
シャドウを正しく投影するには2つの光線が必要です。タイルは長方形であるため、利用可能な対称性を使用して多くの仮定を行うことができます。
光線座標は、障害タイルの周りの単純な空間分割を使用して計算できます。
各長方形の領域は、タイルのコーナーをシャドウコーンエッジとするかどうかの選択を構成します。
この推論をさらにプッシュして、隣接する複数のタイルを接続し、次のように幅の広い単一のコーンをキャストすることができます。
最初のステップは、観察者の方向に障害物がないことを確認することです。その場合、最も近い障害物が代わりに考慮されます。
黄色いタイルが障害物である場合、そのタイルは新しい赤いタイルになります。
次に、コーンの上端を検討します。
青いタイルはすべて、シャドウコーンを広げる可能性のある候補です。少なくとも1つが障害物である場合、前に見たように、そのタイルの周囲の空間分割を使用してレイを移動できます。
緑のタイルは、オブザーバーがオレンジ色の線の上にある場合にのみ候補になります。
同じことは、他の光線と、赤い障害物に関する観察者の他の位置を表します。
基本的な考え方は、各コーンキャスティングで可能な限り多くの領域をカバーし、チェックする障害物のリストをできるだけ速く短縮することです。