Saya lebih suka melemparkan bayangan bayangan daripada garis pandang.
Katakanlah ini area tampilan Anda (area yang berpotensi terlihat)
######################
#####.............####
###................###
##..................##
#....................#
#....................#
#..........@.........#
#....................#
#....................#
##..................##
###................###
#####.............####
######################
Blok # tidak terlihat saat. terlihat
Mari kita letakkan beberapa kendala X:
######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXXX...........#
##..................##
###....X...........###
#####.............####
######################
Anda memiliki daftar X yang ada di dalam area tampilan lalu Anda menandai sebagai disembunyikan setiap ubin yang ada di belakang setiap rintangan ini: ketika suatu rintangan ditandai sebagai tersembunyi, Anda menghapusnya dari daftar.
######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXX*...........#
##......##..........##
###....*#..........###
#####.###.........####
######################
Pada contoh di atas, Anda dapat melihat bayangan yang dilemparkan oleh paling kanan dari dinding bawah dan bagaimana bayangan ini menghapus hambatan tersembunyi dari daftar hambatan yang harus Anda periksa (X harus memeriksa; * dicentang).
Jika Anda mengurutkan daftar menggunakan beberapa partisi biner sehingga cosest X diperiksa terlebih dahulu, Anda mungkin sedikit mempercepat pemeriksaan Anda.
Anda dapat menggunakan semacam algoritma "Naval Battles" untuk memeriksa blok Xs sekaligus (pada dasarnya mencari X yang ada di arah yang dapat membuat bayangan kerucut lebih luas)
[EDIT]
Diperlukan dua sinar untuk membuat bayangan dengan benar dan, karena ubin berbentuk persegi panjang, banyak asumsi dapat dilakukan dengan menggunakan simetri yang tersedia.
Koordinat ray dapat dihitung menggunakan partisi ruang sederhana di sekitar ubin rintangan:
Setiap area persegi panjang merupakan pilihan tentang sudut ubin apa yang harus diambil sebagai tepi kerucut bayangan.
Alasan ini dapat didorong lebih jauh untuk menghubungkan beberapa ubin yang berdekatan dan membiarkannya membentuk kerucut yang lebih luas sebagai berikut.
Langkah pertama adalah memastikan bahwa tidak ada rintangan yang mengarah ke arah pengamat, dalam hal ini yang dianggap sebagai hambatan terdekat adalah:
Jika ubin kuning merupakan kendala, ubin itu menjadi ubin merah baru.
Sekarang mari kita perhatikan tepi kerucut atas:
Ubin biru adalah semua kandidat yang memungkinkan untuk membuat bayangan kerucut lebih luas: jika setidaknya salah satu dari mereka adalah penghalang, sinar dapat dipindahkan menggunakan ruang yang berpisah di sekitar ubin seperti yang terlihat sebelumnya.
Ubin hijau adalah kandidat hanya jika pengamat berada di atas garis oranye yang mengikuti:
Yang sama adalah singkatan dari ray lain dan untuk posisi lain dari pengamat tentang hambatan merah.
Gagasan yang mendasarinya adalah untuk mencakup area sebanyak mungkin untuk setiap casting kerucut dan untuk mempersingkat secepat mungkin daftar hambatan untuk diperiksa.