89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import computeDestinationPoint from 'geolib/es/computeDestinationPoint';
|
|
import Parser from '../parser';
|
|
import { computeSpeed } from '../utils/computeSpeed';
|
|
import { computeTurnRate } from '../utils/computeTurnRate';
|
|
|
|
// NOTE: Distance is interpreted as distance and not time
|
|
export const TerminatorsHA = (leg: HATerminalEntry, previousFix: NavFix): [NavFix?, LineSegment[]?] => {
|
|
const refFix = {
|
|
latitude: leg.WptLat,
|
|
longitude: leg.WptLon,
|
|
};
|
|
const speed = computeSpeed(leg, previousFix);
|
|
const turnRate = computeTurnRate(speed, Parser.AC_BANK);
|
|
const inboundCrs = leg.Course.toTrue(refFix);
|
|
const outboundCrs = inboundCrs.reciprocalCourse();
|
|
|
|
const line: LineSegment[] = [[previousFix.longitude, previousFix.latitude]];
|
|
|
|
// Generate top arc
|
|
let currentCrs = inboundCrs;
|
|
while (!currentCrs.equal(outboundCrs)) {
|
|
let time = 0;
|
|
if (leg.TurnDir === 'R') {
|
|
const delta = (outboundCrs - currentCrs).normaliseDegrees();
|
|
const increment = delta < 0.1 ? delta : 0.1;
|
|
currentCrs = (currentCrs + increment).normaliseDegrees();
|
|
time = increment / turnRate;
|
|
} else {
|
|
const delta = (currentCrs - outboundCrs).normaliseDegrees();
|
|
const increment = delta < 0.1 ? delta : 0.1;
|
|
currentCrs = (currentCrs - increment).normaliseDegrees();
|
|
time = increment / turnRate;
|
|
}
|
|
|
|
const arcFix = computeDestinationPoint(
|
|
{
|
|
latitude: line.at(-1)![1],
|
|
longitude: line.at(-1)![0],
|
|
},
|
|
((speed / 3600) * time).toMetre(),
|
|
currentCrs
|
|
);
|
|
|
|
line.push([arcFix.longitude, arcFix.latitude]);
|
|
}
|
|
|
|
const outboundStart = computeDestinationPoint(
|
|
{
|
|
latitude: line.at(-1)![1],
|
|
longitude: line.at(-1)![0],
|
|
},
|
|
leg.Distance.toMetre(),
|
|
outboundCrs
|
|
);
|
|
line.push([outboundStart.longitude, outboundStart.latitude]);
|
|
|
|
// Generate bottom arc
|
|
currentCrs = outboundCrs;
|
|
while (!currentCrs.equal(inboundCrs)) {
|
|
let time = 0;
|
|
if (leg.TurnDir === 'R') {
|
|
const delta = (inboundCrs - currentCrs).normaliseDegrees();
|
|
const increment = delta < 0.1 ? delta : 0.1;
|
|
currentCrs = (currentCrs + increment).normaliseDegrees();
|
|
time = increment / turnRate;
|
|
} else {
|
|
const delta = (currentCrs - inboundCrs).normaliseDegrees();
|
|
const increment = delta < 0.1 ? delta : 0.1;
|
|
currentCrs = (currentCrs - increment).normaliseDegrees();
|
|
time = increment / turnRate;
|
|
}
|
|
|
|
const arcFix = computeDestinationPoint(
|
|
{
|
|
latitude: line.at(-1)![1],
|
|
longitude: line.at(-1)![0],
|
|
},
|
|
((speed / 3600) * time).toMetre(),
|
|
currentCrs
|
|
);
|
|
|
|
line.push([arcFix.longitude, arcFix.latitude]);
|
|
}
|
|
|
|
line.push([refFix.longitude, refFix.latitude]);
|
|
|
|
return [refFix, line];
|
|
};
|