diff --git a/assets/js/elevation_profile_hook.js b/assets/js/elevation_profile_hook.js index 311f7b89..12643d0f 100644 --- a/assets/js/elevation_profile_hook.js +++ b/assets/js/elevation_profile_hook.js @@ -67,10 +67,20 @@ export const ElevationProfile = { renderChart(data) { const points = data.points const distances = points.map(p => p.dist_km * KM2MI) - const elevations = points.map(p => p.elev * M2FT) + const showFresnel = data.freq_mhz >= 1000 + + // Earth curvature: add bulge to terrain so it curves up in the middle + // relative to the straight LOS beam. bulge(f) = d1*d2 / (2*k*R) + const k = data.k_factor || (4 / 3) + const R = 6371000 // earth radius in meters + const dTotal = (data.dist_km || 0) * 1000 + const elevations = points.map((p, i) => { + const f = points.length > 1 ? i / (points.length - 1) : 0 + const bulge = (f * dTotal * (1 - f) * dTotal) / (2 * k * R) + return (p.elev + bulge) * M2FT + }) const losLine = points.map(p => p.beam * M2FT) const fresnelLower = points.map(p => (p.beam - p.r1) * M2FT) - const showFresnel = data.freq_mhz >= 1000 const ducts = (data.ducts || []).map(d => ({ base_ft: d.base_m_msl * M2FT, diff --git a/lib/microwaveprop/terrain/terrain_analysis.ex b/lib/microwaveprop/terrain/terrain_analysis.ex index cb10989d..f281a0fc 100644 --- a/lib/microwaveprop/terrain/terrain_analysis.ex +++ b/lib/microwaveprop/terrain/terrain_analysis.ex @@ -89,6 +89,7 @@ defmodule Microwaveprop.Terrain.TerrainAnalysis do points: points, diffraction_db: diffraction_db, verdict: verdict, + k_factor: k, max_elevation_m: max_elevation_m, min_clearance_m: min_clearance_m, obstructed_count: length(obstructed), diff --git a/lib/microwaveprop_web/live/contact_live/show.ex b/lib/microwaveprop_web/live/contact_live/show.ex index dc7f07ca..7069fdf2 100644 --- a/lib/microwaveprop_web/live/contact_live/show.ex +++ b/lib/microwaveprop_web/live/contact_live/show.ex @@ -1103,6 +1103,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do end), freq_mhz: freq_ghz * 1000, dist_km: dist_km, + k_factor: analysis.k_factor, fwd_az: fwd_az, rev_az: rev_az, fwd_el: fwd_el,