Швидкий і брудний метод - намалювати тіні тільки на дахах будівлі, зробити їх темно-сірими (бажано напівпрозорими, якщо є якісь основні шари ґрунту), і намалювати над ними багатокутники будівлі. Тіні на даху отримують шляхом перекладу будівельних багатокутників на відстані, визначені висотами будівлі, у напрямку, встановленому азимутом та висотою джерела світла (вважається нескінченним далеко). (Формула кількості перекладу відображається нижче.)
Це, як правило, справно, за винятком низьких висот або високих будівель (наприклад, хмарочосів): подивіться, як тіні високих ізольованих будівель з правого боку відокремлюються від самих будівель.
Щоб правильно з'єднати тіні з будинками, потрібно включити тіні стін будівлі . Це не важко зробити. Тінь стіни, що проходить між точкою, розташованою на P, та іншою точкою, розташованою у Q, буде чотирикутником, окресленим {P, Q, Q ', P'}, де Q '- тінь Q, а P' - тінь P. Полігональна споруда буде сукупністю з’єднаних багатокутників, представлених замкнутими послідовностями точок (P (1), P (2), ..., P (n)). Для кожного такого многокутника сформуйте об’єднання тіней ребер (P (1), P (2)), (P (2), P (3)), ..., (P (n), P ( 1)). Це легко зробити за допомогою петлі по краях.
Для світла при азимут через градуси ( до сходу від півночі) і висоти и градусів (від горизонту), тіні в точці Р з прогнозованими координатами (х, у) і висот ч (всього виражається в тих же одиницях , наприклад, метри), розташований при P '= (x - h sin (a) / tan (s), y - h cos (a) / tan (s)). Вам потрібно лише обчислити sin (a) / tan (s) та cos (a) / tan (s) один раз для всього шару, і для кожного багатокутника потрібно лише один раз помножити ці коефіцієнти на висоту, щоб отримати зрушення для кожна точкова тінь у полігоні. (Справжнє обчислювальне навантаження несе ГІС, а не ваш код, оскільки він утворює об'єднання всіх цих чотирикутників.)
Ось приклад ефекту. (Азимут і висота дещо змінилися в порівнянні з першою фігурою, але багатокутники та висоти будівлі - які змінюються - такі ж, як і раніше.)
Додаток
У відповідь на запит, ось код, який використовується для створення другого прикладу. Хоча майже ніхто не використовує цю мову (Avenue), він цілком може слугувати псевдокодом для створення рішення у вашому улюбленому ГІС. (На відміну від більшості псевдокодів, проте він був перевірений, фактично запустивши його. :-) Це так просто, що ніяких пояснень не потрібно; просто майте на увазі, що індексація починається з 0, а не з 1, і що кільця полігонів явно закриті (остання точка у списку збігається з першою точкою).
' 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