Metode yang cepat dan kotor adalah menggambar bayangan atap bangunan saja, menjadikannya abu-abu gelap (lebih disukai semi-transparan jika ada lapisan tanah di bawahnya), dan menggambar poligon bangunan di atasnya. Bayangan atap diperoleh dengan menerjemahkan poligon bangunan dengan jarak yang ditentukan oleh ketinggian bangunan ke arah yang ditentukan oleh azimuth dan ketinggian sumber cahaya (dianggap jauh jauh). (Formula untuk jumlah terjemahan muncul di bawah ini.)
Ini cenderung berfungsi baik kecuali untuk ketinggian rendah atau gedung tinggi (seperti gedung pencakar langit): lihat bagaimana bayangan bangunan terisolasi yang lebih tinggi di sisi kanan dipisahkan dari bangunan itu sendiri.
Untuk menghubungkan bayangan dengan benar ke bangunan, Anda harus menyertakan bayangan dinding bangunan . Ini tidak sulit dilakukan. Bayangan dinding yang memanjang antara titik yang terletak di P dan titik lain yang terletak di Q akan menjadi segiempat yang diuraikan oleh {P, Q, Q ', P'} di mana Q 'adalah bayangan Q dan P' adalah bayangan dari P. Bangunan poligonal akan berupa kumpulan poligon terhubung yang diwakili oleh urutan titik tertutup (P (1), P (2), ..., P (n)). Untuk setiap poligon tersebut, bentuk gabungan bayangan tepi (P (1), P (2)), (P (2), P (3)), ..., (P (n), P ( 1)). Ini mudah dilakukan dengan cara loop di tepi.
Untuk lampu pada azimut suatu derajat (timur dari utara) dan ketinggian s derajat (dari cakrawala), bayangan titik P dengan koordinat proyeksi (x, y) dan tinggi h (semua dinyatakan dalam satuan yang sama , seperti meter) terletak di P '= (x - h sin (a) / tan (s), y - h cos (a) / tan (s)). Anda hanya perlu menghitung sin (a) / tan (s) dan cos (a) / tan (s) satu kali untuk seluruh lapisan, dan untuk setiap poligon Anda hanya perlu mengalikan faktor-faktor tersebut dengan tinggi satu kali untuk mendapatkan offset untuk setiap titik bayangan di poligon. (Beban kerja komputasi yang sebenarnya dipikul oleh GIS, bukan kode Anda, karena membentuk serikat pekerja dari semua segiempat ini.)
Berikut ini contoh efeknya. (Azimuth dan ketinggian telah berubah sedikit dibandingkan dengan gambar pertama, tetapi poligon dan ketinggian bangunan - yang bervariasi - sama dengan sebelumnya.)
Lampiran
Menanggapi permintaan, inilah kode yang digunakan untuk membuat contoh kedua. Meskipun hampir tidak ada yang menggunakan bahasa ini (Avenue) lagi, itu bisa berfungsi sebagai pseudocode untuk menciptakan solusi dalam GIS favorit Anda. (Tidak seperti kebanyakan pseudocode, bagaimanapun, ia telah diuji dengan benar-benar menjalankannya. :-) Ini sangat sederhana sehingga tidak ada penjelasan yang diperlukan; perlu diketahui bahwa pengindeksan dimulai dengan 0, bukan 1, dan bahwa cincin poligon secara eksplisit ditutup (titik terakhir dalam daftar bertepatan dengan titik pertama).
' S
' Return the shadow of a shape.
' Field calculator example:
' av.run("S", {[shape], [height], 200, 35})
'======================================================================'
theShape = SELF.Get(0) ' A projected polygon
xHeight = SELF.Get(1) ' Expressed in the projected units
xAzimuth = SELF.Get(2).AsRadians ' Any angle (in degrees) east of north
xAltitude = SELF.Get(3).AsRadians ' Angle between 0 and 90 (vertical)
'
' Compute the shadow offsets.
'
xSpread = 1/xAltitude.Tan
x = -xHeight * xSpread * xAzimuth.Sin
y = -xHeight * xSpread * xAzimuth.Cos
xy = x@y
'
' Begin with the original shape.
'
p = theShape.Clone
'
' Adjoin the wall shadows.
'
for each lPts in theShape.AsList ' Loop over the rings
for each i in 1..(lPts.Count-1) ' Loop over edges in this ring
l = {lPts.Get(i-1), lPts.Get(i), lPts.Get(i)+xy, lPts.Get(i-1)+xy}
p = p.ReturnUnion(Polygon.Make({l}))
end
end
return p
' end of script