Major refactoring of RFCP backend: - Modular propagation models (8 models) - SharedMemoryManager for terrain data - ProcessPoolExecutor parallel processing - WebSocket progress streaming - Building filtering pipeline (351k → 15k) - 82 unit tests Performance: Standard preset 38s → 5s (7.6x speedup) Known issue: Detailed preset timeout (fix in 3.1.0)
41 lines
849 B
Python
41 lines
849 B
Python
"""
|
|
Knife-edge diffraction geometry calculations.
|
|
"""
|
|
|
|
import math
|
|
|
|
|
|
def knife_edge_loss(
|
|
d1_m: float,
|
|
d2_m: float,
|
|
h_m: float,
|
|
wavelength_m: float,
|
|
) -> float:
|
|
"""
|
|
Calculate diffraction loss over single knife edge.
|
|
|
|
Args:
|
|
d1_m: Distance TX to obstacle
|
|
d2_m: Distance obstacle to RX
|
|
h_m: Obstacle height above LOS (positive = above)
|
|
wavelength_m: Signal wavelength
|
|
|
|
Returns:
|
|
Loss in dB (>= 0)
|
|
"""
|
|
if d1_m <= 0 or d2_m <= 0 or wavelength_m <= 0:
|
|
return 0.0
|
|
|
|
v = h_m * math.sqrt(2 * (d1_m + d2_m) / (wavelength_m * d1_m * d2_m))
|
|
|
|
if v < -0.78:
|
|
L = 0.0
|
|
elif v < 0:
|
|
L = 6.02 + 9.11 * v - 1.27 * v ** 2
|
|
elif v < 2.4:
|
|
L = 6.02 + 9.11 * v + 1.65 * v ** 2
|
|
else:
|
|
L = 12.95 + 20 * math.log10(v)
|
|
|
|
return max(0.0, L)
|