@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 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` **[string][5]** unit of measurement for axes (optional, default `'kilometers'`)
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://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
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
 
@@ -4,15 +4,16 @@
4
4
 
5
5
 
6
6
 
7
+
7
8
  var _helpers = require('@turf/helpers');
8
- var _rhumbdestination = require('@turf/rhumb-destination');
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
- const steps = options.steps || 64;
14
+ let steps = options.steps || 64;
14
15
  const units = options.units || "kilometers";
15
- const angle = options.angle || 0;
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, center);
25
- if (units !== "degrees") {
26
- const xDest = _rhumbdestination.rhumbDestination.call(void 0, center, xSemiAxis, 90, { units });
27
- const yDest = _rhumbdestination.rhumbDestination.call(void 0, center, ySemiAxis, 0, { units });
28
- xSemiAxis = _invariant.getCoord.call(void 0, xDest)[0] - centerCoords[0];
29
- ySemiAxis = _invariant.getCoord.call(void 0, yDest)[1] - centerCoords[1];
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
- const coordinates = [];
32
- for (let i = 0; i < steps; i += 1) {
33
- const stepAngle = i * -360 / steps;
34
- let x = xSemiAxis * ySemiAxis / Math.sqrt(
35
- Math.pow(ySemiAxis, 2) + Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)
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
- let y = xSemiAxis * ySemiAxis / Math.sqrt(
38
- Math.pow(xSemiAxis, 2) + Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)
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
- coordinates.push(coordinates[0]);
52
- if (units === "degrees") {
53
- return _helpers.polygon.call(void 0, [coordinates], properties);
54
- } else {
55
- return _transformrotate.transformRotate.call(void 0, _helpers.polygon.call(void 0, [coordinates], properties), angle, {
56
- pivot
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
- function getTanDeg(deg) {
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 = turf_ellipse_default; exports.ellipse = ellipse;
91
+ exports.default = index_default; exports.ellipse = ellipse;
69
92
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
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 degreesToRadians,\n polygon,\n isObject,\n isNumber,\n Coord,\n Units,\n} from \"@turf/helpers\";\nimport { rhumbDestination } from \"@turf/rhumb-destination\";\nimport { transformRotate } from \"@turf/transform-rotate\";\nimport { getCoord } from \"@turf/invariant\";\nimport { GeoJsonProperties, Feature, Polygon } 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 {string} [options.units='kilometers'] unit of measurement for axes\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 const steps = options.steps || 64;\n const units = options.units || \"kilometers\";\n const angle = options.angle || 0;\n const pivot = options.pivot || center;\n const properties = options.properties || {};\n\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(center);\n if (units !== \"degrees\") {\n const xDest = rhumbDestination(center, xSemiAxis, 90, { units });\n const yDest = rhumbDestination(center, ySemiAxis, 0, { units });\n xSemiAxis = getCoord(xDest)[0] - centerCoords[0];\n ySemiAxis = getCoord(yDest)[1] - centerCoords[1];\n }\n\n const coordinates: number[][] = [];\n for (let i = 0; i < steps; i += 1) {\n const stepAngle = (i * -360) / steps;\n let x =\n (xSemiAxis * ySemiAxis) /\n Math.sqrt(\n Math.pow(ySemiAxis, 2) +\n Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)\n );\n let y =\n (xSemiAxis * ySemiAxis) /\n Math.sqrt(\n Math.pow(xSemiAxis, 2) +\n Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)\n );\n\n if (stepAngle < -90 && stepAngle >= -270) x = -x;\n if (stepAngle < -180 && stepAngle >= -360) y = -y;\n if (units === \"degrees\") {\n const angleRad = degreesToRadians(angle);\n const newx = x * Math.cos(angleRad) + y * Math.sin(angleRad);\n const newy = y * Math.cos(angleRad) - x * Math.sin(angleRad);\n x = newx;\n y = newy;\n }\n\n coordinates.push([x + centerCoords[0], y + centerCoords[1]]);\n }\n coordinates.push(coordinates[0]);\n if (units === \"degrees\") {\n return polygon([coordinates], properties);\n } else {\n return transformRotate(polygon([coordinates], properties), angle, {\n pivot,\n });\n }\n}\n\n/**\n * Get Tan Degrees\n *\n * @private\n * @param {number} deg Degrees\n * @returns {number} Tan Degrees\n */\nfunction getTanDeg(deg: number) {\n const rad = (deg * Math.PI) / 180;\n return Math.tan(rad);\n}\n\nexport { ellipse };\nexport default ellipse;\n"]}
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"]}
@@ -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 {string} [options.units='kilometers'] unit of measurement for axes
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
@@ -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 {string} [options.units='kilometers'] unit of measurement for axes
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 { rhumbDestination } from "@turf/rhumb-destination";
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
- const steps = options.steps || 64;
14
+ let steps = options.steps || 64;
14
15
  const units = options.units || "kilometers";
15
- const angle = options.angle || 0;
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(center);
25
- if (units !== "degrees") {
26
- const xDest = rhumbDestination(center, xSemiAxis, 90, { units });
27
- const yDest = rhumbDestination(center, ySemiAxis, 0, { units });
28
- xSemiAxis = getCoord(xDest)[0] - centerCoords[0];
29
- ySemiAxis = getCoord(yDest)[1] - centerCoords[1];
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
- const coordinates = [];
32
- for (let i = 0; i < steps; i += 1) {
33
- const stepAngle = i * -360 / steps;
34
- let x = xSemiAxis * ySemiAxis / Math.sqrt(
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
- let y = xSemiAxis * ySemiAxis / Math.sqrt(
38
- Math.pow(xSemiAxis, 2) + Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)
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
- coordinates.push(coordinates[0]);
52
- if (units === "degrees") {
53
- return polygon([coordinates], properties);
54
- } else {
55
- return transformRotate(polygon([coordinates], properties), angle, {
56
- pivot
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
- function getTanDeg(deg) {
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
- turf_ellipse_default as default,
89
+ index_default as default,
67
90
  ellipse
68
91
  };
69
92
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts"],"sourcesContent":["import {\n degreesToRadians,\n polygon,\n isObject,\n isNumber,\n Coord,\n Units,\n} from \"@turf/helpers\";\nimport { rhumbDestination } from \"@turf/rhumb-destination\";\nimport { transformRotate } from \"@turf/transform-rotate\";\nimport { getCoord } from \"@turf/invariant\";\nimport { GeoJsonProperties, Feature, Polygon } 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 {string} [options.units='kilometers'] unit of measurement for axes\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 const steps = options.steps || 64;\n const units = options.units || \"kilometers\";\n const angle = options.angle || 0;\n const pivot = options.pivot || center;\n const properties = options.properties || {};\n\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(center);\n if (units !== \"degrees\") {\n const xDest = rhumbDestination(center, xSemiAxis, 90, { units });\n const yDest = rhumbDestination(center, ySemiAxis, 0, { units });\n xSemiAxis = getCoord(xDest)[0] - centerCoords[0];\n ySemiAxis = getCoord(yDest)[1] - centerCoords[1];\n }\n\n const coordinates: number[][] = [];\n for (let i = 0; i < steps; i += 1) {\n const stepAngle = (i * -360) / steps;\n let x =\n (xSemiAxis * ySemiAxis) /\n Math.sqrt(\n Math.pow(ySemiAxis, 2) +\n Math.pow(xSemiAxis, 2) * Math.pow(getTanDeg(stepAngle), 2)\n );\n let y =\n (xSemiAxis * ySemiAxis) /\n Math.sqrt(\n Math.pow(xSemiAxis, 2) +\n Math.pow(ySemiAxis, 2) / Math.pow(getTanDeg(stepAngle), 2)\n );\n\n if (stepAngle < -90 && stepAngle >= -270) x = -x;\n if (stepAngle < -180 && stepAngle >= -360) y = -y;\n if (units === \"degrees\") {\n const angleRad = degreesToRadians(angle);\n const newx = x * Math.cos(angleRad) + y * Math.sin(angleRad);\n const newy = y * Math.cos(angleRad) - x * Math.sin(angleRad);\n x = newx;\n y = newy;\n }\n\n coordinates.push([x + centerCoords[0], y + centerCoords[1]]);\n }\n coordinates.push(coordinates[0]);\n if (units === \"degrees\") {\n return polygon([coordinates], properties);\n } else {\n return transformRotate(polygon([coordinates], properties), angle, {\n pivot,\n });\n }\n}\n\n/**\n * Get Tan Degrees\n *\n * @private\n * @param {number} deg Degrees\n * @returns {number} Tan Degrees\n */\nfunction getTanDeg(deg: number) {\n const rad = (deg * Math.PI) / 180;\n return Math.tan(rad);\n}\n\nexport { ellipse };\nexport default ellipse;\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,gBAAgB;AAyBzB,SAAS,QACP,QACA,WACA,WACA,SAOkB;AAElB,YAAU,WAAW,CAAC;AACtB,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,aAAa,QAAQ,cAAc,CAAC;AAG1C,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,oBAAoB;AACjD,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,uBAAuB;AACvD,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,uBAAuB;AACvD,MAAI,CAAC,SAAS,OAAO,EAAG,OAAM,IAAI,MAAM,2BAA2B;AACnE,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,MAAM,wBAAwB;AAC9D,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,MAAM,wBAAwB;AAE9D,QAAM,eAAe,SAAS,MAAM;AACpC,MAAI,UAAU,WAAW;AACvB,UAAM,QAAQ,iBAAiB,QAAQ,WAAW,IAAI,EAAE,MAAM,CAAC;AAC/D,UAAM,QAAQ,iBAAiB,QAAQ,WAAW,GAAG,EAAE,MAAM,CAAC;AAC9D,gBAAY,SAAS,KAAK,EAAE,CAAC,IAAI,aAAa,CAAC;AAC/C,gBAAY,SAAS,KAAK,EAAE,CAAC,IAAI,aAAa,CAAC;AAAA,EACjD;AAEA,QAAM,cAA0B,CAAC;AACjC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK,GAAG;AACjC,UAAM,YAAa,IAAI,OAAQ;AAC/B,QAAI,IACD,YAAY,YACb,KAAK;AAAA,MACH,KAAK,IAAI,WAAW,CAAC,IACnB,KAAK,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,UAAU,SAAS,GAAG,CAAC;AAAA,IAC7D;AACF,QAAI,IACD,YAAY,YACb,KAAK;AAAA,MACH,KAAK,IAAI,WAAW,CAAC,IACnB,KAAK,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,UAAU,SAAS,GAAG,CAAC;AAAA,IAC7D;AAEF,QAAI,YAAY,OAAO,aAAa,KAAM,KAAI,CAAC;AAC/C,QAAI,YAAY,QAAQ,aAAa,KAAM,KAAI,CAAC;AAChD,QAAI,UAAU,WAAW;AACvB,YAAM,WAAW,iBAAiB,KAAK;AACvC,YAAM,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,IAAI,KAAK,IAAI,QAAQ;AAC3D,YAAM,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,IAAI,KAAK,IAAI,QAAQ;AAC3D,UAAI;AACJ,UAAI;AAAA,IACN;AAEA,gBAAY,KAAK,CAAC,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC;AAAA,EAC7D;AACA,cAAY,KAAK,YAAY,CAAC,CAAC;AAC/B,MAAI,UAAU,WAAW;AACvB,WAAO,QAAQ,CAAC,WAAW,GAAG,UAAU;AAAA,EAC1C,OAAO;AACL,WAAO,gBAAgB,QAAQ,CAAC,WAAW,GAAG,UAAU,GAAG,OAAO;AAAA,MAChE;AAAA,IACF,CAAC;AAAA,EACH;AACF;AASA,SAAS,UAAU,KAAa;AAC9B,QAAM,MAAO,MAAM,KAAK,KAAM;AAC9B,SAAO,KAAK,IAAI,GAAG;AACrB;AAGA,IAAO,uBAAQ;","names":[]}
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.2.0",
4
- "description": "turf ellipse module",
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": "npm-run-all --npm-path npm 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/bbox-polygon": "^7.2.0",
57
- "@turf/circle": "^7.2.0",
58
- "@turf/destination": "^7.2.0",
59
- "@turf/truncate": "^7.2.0",
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": "^4.13.4",
63
+ "@types/tape": "^5.8.1",
62
64
  "benchmark": "^2.1.4",
63
- "glob": "^10.3.10",
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.3.5",
68
- "tsx": "^4.19.2",
69
- "typescript": "^5.5.4",
70
- "write-json-file": "^5.0.0"
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/helpers": "^7.2.0",
74
- "@turf/invariant": "^7.2.0",
75
- "@turf/rhumb-destination": "^7.2.0",
76
- "@turf/transform-rotate": "^7.2.0",
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": "7b0f0374c4668cd569f8904c71e2ae7d941be867"
82
+ "gitHead": "b7f1b4eafb760431e03955499d8eac9489438219"
81
83
  }