From b8380e3e0f68ef661234f15ea56060c600cc2b08 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Wed, 22 Apr 2026 16:18:12 -0500 Subject: [PATCH] Fix LOS clearance: use real bezier apex, not control point --- static/js/nlos.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/static/js/nlos.js b/static/js/nlos.js index 919bc7c..ff9ceec 100644 --- a/static/js/nlos.js +++ b/static/js/nlos.js @@ -279,12 +279,13 @@ const h2px = s.values.h2 * pxPerM; const yA = groundY - h1px, yB = groundY - h2px; - // signal line, compute clearance over hill apex + // signal line, compute clearance over the hill's actual apex. The hill is drawn + // as a quadratic bezier from (hx-hw, groundY) to (hx+hw, groundY) with control + // at (hx, groundY - hh*2). At t=0.5 the curve reaches groundY - hh, which is + // the real visual top. Using the control-point y here would over-count by 2x. const t = (hx - xA) / (xB - xA); const yOnRay = yA + (yB - yA) * t; - const hillTop = groundY - hh * 2; - const clearance = hillTop - yOnRay; // negative = obstructed... actually no: smaller y = higher. yOnRay < hillTop (more negative offset) means ray is ABOVE hill => clearance positive. - // With screen coords (y down), ray above hill means yOnRay < hillTop. Clearance in meters = (hillTop - yOnRay)/pxPerM. Positive when ray above hill. + const hillTop = groundY - hh; const clearanceM = (hillTop - yOnRay) / pxPerM; const blocked = clearanceM < 0;