code wiki / _hdl_build / nx_geo_los.nx

nx_geo_los.nx source

↩ module page · 37 lines · 1837 B

1// nx_geo_los.nx -- LIB: GEO-022 LINE-OF-SIGHT / viewshed over a terrain elevation profile (DEM). 2// 3// Given an elevation profile sampled along a transect (heights[0..n]), an observer at index 0 and a 4// target at index n (each with an eye/structure height above ground), the target is VISIBLE iff no 5// intermediate terrain sample rises above the straight sight-line from observer to target. 6// 7// THE EXCEED ANGLE: the sight-line test is INTEGER and cross-multiplied -- compare heights[i]*n 8// against obsH*n + (tgtH-obsH)*i (no division, no float) -> the visible/blocked verdict is EXACT and 9// deterministic, even when a terrain sample sits exactly on the sight-line (decided, not an epsilon 10// coin-flip). Sovereign + offline; the DEM is seeded data, not a service. license_tier: ORIGINAL 11import "nx_syscalls.nx" 12 13// 1 if the target (index n) is visible from the observer (index 0), else 0 (the blocking index can be 14// recovered with geo_los_blocker). obs_eye / tgt_eye are heights ABOVE the ground at each endpoint. 15func geo_line_of_sight(heights: *i64, n: i64, obs_eye: i64, tgt_eye: i64) -> i64 { 16 let obsH: i64 = heights[0] + obs_eye 17 let tgtH: i64 = heights[n] + tgt_eye 18 var i: i64 = 1 19 while i < n { 20 // sight-line height at i = obsH + (tgtH-obsH)*i/n ; compare *n to avoid division. 21 if heights[i] * n > obsH * n + (tgtH - obsH) * i { return 0 } 22 i = i + 1 23 } 24 return 1 25} 26 27// index of the first terrain sample that blocks the sight-line, or -1 if the target is visible. 28func geo_los_blocker(heights: *i64, n: i64, obs_eye: i64, tgt_eye: i64) -> i64 { 29 let obsH: i64 = heights[0] + obs_eye 30 let tgtH: i64 = heights[n] + tgt_eye 31 var i: i64 = 1 32 while i < n { 33 if heights[i] * n > obsH * n + (tgtH - obsH) * i { return i } 34 i = i + 1 35 } 36 return 0 - 1 37}