@turf/ellipse
Version:
Takes a Point and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision.
92 lines (83 loc) • 3.13 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true});// index.ts
var _helpers = require('@turf/helpers');
var _destination = require('@turf/destination');
var _transformrotate = require('@turf/transform-rotate');
var _invariant = require('@turf/invariant');
function ellipse(center, xSemiAxis, ySemiAxis, options) {
options = options || {};
let steps = options.steps || 64;
const units = options.units || "kilometers";
let angle = options.angle || 0;
const pivot = options.pivot || center;
const properties = options.properties || {};
if (!center) throw new Error("center is required");
if (!xSemiAxis) throw new Error("xSemiAxis is required");
if (!ySemiAxis) throw new Error("ySemiAxis is required");
if (!_helpers.isObject.call(void 0, options)) throw new Error("options must be an object");
if (!_helpers.isNumber.call(void 0, steps)) throw new Error("steps must be a number");
if (!_helpers.isNumber.call(void 0, angle)) throw new Error("angle must be a number");
const centerCoords = _invariant.getCoord.call(void 0,
_transformrotate.transformRotate.call(void 0, _helpers.point.call(void 0, _invariant.getCoord.call(void 0, center)), angle, { pivot })
);
angle = -90 + angle;
steps = Math.ceil(steps / 4);
let quadrantParameters = [];
let parameters = [];
const a = xSemiAxis;
const b = ySemiAxis;
const c = b;
const m = (a - b) / (Math.PI / 2);
const A = (a + b) * Math.PI / 4;
const v = 0.5;
const k = steps;
let w = 0;
let x = 0;
for (let i = 0; i < steps; i++) {
x += w;
if (m === 0) {
w = A / k / c;
} else {
w = (-(m * x + c) + Math.sqrt(Math.pow(m * x + c, 2) - 4 * (v * m) * -(A / k))) / (2 * (v * m));
}
if (x != 0) {
quadrantParameters.push(x);
}
}
parameters.push(0);
for (let i = 0; i < quadrantParameters.length; i++) {
parameters.push(quadrantParameters[i]);
}
parameters.push(Math.PI / 2);
for (let i = 0; i < quadrantParameters.length; i++) {
parameters.push(
Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
);
}
parameters.push(Math.PI);
for (let i = 0; i < quadrantParameters.length; i++) {
parameters.push(Math.PI + quadrantParameters[i]);
}
parameters.push(3 * Math.PI / 2);
for (let i = 0; i < quadrantParameters.length; i++) {
parameters.push(
2 * Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
);
}
parameters.push(0);
const coords = [];
for (const param of parameters) {
const theta = Math.atan2(b * Math.sin(param), a * Math.cos(param));
const r = Math.sqrt(
Math.pow(a, 2) * Math.pow(b, 2) / (Math.pow(a * Math.sin(theta), 2) + Math.pow(b * Math.cos(theta), 2))
);
coords.push(
_destination.destination.call(void 0, centerCoords, r, angle + _helpers.radiansToDegrees.call(void 0, theta), {
units
}).geometry.coordinates
);
}
return _helpers.polygon.call(void 0, [coords], properties);
}
var index_default = ellipse;
exports.default = index_default; exports.ellipse = ellipse;
//# sourceMappingURL=index.cjs.map