gpml2pvjson
Version:
convert GPML (XML) to pvjson (json)
263 lines • 12.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.lerp = exports.compass = exports.quadrant = exports.fromSlope = exports.fromSinCos = exports.toGon = exports.toDeg = exports.toRad = exports.distance = exports.diff = exports.between = exports.shortestDirection = exports.normalize = exports.normalizeHalf = exports.degreesToRadians = exports.radiansToDegrees = void 0;
var fp_1 = require("lodash/fp");
// based on code drawn from this repo:
// https://github.com/infusion/Angles.js/blob/master/angles.js
var TAU = 2 * Math.PI;
var EPS = 1e-15;
var SCALE = 2 * Math.PI;
var DIRECTIONS = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"];
/**
* Mathematical modulo
*
* @param {number} x
* @param {number} m
* @returns {number}
*/
function mod(x, m) {
return ((x % m) + m) % m;
}
/**
* Convert from radians to degrees
*
* @param {number} radians
* @returns {number} degrees
*/
function radiansToDegrees(radians) {
return (180 / Math.PI) * radians;
}
exports.radiansToDegrees = radiansToDegrees;
/**
* Convert from degrees to radians
*
* @param {number} degrees
* @returns {number} radians
*/
function degreesToRadians(degrees) {
return (Math.PI / 180) * degrees;
}
exports.degreesToRadians = degreesToRadians;
/**
* Normalize an arbitrary angle to the interval [-180, 180)
*
* @param {number} n
* @returns {number}
*/
function normalizeHalf(n) {
var h = SCALE / 2;
return mod(n + h, SCALE) - h;
}
exports.normalizeHalf = normalizeHalf;
/**
* Normalize an arbitrary angle to the interval [0, 360)
*
* @param {number} n
* @returns {number}
*/
function normalize(n) {
return mod(n, SCALE);
}
exports.normalize = normalize;
/**
* Gets the shortest direction to rotate to another angle
*
* @param {number} from
* @param {number} to
* @returns {number}
*/
function shortestDirection(from, to) {
var z = from - to;
// mod(-z, 360) < mod(z, 360) <=> mod(z + 180, 360) < 180 , for all z \ 180
if (from === to) {
return 0;
// if (mod(-z, 360) < mod(z, 360)) {
}
else if (normalizeHalf(z) < 0) {
return -1; // Left
}
else {
return +1; // Right
}
}
exports.shortestDirection = shortestDirection;
/**
* Checks if an angle is between two other angles
*
* @param {number} n
* @param {number} a
* @param {number} b
* @returns {boolean}
*/
function between(n, a, b) {
// Check if an angle n is between a and b
n = mod(n, SCALE);
a = mod(a, SCALE);
b = mod(b, SCALE);
if (a < b)
return a <= n && n <= b;
// return 0 <= n && n <= b || a <= n && n < 360;
return a <= n || n <= b;
}
exports.between = between;
/**
* Calculates the angular difference between two angles
* @param {number} a
* @param {number} b
* @returns {number}
*/
function diff(a, b) {
return Math.abs(b - a) % SCALE;
}
exports.diff = diff;
/**
* Calculate the minimal distance between two angles
*
* @param {number} a
* @param {number} b
* @returns {number}
*/
function distance(a, b) {
var h = SCALE / 2;
// One-Liner:
//return Math.min(mod(a - b, m), mod(b - a, m));
var diff = normalizeHalf(a - b);
if (diff > h)
diff = diff - SCALE;
return Math.abs(diff);
}
exports.distance = distance;
/**
* Calculate radians from current angle
*
* @param {number} n
* @returns {number}
*/
function toRad(n) {
// https://en.wikipedia.org/wiki/Radian
return (n / SCALE) * TAU;
}
exports.toRad = toRad;
/**
* Calculate degrees from current angle
*
* @param {number} n
* @returns {number}
*/
function toDeg(n) {
// https://en.wikipedia.org/wiki/Degree_(angle)
return (n / SCALE) * 360;
}
exports.toDeg = toDeg;
/**
* Calculate gons from current angle
*
* @param {number} n
* @returns {number}
*/
function toGon(n) {
// https://en.wikipedia.org/wiki/Gradian
return (n / SCALE) * 400;
}
exports.toGon = toGon;
/**
* Given the sine and cosine of an angle, what is the original angle?
*
* @param {number} sin
* @param {number} cos
* @returns {number}
*/
function fromSinCos(sin, cos) {
var angle = (1 + Math.acos(cos) / TAU) * SCALE;
if (sin < 0) {
angle = SCALE - angle;
}
return mod(angle, SCALE);
}
exports.fromSinCos = fromSinCos;
/**
* What is the angle of two points making a line
*
* @param {Array} p1
* @param {Array} p2
* @returns {number}
*/
function fromSlope(p1, p2) {
var angle = (TAU + Math.atan2(p2[1] - p1[1], p2[0] - p1[0])) % TAU;
return (angle / TAU) * SCALE;
}
exports.fromSlope = fromSlope;
/**
* Returns the quadrant
*
* @param {number} x The point x-coordinate
* @param {number} y The point y-coordinate
* @param {number=} k The optional number of regions in the coordinate-system
* @param {number=} shift An optional angle to rotate the coordinate system
* @returns {number}
*/
function quadrant(x, y, k, shift) {
if (fp_1.isUndefined(k))
k = 4; // How many regions? 4 = quadrant, 8 = octant, ...
if (fp_1.isUndefined(shift))
shift = 0; // Rotate the coordinate system by shift° (positiv = counter-clockwise)
/* shift = PI / k, k = 4:
* I) 45-135
* II) 135-225
* III) 225-315
* IV) 315-360
*/
/* shift = 0, k = 4:
* I) 0-90
* II) 90-180
* III) 180-270
* IV) 270-360
*/
var phi = (Math.atan2(y, x) + TAU) / TAU;
if (Math.abs((phi * SCALE) % (SCALE / k)) < EPS) {
return 0;
}
return 1 + mod(Math.floor((k * shift) / SCALE + k * phi), k);
}
exports.quadrant = quadrant;
/**
* Calculates the compass direction of the given angle
*
* @param {number} angle
* @returns {string}
*/
function compass(course) {
// 0° = N
// 90° = E
// 180° = S
// 270° = W
var k = DIRECTIONS.length;
var dir = Math.round((course / SCALE) * k);
return DIRECTIONS[mod(dir, k)];
}
exports.compass = compass;
/**
* Calculates the linear interpolation of two angles
*
* @param {number} a Angle one
* @param {number} b Angle two
* @param {number} p Percentage
* @param {number} dir Direction (either 1 [=CW] or -1 [=CCW])
* @returns {number}
*/
function lerp(a, b, p, dir) {
a = mod(a, SCALE);
b = mod(b, SCALE);
if (a === b)
return a;
// dir becomes an offset if we have to add a full revolution (=scale)
if (!dir)
dir = -SCALE;
else if ((dir === 1) === a < b)
dir *= SCALE;
else
dir = 0;
return mod(a + p * (b - a - dir), SCALE);
}
exports.lerp = lerp;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQW5nbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3Bpbm9mZnMvQW5nbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0NBQXdDO0FBRXhDLHNDQUFzQztBQUN0Qyw4REFBOEQ7QUFFOUQsSUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDeEIsSUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDO0FBQ2xCLElBQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO0FBQzFCLElBQU0sVUFBVSxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBRWhFOzs7Ozs7R0FNRztBQUNILFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ2YsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxPQUFlO0lBQzlDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQztBQUNuQyxDQUFDO0FBRkQsNENBRUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQWdCLGdCQUFnQixDQUFDLE9BQWU7SUFDOUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDO0FBQ25DLENBQUM7QUFGRCw0Q0FFQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLENBQUM7SUFDN0IsSUFBSSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUVsQixPQUFPLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFF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