@turf/ellipse 7.2.0 → 7.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cjs/index.cjs +62 -39
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +64 -41
- package/dist/esm/index.js.map +1 -1
- package/package.json +22 -20
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Takes a [Point][1] and calculates the ellipse polygon given two semi-axes expres
|
|
|
16
16
|
* `options.angle` **[number][3]** angle of rotation in decimal degrees, positive clockwise (optional, default `0`)
|
|
17
17
|
* `options.pivot` **[Coord][2]** point around which any rotation will be performed (optional, default `center`)
|
|
18
18
|
* `options.steps` **[number][3]** number of steps (optional, default `64`)
|
|
19
|
-
* `options.units` **
|
|
19
|
+
* `options.units` **Units** unit of measurement for axes. Supports all valid Turf [Units][5] (optional, default `'kilometers'`)
|
|
20
20
|
* `options.properties` **[Object][4]** properties (optional, default `{}`)
|
|
21
21
|
|
|
22
22
|
### Examples
|
|
@@ -41,7 +41,7 @@ Returns **[Feature][6]<[Polygon][7]>** ellipse polygon
|
|
|
41
41
|
|
|
42
42
|
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
|
43
43
|
|
|
44
|
-
[5]: https://
|
|
44
|
+
[5]: https://turfjs.org/docs/api/types/Units
|
|
45
45
|
|
|
46
46
|
[6]: https://tools.ietf.org/html/rfc7946#section-3.2
|
|
47
47
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
var _helpers = require('@turf/helpers');
|
|
8
|
-
var
|
|
9
|
+
var _destination = require('@turf/destination');
|
|
9
10
|
var _transformrotate = require('@turf/transform-rotate');
|
|
10
11
|
var _invariant = require('@turf/invariant');
|
|
11
12
|
function ellipse(center, xSemiAxis, ySemiAxis, options) {
|
|
12
13
|
options = options || {};
|
|
13
|
-
|
|
14
|
+
let steps = options.steps || 64;
|
|
14
15
|
const units = options.units || "kilometers";
|
|
15
|
-
|
|
16
|
+
let angle = options.angle || 0;
|
|
16
17
|
const pivot = options.pivot || center;
|
|
17
18
|
const properties = options.properties || {};
|
|
18
19
|
if (!center) throw new Error("center is required");
|
|
@@ -21,49 +22,71 @@ function ellipse(center, xSemiAxis, ySemiAxis, options) {
|
|
|
21
22
|
if (!_helpers.isObject.call(void 0, options)) throw new Error("options must be an object");
|
|
22
23
|
if (!_helpers.isNumber.call(void 0, steps)) throw new Error("steps must be a number");
|
|
23
24
|
if (!_helpers.isNumber.call(void 0, angle)) throw new Error("angle must be a number");
|
|
24
|
-
const centerCoords = _invariant.getCoord.call(void 0,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const centerCoords = _invariant.getCoord.call(void 0,
|
|
26
|
+
_transformrotate.transformRotate.call(void 0, _helpers.point.call(void 0, _invariant.getCoord.call(void 0, center)), angle, { pivot })
|
|
27
|
+
);
|
|
28
|
+
angle = -90 + angle;
|
|
29
|
+
steps = Math.ceil(steps / 4);
|
|
30
|
+
let quadrantParameters = [];
|
|
31
|
+
let parameters = [];
|
|
32
|
+
const a = xSemiAxis;
|
|
33
|
+
const b = ySemiAxis;
|
|
34
|
+
const c = b;
|
|
35
|
+
const m = (a - b) / (Math.PI / 2);
|
|
36
|
+
const A = (a + b) * Math.PI / 4;
|
|
37
|
+
const v = 0.5;
|
|
38
|
+
const k = steps;
|
|
39
|
+
let w = 0;
|
|
40
|
+
let x = 0;
|
|
41
|
+
for (let i = 0; i < steps; i++) {
|
|
42
|
+
x += w;
|
|
43
|
+
if (m === 0) {
|
|
44
|
+
w = A / k / c;
|
|
45
|
+
} else {
|
|
46
|
+
w = (-(m * x + c) + Math.sqrt(Math.pow(m * x + c, 2) - 4 * (v * m) * -(A / k))) / (2 * (v * m));
|
|
47
|
+
}
|
|
48
|
+
if (x != 0) {
|
|
49
|
+
quadrantParameters.push(x);
|
|
50
|
+
}
|
|
30
51
|
}
|
|
31
|
-
|
|
32
|
-
for (let i = 0; i <
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
parameters.push(0);
|
|
53
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
54
|
+
parameters.push(quadrantParameters[i]);
|
|
55
|
+
}
|
|
56
|
+
parameters.push(Math.PI / 2);
|
|
57
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
58
|
+
parameters.push(
|
|
59
|
+
Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
|
|
36
60
|
);
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
}
|
|
62
|
+
parameters.push(Math.PI);
|
|
63
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
64
|
+
parameters.push(Math.PI + quadrantParameters[i]);
|
|
65
|
+
}
|
|
66
|
+
parameters.push(3 * Math.PI / 2);
|
|
67
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
68
|
+
parameters.push(
|
|
69
|
+
2 * Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
|
|
39
70
|
);
|
|
40
|
-
if (stepAngle < -90 && stepAngle >= -270) x = -x;
|
|
41
|
-
if (stepAngle < -180 && stepAngle >= -360) y = -y;
|
|
42
|
-
if (units === "degrees") {
|
|
43
|
-
const angleRad = _helpers.degreesToRadians.call(void 0, angle);
|
|
44
|
-
const newx = x * Math.cos(angleRad) + y * Math.sin(angleRad);
|
|
45
|
-
const newy = y * Math.cos(angleRad) - x * Math.sin(angleRad);
|
|
46
|
-
x = newx;
|
|
47
|
-
y = newy;
|
|
48
|
-
}
|
|
49
|
-
coordinates.push([x + centerCoords[0], y + centerCoords[1]]);
|
|
50
71
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
parameters.push(0);
|
|
73
|
+
const coords = [];
|
|
74
|
+
for (const param of parameters) {
|
|
75
|
+
const theta = Math.atan2(b * Math.sin(param), a * Math.cos(param));
|
|
76
|
+
const r = Math.sqrt(
|
|
77
|
+
Math.pow(a, 2) * Math.pow(b, 2) / (Math.pow(a * Math.sin(theta), 2) + Math.pow(b * Math.cos(theta), 2))
|
|
78
|
+
);
|
|
79
|
+
coords.push(
|
|
80
|
+
_destination.destination.call(void 0, centerCoords, r, angle + _helpers.radiansToDegrees.call(void 0, theta), {
|
|
81
|
+
units
|
|
82
|
+
}).geometry.coordinates
|
|
83
|
+
);
|
|
58
84
|
}
|
|
85
|
+
return _helpers.polygon.call(void 0, [coords], properties);
|
|
59
86
|
}
|
|
60
|
-
|
|
61
|
-
const rad = deg * Math.PI / 180;
|
|
62
|
-
return Math.tan(rad);
|
|
63
|
-
}
|
|
64
|
-
var turf_ellipse_default = ellipse;
|
|
87
|
+
var index_default = ellipse;
|
|
65
88
|
|
|
66
89
|
|
|
67
90
|
|
|
68
|
-
exports.default =
|
|
91
|
+
exports.default = index_default; exports.ellipse = ellipse;
|
|
69
92
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-ellipse/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"AAAA;ACAA;AACE;AACA;AACA;AACA;AAAA,
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-ellipse/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-ellipse/dist/cjs/index.cjs","sourcesContent":[null,"import {\n polygon,\n isObject,\n isNumber,\n Coord,\n Units,\n point,\n radiansToDegrees,\n} from \"@turf/helpers\";\nimport { destination } from \"@turf/destination\";\nimport { transformRotate } from \"@turf/transform-rotate\";\nimport { getCoord } from \"@turf/invariant\";\nimport { GeoJsonProperties, Feature, Polygon, Position } from \"geojson\";\n\n/**\n * Takes a {@link Point} and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision.\n *\n * @param {Coord} center center point\n * @param {number} xSemiAxis semi (major) axis of the ellipse along the x-axis\n * @param {number} ySemiAxis semi (minor) axis of the ellipse along the y-axis\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.angle=0] angle of rotation in decimal degrees, positive clockwise\n * @param {Coord} [options.pivot=center] point around which any rotation will be performed\n * @param {number} [options.steps=64] number of steps\n * @param {Units} [options.units='kilometers'] unit of measurement for axes. Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}\n * @param {Object} [options.properties={}] properties\n * @returns {Feature<Polygon>} ellipse polygon\n * @example\n * var center = [-75, 40];\n * var xSemiAxis = 5;\n * var ySemiAxis = 2;\n * var ellipse = turf.ellipse(center, xSemiAxis, ySemiAxis);\n *\n * //addToMap\n * var addToMap = [turf.point(center), ellipse]\n */\nfunction ellipse(\n center: Coord,\n xSemiAxis: number,\n ySemiAxis: number,\n options: {\n steps?: number;\n units?: Units;\n angle?: number;\n pivot?: Coord;\n properties?: GeoJsonProperties;\n }\n): Feature<Polygon> {\n // Optional params\n options = options || {};\n let steps = options.steps || 64;\n const units = options.units || \"kilometers\";\n let angle = options.angle || 0;\n const pivot = options.pivot || center;\n const properties = options.properties || {};\n // validation\n if (!center) throw new Error(\"center is required\");\n if (!xSemiAxis) throw new Error(\"xSemiAxis is required\");\n if (!ySemiAxis) throw new Error(\"ySemiAxis is required\");\n if (!isObject(options)) throw new Error(\"options must be an object\");\n if (!isNumber(steps)) throw new Error(\"steps must be a number\");\n if (!isNumber(angle)) throw new Error(\"angle must be a number\");\n\n const centerCoords = getCoord(\n transformRotate(point(getCoord(center)), angle, { pivot })\n );\n\n angle = -90 + angle;\n\n // Divide steps by 4 for one quadrant\n steps = Math.ceil(steps / 4);\n\n let quadrantParameters = [];\n let parameters = [];\n\n const a = xSemiAxis;\n const b = ySemiAxis;\n\n // Gradient x intersect\n const c = b;\n\n // Gradient of line\n const m = (a - b) / (Math.PI / 2);\n\n // Area under line\n const A = ((a + b) * Math.PI) / 4;\n\n // Weighting function\n const v = 0.5;\n\n const k = steps;\n\n let w = 0;\n let x = 0;\n\n for (let i = 0; i < steps; i++) {\n x += w;\n\n if (m === 0) {\n // It's a circle, so use simplified c*w - A/k == 0\n w = A / k / c;\n } else {\n // Otherwise, use full (v*m)*w^2 + (m*x+c)*w - A/k == 0\n // Solve as quadratic ax^2 + bx + c = 0\n w =\n (-(m * x + c) +\n Math.sqrt(Math.pow(m * x + c, 2) - 4 * (v * m) * -(A / k))) /\n (2 * (v * m));\n }\n if (x != 0) {\n // easier to add it later to avoid having twice the same point\n quadrantParameters.push(x);\n }\n }\n\n //NE\n parameters.push(0);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(quadrantParameters[i]);\n }\n //NW\n parameters.push(Math.PI / 2);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(\n Math.PI - quadrantParameters[quadrantParameters.length - i - 1]\n );\n }\n //SW\n parameters.push(Math.PI);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(Math.PI + quadrantParameters[i]);\n }\n //SE\n parameters.push((3 * Math.PI) / 2);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(\n 2 * Math.PI - quadrantParameters[quadrantParameters.length - i - 1]\n );\n }\n parameters.push(0);\n\n // We can now construct the ellipse\n const coords: Position[] = [];\n for (const param of parameters) {\n const theta = Math.atan2(b * Math.sin(param), a * Math.cos(param));\n const r = Math.sqrt(\n (Math.pow(a, 2) * Math.pow(b, 2)) /\n (Math.pow(a * Math.sin(theta), 2) + Math.pow(b * Math.cos(theta), 2))\n );\n coords.push(\n destination(centerCoords, r, angle + radiansToDegrees(theta), {\n units: units,\n }).geometry.coordinates\n );\n }\n return polygon([coords], properties);\n}\n\nexport { ellipse };\nexport default ellipse;\n"]}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -11,7 +11,7 @@ import { GeoJsonProperties, Feature, Polygon } from 'geojson';
|
|
|
11
11
|
* @param {number} [options.angle=0] angle of rotation in decimal degrees, positive clockwise
|
|
12
12
|
* @param {Coord} [options.pivot=center] point around which any rotation will be performed
|
|
13
13
|
* @param {number} [options.steps=64] number of steps
|
|
14
|
-
* @param {
|
|
14
|
+
* @param {Units} [options.units='kilometers'] unit of measurement for axes. Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}
|
|
15
15
|
* @param {Object} [options.properties={}] properties
|
|
16
16
|
* @returns {Feature<Polygon>} ellipse polygon
|
|
17
17
|
* @example
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { GeoJsonProperties, Feature, Polygon } from 'geojson';
|
|
|
11
11
|
* @param {number} [options.angle=0] angle of rotation in decimal degrees, positive clockwise
|
|
12
12
|
* @param {Coord} [options.pivot=center] point around which any rotation will be performed
|
|
13
13
|
* @param {number} [options.steps=64] number of steps
|
|
14
|
-
* @param {
|
|
14
|
+
* @param {Units} [options.units='kilometers'] unit of measurement for axes. Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}
|
|
15
15
|
* @param {Object} [options.properties={}] properties
|
|
16
16
|
* @returns {Feature<Polygon>} ellipse polygon
|
|
17
17
|
* @example
|
package/dist/esm/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
// index.ts
|
|
2
2
|
import {
|
|
3
|
-
degreesToRadians,
|
|
4
3
|
polygon,
|
|
5
4
|
isObject,
|
|
6
|
-
isNumber
|
|
5
|
+
isNumber,
|
|
6
|
+
point,
|
|
7
|
+
radiansToDegrees
|
|
7
8
|
} from "@turf/helpers";
|
|
8
|
-
import {
|
|
9
|
+
import { destination } from "@turf/destination";
|
|
9
10
|
import { transformRotate } from "@turf/transform-rotate";
|
|
10
11
|
import { getCoord } from "@turf/invariant";
|
|
11
12
|
function ellipse(center, xSemiAxis, ySemiAxis, options) {
|
|
12
13
|
options = options || {};
|
|
13
|
-
|
|
14
|
+
let steps = options.steps || 64;
|
|
14
15
|
const units = options.units || "kilometers";
|
|
15
|
-
|
|
16
|
+
let angle = options.angle || 0;
|
|
16
17
|
const pivot = options.pivot || center;
|
|
17
18
|
const properties = options.properties || {};
|
|
18
19
|
if (!center) throw new Error("center is required");
|
|
@@ -21,49 +22,71 @@ function ellipse(center, xSemiAxis, ySemiAxis, options) {
|
|
|
21
22
|
if (!isObject(options)) throw new Error("options must be an object");
|
|
22
23
|
if (!isNumber(steps)) throw new Error("steps must be a number");
|
|
23
24
|
if (!isNumber(angle)) throw new Error("angle must be a number");
|
|
24
|
-
const centerCoords = getCoord(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const centerCoords = getCoord(
|
|
26
|
+
transformRotate(point(getCoord(center)), angle, { pivot })
|
|
27
|
+
);
|
|
28
|
+
angle = -90 + angle;
|
|
29
|
+
steps = Math.ceil(steps / 4);
|
|
30
|
+
let quadrantParameters = [];
|
|
31
|
+
let parameters = [];
|
|
32
|
+
const a = xSemiAxis;
|
|
33
|
+
const b = ySemiAxis;
|
|
34
|
+
const c = b;
|
|
35
|
+
const m = (a - b) / (Math.PI / 2);
|
|
36
|
+
const A = (a + b) * Math.PI / 4;
|
|
37
|
+
const v = 0.5;
|
|
38
|
+
const k = steps;
|
|
39
|
+
let w = 0;
|
|
40
|
+
let x = 0;
|
|
41
|
+
for (let i = 0; i < steps; i++) {
|
|
42
|
+
x += w;
|
|
43
|
+
if (m === 0) {
|
|
44
|
+
w = A / k / c;
|
|
45
|
+
} else {
|
|
46
|
+
w = (-(m * x + c) + Math.sqrt(Math.pow(m * x + c, 2) - 4 * (v * m) * -(A / k))) / (2 * (v * m));
|
|
47
|
+
}
|
|
48
|
+
if (x != 0) {
|
|
49
|
+
quadrantParameters.push(x);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
parameters.push(0);
|
|
53
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
54
|
+
parameters.push(quadrantParameters[i]);
|
|
30
55
|
}
|
|
31
|
-
|
|
32
|
-
for (let i = 0; i <
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Math.pow(ySemiAxis, 2) + Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)
|
|
56
|
+
parameters.push(Math.PI / 2);
|
|
57
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
58
|
+
parameters.push(
|
|
59
|
+
Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
|
|
36
60
|
);
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
}
|
|
62
|
+
parameters.push(Math.PI);
|
|
63
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
64
|
+
parameters.push(Math.PI + quadrantParameters[i]);
|
|
65
|
+
}
|
|
66
|
+
parameters.push(3 * Math.PI / 2);
|
|
67
|
+
for (let i = 0; i < quadrantParameters.length; i++) {
|
|
68
|
+
parameters.push(
|
|
69
|
+
2 * Math.PI - quadrantParameters[quadrantParameters.length - i - 1]
|
|
39
70
|
);
|
|
40
|
-
if (stepAngle < -90 && stepAngle >= -270) x = -x;
|
|
41
|
-
if (stepAngle < -180 && stepAngle >= -360) y = -y;
|
|
42
|
-
if (units === "degrees") {
|
|
43
|
-
const angleRad = degreesToRadians(angle);
|
|
44
|
-
const newx = x * Math.cos(angleRad) + y * Math.sin(angleRad);
|
|
45
|
-
const newy = y * Math.cos(angleRad) - x * Math.sin(angleRad);
|
|
46
|
-
x = newx;
|
|
47
|
-
y = newy;
|
|
48
|
-
}
|
|
49
|
-
coordinates.push([x + centerCoords[0], y + centerCoords[1]]);
|
|
50
71
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
parameters.push(0);
|
|
73
|
+
const coords = [];
|
|
74
|
+
for (const param of parameters) {
|
|
75
|
+
const theta = Math.atan2(b * Math.sin(param), a * Math.cos(param));
|
|
76
|
+
const r = Math.sqrt(
|
|
77
|
+
Math.pow(a, 2) * Math.pow(b, 2) / (Math.pow(a * Math.sin(theta), 2) + Math.pow(b * Math.cos(theta), 2))
|
|
78
|
+
);
|
|
79
|
+
coords.push(
|
|
80
|
+
destination(centerCoords, r, angle + radiansToDegrees(theta), {
|
|
81
|
+
units
|
|
82
|
+
}).geometry.coordinates
|
|
83
|
+
);
|
|
58
84
|
}
|
|
85
|
+
return polygon([coords], properties);
|
|
59
86
|
}
|
|
60
|
-
|
|
61
|
-
const rad = deg * Math.PI / 180;
|
|
62
|
-
return Math.tan(rad);
|
|
63
|
-
}
|
|
64
|
-
var turf_ellipse_default = ellipse;
|
|
87
|
+
var index_default = ellipse;
|
|
65
88
|
export {
|
|
66
|
-
|
|
89
|
+
index_default as default,
|
|
67
90
|
ellipse
|
|
68
91
|
};
|
|
69
92
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../index.ts"],"sourcesContent":["import {\n
|
|
1
|
+
{"version":3,"sources":["../../index.ts"],"sourcesContent":["import {\n polygon,\n isObject,\n isNumber,\n Coord,\n Units,\n point,\n radiansToDegrees,\n} from \"@turf/helpers\";\nimport { destination } from \"@turf/destination\";\nimport { transformRotate } from \"@turf/transform-rotate\";\nimport { getCoord } from \"@turf/invariant\";\nimport { GeoJsonProperties, Feature, Polygon, Position } from \"geojson\";\n\n/**\n * Takes a {@link Point} and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision.\n *\n * @param {Coord} center center point\n * @param {number} xSemiAxis semi (major) axis of the ellipse along the x-axis\n * @param {number} ySemiAxis semi (minor) axis of the ellipse along the y-axis\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.angle=0] angle of rotation in decimal degrees, positive clockwise\n * @param {Coord} [options.pivot=center] point around which any rotation will be performed\n * @param {number} [options.steps=64] number of steps\n * @param {Units} [options.units='kilometers'] unit of measurement for axes. Supports all valid Turf {@link https://turfjs.org/docs/api/types/Units Units}\n * @param {Object} [options.properties={}] properties\n * @returns {Feature<Polygon>} ellipse polygon\n * @example\n * var center = [-75, 40];\n * var xSemiAxis = 5;\n * var ySemiAxis = 2;\n * var ellipse = turf.ellipse(center, xSemiAxis, ySemiAxis);\n *\n * //addToMap\n * var addToMap = [turf.point(center), ellipse]\n */\nfunction ellipse(\n center: Coord,\n xSemiAxis: number,\n ySemiAxis: number,\n options: {\n steps?: number;\n units?: Units;\n angle?: number;\n pivot?: Coord;\n properties?: GeoJsonProperties;\n }\n): Feature<Polygon> {\n // Optional params\n options = options || {};\n let steps = options.steps || 64;\n const units = options.units || \"kilometers\";\n let angle = options.angle || 0;\n const pivot = options.pivot || center;\n const properties = options.properties || {};\n // validation\n if (!center) throw new Error(\"center is required\");\n if (!xSemiAxis) throw new Error(\"xSemiAxis is required\");\n if (!ySemiAxis) throw new Error(\"ySemiAxis is required\");\n if (!isObject(options)) throw new Error(\"options must be an object\");\n if (!isNumber(steps)) throw new Error(\"steps must be a number\");\n if (!isNumber(angle)) throw new Error(\"angle must be a number\");\n\n const centerCoords = getCoord(\n transformRotate(point(getCoord(center)), angle, { pivot })\n );\n\n angle = -90 + angle;\n\n // Divide steps by 4 for one quadrant\n steps = Math.ceil(steps / 4);\n\n let quadrantParameters = [];\n let parameters = [];\n\n const a = xSemiAxis;\n const b = ySemiAxis;\n\n // Gradient x intersect\n const c = b;\n\n // Gradient of line\n const m = (a - b) / (Math.PI / 2);\n\n // Area under line\n const A = ((a + b) * Math.PI) / 4;\n\n // Weighting function\n const v = 0.5;\n\n const k = steps;\n\n let w = 0;\n let x = 0;\n\n for (let i = 0; i < steps; i++) {\n x += w;\n\n if (m === 0) {\n // It's a circle, so use simplified c*w - A/k == 0\n w = A / k / c;\n } else {\n // Otherwise, use full (v*m)*w^2 + (m*x+c)*w - A/k == 0\n // Solve as quadratic ax^2 + bx + c = 0\n w =\n (-(m * x + c) +\n Math.sqrt(Math.pow(m * x + c, 2) - 4 * (v * m) * -(A / k))) /\n (2 * (v * m));\n }\n if (x != 0) {\n // easier to add it later to avoid having twice the same point\n quadrantParameters.push(x);\n }\n }\n\n //NE\n parameters.push(0);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(quadrantParameters[i]);\n }\n //NW\n parameters.push(Math.PI / 2);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(\n Math.PI - quadrantParameters[quadrantParameters.length - i - 1]\n );\n }\n //SW\n parameters.push(Math.PI);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(Math.PI + quadrantParameters[i]);\n }\n //SE\n parameters.push((3 * Math.PI) / 2);\n for (let i = 0; i < quadrantParameters.length; i++) {\n parameters.push(\n 2 * Math.PI - quadrantParameters[quadrantParameters.length - i - 1]\n );\n }\n parameters.push(0);\n\n // We can now construct the ellipse\n const coords: Position[] = [];\n for (const param of parameters) {\n const theta = Math.atan2(b * Math.sin(param), a * Math.cos(param));\n const r = Math.sqrt(\n (Math.pow(a, 2) * Math.pow(b, 2)) /\n (Math.pow(a * Math.sin(theta), 2) + Math.pow(b * Math.cos(theta), 2))\n );\n coords.push(\n destination(centerCoords, r, angle + radiansToDegrees(theta), {\n units: units,\n }).geometry.coordinates\n );\n }\n return polygon([coords], properties);\n}\n\nexport { ellipse };\nexport default ellipse;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turf/ellipse",
|
|
3
|
-
"version": "7.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "7.3.1",
|
|
4
|
+
"description": "Takes a Point and calculates the ellipse polygon given two semi-axes expressed in variable units and steps for precision.",
|
|
5
5
|
"author": "Turf Authors",
|
|
6
6
|
"contributors": [
|
|
7
|
-
"Moacir P. de Sá Pereira <@muziejus>"
|
|
7
|
+
"Moacir P. de Sá Pereira <@muziejus>",
|
|
8
|
+
"Pavel Rozvora <@prozvora>"
|
|
8
9
|
],
|
|
9
10
|
"license": "MIT",
|
|
10
11
|
"bugs": {
|
|
@@ -48,34 +49,35 @@
|
|
|
48
49
|
"bench": "tsx bench.ts",
|
|
49
50
|
"build": "tsup --config ../../tsup.config.ts",
|
|
50
51
|
"docs": "tsx ../../scripts/generate-readmes.ts",
|
|
51
|
-
"test": "
|
|
52
|
+
"test": "pnpm run /test:.*/",
|
|
52
53
|
"test:tape": "tsx test.ts"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@placemarkio/check-geojson": "^0.1.12",
|
|
56
|
-
"@turf/
|
|
57
|
-
"@turf/
|
|
58
|
-
"@turf/
|
|
59
|
-
"@turf/
|
|
57
|
+
"@turf/area": "7.3.1",
|
|
58
|
+
"@turf/bbox-polygon": "7.3.1",
|
|
59
|
+
"@turf/circle": "7.3.1",
|
|
60
|
+
"@turf/intersect": "7.3.1",
|
|
61
|
+
"@turf/truncate": "7.3.1",
|
|
60
62
|
"@types/benchmark": "^2.1.5",
|
|
61
|
-
"@types/tape": "^
|
|
63
|
+
"@types/tape": "^5.8.1",
|
|
62
64
|
"benchmark": "^2.1.4",
|
|
63
|
-
"glob": "^
|
|
65
|
+
"glob": "^11.1.0",
|
|
64
66
|
"load-json-file": "^7.0.1",
|
|
65
|
-
"npm-run-all": "^4.1.5",
|
|
66
67
|
"tape": "^5.9.0",
|
|
67
|
-
"tsup": "^8.
|
|
68
|
-
"tsx": "^4.19.
|
|
69
|
-
"typescript": "^5.
|
|
70
|
-
"write-json-file": "^
|
|
68
|
+
"tsup": "^8.4.0",
|
|
69
|
+
"tsx": "^4.19.4",
|
|
70
|
+
"typescript": "^5.8.3",
|
|
71
|
+
"write-json-file": "^6.0.0"
|
|
71
72
|
},
|
|
72
73
|
"dependencies": {
|
|
73
|
-
"@turf/
|
|
74
|
-
"@turf/
|
|
75
|
-
"@turf/
|
|
76
|
-
"@turf/
|
|
74
|
+
"@turf/destination": "7.3.1",
|
|
75
|
+
"@turf/distance": "7.3.1",
|
|
76
|
+
"@turf/helpers": "7.3.1",
|
|
77
|
+
"@turf/invariant": "7.3.1",
|
|
78
|
+
"@turf/transform-rotate": "7.3.1",
|
|
77
79
|
"@types/geojson": "^7946.0.10",
|
|
78
80
|
"tslib": "^2.8.1"
|
|
79
81
|
},
|
|
80
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "b7f1b4eafb760431e03955499d8eac9489438219"
|
|
81
83
|
}
|