# Exercise 1: plan a light for a second headland. import math NM = 1852.0 NM_PER_SQRT_M = 3.86 / (NM / 1000) def geographic_range_nm(light_m, eye_m): return NM_PER_SQRT_M * (math.sqrt(light_m) + math.sqrt(eye_m)) def luminous_range_nm(intensity_cd, visibility_nm): t = 0.05 ** (1 / visibility_nm) lo, hi = 0.01, 200.0 for _ in range(100): mid = (lo + hi) / 2 if intensity_cd * t ** mid / (mid * NM) ** 2 > 2e-7: lo = mid else: hi = mid return (lo + hi) / 2 def intensity_needed_cd(range_nm, visibility_nm): lo, hi = 1.0, 1e9 for _ in range(200): mid = math.sqrt(lo * hi) if luminous_range_nm(mid, visibility_nm) < range_nm: lo = mid else: hi = mid return hi EYE_M, CLEAR_NM, POOR_NM, GROUND_M = 10, 20, 8, 30 # assumed brief for the second headland # Part 1: the focal height that gives the clear-weather horizon, and the tower that makes it. focal_needed = (CLEAR_NM / NM_PER_SQRT_M - math.sqrt(EYE_M)) ** 2 print("focal height needed for", CLEAR_NM, "nm:", round(focal_needed, 1), "m; tower on", GROUND_M, "m of ground:", round(focal_needed - GROUND_M, 1), "m") # Part 2: the geographic range for towers of 10 to 25 m. for tower in (10, 15, 20, 25): geo = geographic_range_nm(GROUND_M + tower, EYE_M) print("tower", tower, "m -> focal", GROUND_M + tower, "m ->", round(geo, 1), "nm", "(meets the brief)" if geo >= CLEAR_NM else "(too short)") # Part 3: the intensity each weather case needs, and which one decides. cd_clear = intensity_needed_cd(CLEAR_NM, 10) cd_poor = intensity_needed_cd(POOR_NM, 2) print("clear case:", round(cd_clear), "cd | poor case:", round(cd_poor), "cd | decides:", "clear" if cd_clear > cd_poor else "poor") # Part 4: how much extra intensity buys how much extra range at the standard visibility. base = max(cd_clear, cd_poor) for factor in (1, 2, 4, 10): print(factor, "x intensity -> nominal range", round(luminous_range_nm(base * factor, 10), 1), "nm") # focal height needed for 20 nm: 41.4 m; tower on 30 m of ground: 11.4 m # tower 10 m -> focal 40 m -> 19.8 nm (too short) # tower 15 m -> focal 45 m -> 20.6 nm (meets the brief) # tower 20 m -> focal 50 m -> 21.3 nm (meets the brief) # tower 25 m -> focal 55 m -> 22.0 nm (meets the brief) # clear case: 109757 cd | poor case: 7024443 cd | decides: poor # 1 x intensity -> nominal range 31.0 nm # 2 x intensity -> nominal range 32.9 nm # 4 x intensity -> nominal range 34.8 nm # 10 x intensity -> nominal range 37.4 nm