Phương pháp nhanh và bẩn là chỉ vẽ bóng của mái nhà, làm cho chúng có màu xám đen (tốt nhất là bán trong suốt nếu có bất kỳ lớp mặt đất nào bên dưới) và vẽ đa giác tòa nhà lên trên chúng. Các bóng mái thu được bằng cách dịch các đa giác của tòa nhà theo khoảng cách được xác định bởi độ cao của tòa nhà theo hướng được thiết lập bởi góc phương vị và độ cao của nguồn sáng (được coi là vô cùng xa). (Một công thức cho số lượng bản dịch xuất hiện bên dưới.)
Điều này có xu hướng hoạt động tốt, ngoại trừ độ cao thấp hoặc các tòa nhà cao tầng (như tòa nhà chọc trời): xem bóng của các tòa nhà biệt lập cao hơn ở phía bên tay phải được tách ra khỏi các tòa nhà.
Để kết nối bóng tối đúng cách với các tòa nhà, bạn cần bao gồm bóng của các bức tường tòa nhà . Điều này không khó để làm. Bóng của bức tường kéo dài giữa một điểm nằm tại P và một điểm khác nằm ở Q sẽ là tứ giác được vạch ra bởi {P, Q, Q ', P'} trong đó Q 'là bóng của Q và P' là bóng của P. Một tòa nhà đa giác sẽ là một tập hợp các đa giác được kết nối được biểu thị bằng các chuỗi điểm kín (P (1), P (2), ..., P (n)). Đối với mỗi đa giác như vậy, tạo thành sự kết hợp các bóng của các cạnh (P (1), P (2)), (P (2), P (3)), ..., (P (n), P ( 1)). Điều này là đơn giản để thực hiện bằng một vòng lặp trên các cạnh.
Đối với một ánh sáng ở một góc phương vị của một độ (phía đông bắc) và độ cao của độ (từ đường chân trời), cái bóng của một điểm P có tọa độ dự kiến (x, y) và chiều cao h (tất cả được thể hiện trong cùng một đơn vị , chẳng hạn như mét) được đặt tại P '= (x - h sin (a) / tan (s), y - h cos (a) / tan (s)). Bạn chỉ phải tính sin (a) / tan (s) và cos (a) / tan (s) một lần cho toàn bộ lớp và đối với mỗi đa giác, bạn chỉ phải nhân các yếu tố đó với chiều cao một lần để có được độ lệch cho mỗi điểm bóng trong đa giác. (Khối lượng công việc tính toán thực sự được thực hiện bởi GIS, không phải mã của bạn, vì nó tạo thành các hiệp hội của tất cả các tứ giác này.)
Đây là một ví dụ về hiệu ứng. (Góc phương vị và độ cao đã thay đổi một chút so với hình đầu tiên, nhưng đa giác và chiều cao của tòa nhà - khác nhau - giống như trước đây.)
ruột thừa
Đáp lại yêu cầu, đây là mã được sử dụng để tạo ví dụ thứ hai. Mặc dù hầu như không ai sử dụng ngôn ngữ này (Đại lộ) nữa, nhưng nó cũng có thể đóng vai trò là mã giả để tạo ra một giải pháp trong hệ thống GIS yêu thích của bạn. (Tuy nhiên, không giống như hầu hết mã giả, nó đã được kiểm tra bằng cách thực sự chạy nó. :-) Thật đơn giản đến nỗi không cần giải thích; chỉ cần lưu ý rằng việc lập chỉ mục bắt đầu bằng 0, không phải 1 và các vòng đa giác được đóng rõ ràng (điểm cuối cùng trong danh sách trùng với điểm đầu tiên).
' 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