76 lines
1.9 KiB
JavaScript
76 lines
1.9 KiB
JavaScript
(() => {
|
|
"use strict";
|
|
|
|
// ------ ANGLE DIFFERENCE BETWEEN TWO BEARINGS ------
|
|
|
|
// bearingDelta :: Radians -> Radians -> Radians
|
|
const bearingDelta = a =>
|
|
// The difference between two bearings: a and b.
|
|
b => {
|
|
const [ax, ay] = [sin(a), cos(a)];
|
|
const [bx, by] = [sin(b), cos(b)];
|
|
|
|
// Cross-product above zero ?
|
|
const sign = ((ay * bx) - (by * ax)) > 0 ? (
|
|
+1
|
|
) : -1;
|
|
|
|
// Sign * dot-product.
|
|
return sign * acos((ax * bx) + (ay * by));
|
|
};
|
|
|
|
|
|
// ---------------------- TEST -----------------------
|
|
// main :: IO ()
|
|
const main = () => [
|
|
[20, 45],
|
|
[-45, 45],
|
|
[-85, 90],
|
|
[-95, 90],
|
|
[-45, 125],
|
|
[-45, 145]
|
|
].map(xy => showMap(...xy))
|
|
.join("\n");
|
|
|
|
|
|
// ------------------- FORMATTING --------------------
|
|
|
|
// showMap :: Degrees -> Degrees -> String
|
|
const showMap = (da, db) => {
|
|
const
|
|
delta = degreesFromRadians(
|
|
bearingDelta(
|
|
radiansFromDegrees(da)
|
|
)(
|
|
radiansFromDegrees(db)
|
|
)
|
|
)
|
|
.toPrecision(4),
|
|
theta = `${da}° +`.padStart(6, " "),
|
|
theta1 = ` ${db}° -> `.padStart(11, " "),
|
|
diff = `${delta}°`.padStart(7, " ");
|
|
|
|
return `${theta}${theta1}${diff}`;
|
|
};
|
|
|
|
// --------------------- GENERIC ---------------------
|
|
|
|
// radiansFromDegrees :: Float -> Float
|
|
const radiansFromDegrees = n =>
|
|
Pi * n / 180.0;
|
|
|
|
// degreesFromRadians :: Float -> Float
|
|
const degreesFromRadians = x =>
|
|
180.0 * x / Pi;
|
|
|
|
// Abbreviations for trigonometric methods and
|
|
// properties of the standard Math library.
|
|
const [
|
|
Pi, sin, cos, acos
|
|
] = ["PI", "sin", "cos", "acos"]
|
|
.map(k => Math[k]);
|
|
|
|
// MAIN ---
|
|
return main();
|
|
})();
|