fix: proper beam heading on the map
This commit is contained in:
@@ -122,10 +122,8 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
|
|||||||
if (from && beamAzimuths && beamAzimuths.length) {
|
if (from && beamAzimuths && beamAzimuths.length) {
|
||||||
const half = (beamWidth ?? 30) / 2;
|
const half = (beamWidth ?? 30) / 2;
|
||||||
const D = 5500; // lobe length (km)
|
const D = 5500; // lobe length (km)
|
||||||
// A great circle pointing poleward runs to lat ±90, where Mercator is
|
// Great-circle radial out to distance D, stopping just short of the pole so
|
||||||
// infinite — the line then snaps across the top of the map. Generate the
|
// a poleward line doesn't snap across the top of the Mercator map.
|
||||||
// radial with plenty of points (smooth curve) and STOP it just before the
|
|
||||||
// pole, so a north/south beam draws a clean line toward the edge instead.
|
|
||||||
const radial = (b: number): [number, number][] => {
|
const radial = (b: number): [number, number][] => {
|
||||||
const pts: [number, number][] = [];
|
const pts: [number, number][] = [];
|
||||||
const N = 64;
|
const N = 64;
|
||||||
@@ -137,26 +135,17 @@ export function MainMap({ fromGrid, toGrid, fromLabel, toLabel, beamAzimuths, be
|
|||||||
return pts;
|
return pts;
|
||||||
};
|
};
|
||||||
for (const az of beamAzimuths) {
|
for (const az of beamAzimuths) {
|
||||||
const arc: [number, number][] = [];
|
// Draw the lobe as a FAN of translucent great-circle radials, not a
|
||||||
for (let b = az - half; b <= az + half + 0.001; b += 2) {
|
// filled polygon: a polygon breaks badly near the poles on Mercator (its
|
||||||
const d = destinationPoint(from.lat, from.lon, b, D);
|
// edges run off toward ±90° and the fill smears across the map), while
|
||||||
arc.push([d.lat, d.lon]);
|
// each radial LINE stays clean. The overlapping lines read as a lobe —
|
||||||
|
// solid near the antenna, fanning out toward the front. Works for any
|
||||||
|
// azimuth, north/south included.
|
||||||
|
for (let b = az - half; b <= az + half + 0.001; b += 1.5) {
|
||||||
|
const line = unwrapLon([[from.lat, from.lon], ...radial(b)]);
|
||||||
|
L.polyline(line as L.LatLngExpression[], { color: '#dc2626', weight: 6, opacity: 0.07 }).addTo(wo);
|
||||||
}
|
}
|
||||||
const ring = unwrapLon([
|
// Boresight (dashed centre line).
|
||||||
[from.lat, from.lon],
|
|
||||||
...radial(az - half),
|
|
||||||
...arc,
|
|
||||||
...radial(az + half).reverse(),
|
|
||||||
]);
|
|
||||||
// Near a pole the lobe's two edges diverge wildly (one runs NW, the
|
|
||||||
// other NE) and look broken on a Mercator map — so for a poleward beam
|
|
||||||
// show ONLY the clean boresight (below). Otherwise draw the filled lobe.
|
|
||||||
if (!ring.some(([la]) => Math.abs(la) > 78)) {
|
|
||||||
L.polygon(ring as L.LatLngExpression[], {
|
|
||||||
color: '#dc2626', weight: 1, opacity: 0.5, fillColor: '#dc2626', fillOpacity: 0.14,
|
|
||||||
}).addTo(wo);
|
|
||||||
}
|
|
||||||
// Boresight (dashed centre line) — always; great-circle polyline is safe.
|
|
||||||
const cl = unwrapLon([[from.lat, from.lon], ...radial(az)]);
|
const cl = unwrapLon([[from.lat, from.lon], ...radial(az)]);
|
||||||
L.polyline(cl as L.LatLngExpression[], { color: '#dc2626', weight: 1.5, opacity: 0.7, dashArray: '5 4' })
|
L.polyline(cl as L.LatLngExpression[], { color: '#dc2626', weight: 1.5, opacity: 0.7, dashArray: '5 4' })
|
||||||
.bindTooltip(`Beam ${Math.round(az)}°`, { permanent: false, direction: 'top' }).addTo(wo);
|
.bindTooltip(`Beam ${Math.round(az)}°`, { permanent: false, direction: 'top' }).addTo(wo);
|
||||||
|
|||||||
Reference in New Issue
Block a user