fix(cockpit): no swath readout while the orbital view looks past the Earth's limb

This commit is contained in:
Sameh Khamis committed 2026-11-08 15:55:02 -08:00
1 parent 5c25bc54e6
commit 6ca53febad
3 files changed
+37 -4

No files matched your search

+15
View File
@@ -364,6 +364,21 @@ export function offNadirAngleDeg({ northDeg = 0, eastDeg = 0 } = {}) {
return (Math.acos(cosine) * 180) / Math.PI;
}
/**
* Whether the view's centre, tilted off nadir, still meets the Earth: its
* angle from nadir (`offNadirAngleDeg`) is within the Earth's angular radius
* from the satellite, asin(R / (R + altitude)).
* @param {number} altitudeM
* @param {{northDeg?: number, eastDeg?: number}} [offset]
* @returns {boolean}
*/
export function offNadirCentreMeetsEarth(altitudeM, offset = {}) {
if (!Number.isFinite(altitudeM) || altitudeM <= 0) return false;
const R = ORBITAL_EARTH_RADIUS_M;
const limbDeg = (Math.asin(R / (R + altitudeM)) * 180) / Math.PI;
return offNadirAngleDeg(offset) < limbDeg;
}
/**
* Roughly how much wider the ground across the frame is at the centre of a
* tilted view than at nadir, on a flat Earth: tilting across the frame (east,
+14
View File
@@ -13,6 +13,7 @@ import {
nadirOrientation,
nextOrbitalZoom,
offNadirAngleDeg,
offNadirCentreMeetsEarth,
offNadirSwathScale,
offNadirOrientation,
orbitalBaseFovRad,
@@ -300,3 +301,16 @@ test("a tilted view's width grows faster across the frame than along it", () =>
}
assert.equal(offNadirSwathScale({ northDeg: Number.NaN }), 1);
});
test('a view tilted past the limb no longer meets the Earth', () => {
// GEO: the Earth spans about 8.7 degrees either side of nadir.
assert.equal(offNadirCentreMeetsEarth(35_786_000, { northDeg: 5 }), true);
assert.equal(offNadirCentreMeetsEarth(35_786_000, { northDeg: 15 }), false);
// LEO: a 30 degree tilt still lands on the ground.
assert.equal(
offNadirCentreMeetsEarth(420_000, { northDeg: 20, eastDeg: 20 }),
true,
);
assert.equal(offNadirCentreMeetsEarth(420_000, { eastDeg: 80 }), false);
assert.equal(offNadirCentreMeetsEarth(NaN, {}), false);
});
+8 -4
View File
@@ -14,6 +14,7 @@ import {
nextOrbitalZoom,
offNadirAngleDeg,
offNadirOrientation,
offNadirCentreMeetsEarth,
offNadirSwathScale,
orbitalBaseFovRad,
previousOrbitalZoom,
@@ -410,9 +411,12 @@ export function publishOrbitalView(info, transition = IDLE_TRANSITION) {
const settledFov = fovForZoom(orbitalBaseFovRad(info.altitudeM), state.zoom);
const footprintKm = footprintWidthKm(info.altitudeM, settledFov, aspect);
const trackUp = Number.isFinite(info.groundTrackDeg);
const swathScale = offset
? offNadirSwathScale(lookTilt(orbitalLookReadoutParts(state.lookTarget)))
: 1;
const tilt = offset
? lookTilt(orbitalLookReadoutParts(state.lookTarget))
: null;
const swathScale = offset ? offNadirSwathScale(tilt) : 1;
// Tilted past the limb, the view's centre looks into space: no swath.
const seesEarth = !offset || offNadirCentreMeetsEarth(info.altitudeM, tilt);
this.publishOrbital({
name: info.name,
classLabel: info.classLabel || '',
@@ -432,7 +436,7 @@ export function publishOrbitalView(info, transition = IDLE_TRANSITION) {
// the nadir footprint (`offNadirSwathScale`); 1 and null at nadir.
swathScale,
swathKm:
offset && Number.isFinite(footprintKm)
offset && seesEarth && Number.isFinite(footprintKm)
? footprintKm * swathScale
: null,
},