Skip to content

Commit

Permalink
updates [turf-ellipse] the distribution of points along the circumfer…
Browse files Browse the repository at this point in the history
…ence is now optional. The default value for accuracy (0) leads to the same result as previously. Using custom values for accuracy will distribute points along the circumference (which is more precise for "thin" ellipses, but more expensive).
  • Loading branch information
hadbn committed Nov 4, 2024
1 parent cad1832 commit f4ed1c5
Show file tree
Hide file tree
Showing 10 changed files with 1,145 additions and 1,130 deletions.
72 changes: 40 additions & 32 deletions packages/turf-ellipse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function ellipse(
const angle = options.angle || 0;
const pivot = options.pivot || center;
const properties = options.properties || {};
const accuracy = options.accuracy || 3;
const accuracy = options.accuracy === undefined ? 0 : options.accuracy;
// validation
if (!center) throw new Error("center is required");
if (!xSemiAxis) throw new Error("xSemiAxis is required");
Expand All @@ -65,6 +65,10 @@ function ellipse(
if (!isNumber(steps)) throw new Error("steps must be a number");
if (!isNumber(angle)) throw new Error("angle must be a number");
if (!isNumber(accuracy)) throw new Error("accuracy must be a number");
if (accuracy !== 0 && accuracy < 1)
throw new Error(
"accuracy must either be equal to -1 or greater or equal to 1"
);

const internalSteps = Math.floor(Math.pow(accuracy, 2) * steps);

Expand All @@ -89,43 +93,47 @@ function ellipse(
let previousCoords = currentCoords;
const cumulatedArcLength = [0];
const cumulatedAngle = [0];

for (let i = 1; i < internalSteps + 1; i += 1) {
previousCoords = currentCoords;
currentAngle = (360 * i) / internalSteps;
r = Math.sqrt(
(Math.pow(xSemiAxis, 2) * Math.pow(ySemiAxis, 2)) /
(Math.pow(
xSemiAxis * Math.cos(degreesToRadians(currentAngle - angle)),
2
) +
Math.pow(
ySemiAxis * Math.sin(degreesToRadians(currentAngle - angle)),
let circumference = 0;
if (accuracy != 0) {
for (let i = 1; i < internalSteps + 1; i += 1) {
previousCoords = currentCoords;
currentAngle = (360 * i) / internalSteps;
r = Math.sqrt(
(Math.pow(xSemiAxis, 2) * Math.pow(ySemiAxis, 2)) /
(Math.pow(
xSemiAxis * Math.cos(degreesToRadians(currentAngle - angle)),
2
))
);
currentCoords = getCoord(
destination(centerCoords, r, currentAngle, { units: units })
);
currentArcLength += distance(previousCoords, currentCoords);
cumulatedAngle.push(currentAngle);
cumulatedArcLength.push(currentArcLength);
) +
Math.pow(
ySemiAxis * Math.sin(degreesToRadians(currentAngle - angle)),
2
))
);
currentCoords = getCoord(
destination(centerCoords, r, currentAngle, { units: units })
);
currentArcLength += distance(previousCoords, currentCoords);
cumulatedAngle.push(currentAngle);
cumulatedArcLength.push(currentArcLength);
}
circumference = cumulatedArcLength[cumulatedArcLength.length - 1];
}
const circumference = cumulatedArcLength[cumulatedArcLength.length - 1];

let j = 0;
for (let i = 1; i < steps; i += 1) {
const targetArcLength = (i * circumference) / steps;
while (cumulatedArcLength[j] < targetArcLength) {
j += 1;
let angleNewPoint = (360 * i) / steps;
if (accuracy != 0) {
const targetArcLength = (i * circumference) / steps;
while (cumulatedArcLength[j] < targetArcLength) {
j += 1;
}
const ratio =
(targetArcLength - cumulatedArcLength[j - 1]) /
(cumulatedArcLength[j] - cumulatedArcLength[j - 1]);
angleNewPoint =
cumulatedAngle[j - 1] +
ratio * (cumulatedAngle[j] - cumulatedAngle[j - 1]);
}
const ratio =
(targetArcLength - cumulatedArcLength[j - 1]) /
(cumulatedArcLength[j] - cumulatedArcLength[j - 1]);
const angleNewPoint =
cumulatedAngle[j - 1] +
ratio * (cumulatedAngle[j] - cumulatedAngle[j - 1]);

r = Math.sqrt(
(Math.pow(xSemiAxis, 2) * Math.pow(ySemiAxis, 2)) /
(Math.pow(
Expand Down
11 changes: 9 additions & 2 deletions packages/turf-ellipse/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ test("turf-ellipse", (t) => {
const name = fixture.name;
const geojson = fixture.geojson;
const center = geojson.geometry.coordinates;
let { xSemiAxis, ySemiAxis, steps, angle, units } = geojson.properties;
let { xSemiAxis, ySemiAxis, steps, angle, units, accuracy } =
geojson.properties;
angle = angle || 0;
const options = { steps, angle, units };
const options = {
steps: steps,
angle: angle,
units: units,
accuracy: accuracy,
};
const maxAxis = Math.max(xSemiAxis, ySemiAxis);

const results = featureCollection([
Expand All @@ -51,6 +57,7 @@ test("turf-ellipse", (t) => {
steps,
angle: angle + 90,
units,
accuracy: accuracy,
}),
"#0F0"
)
Expand Down
240 changes: 120 additions & 120 deletions packages/turf-ellipse/test/out/anti-meridian-degrees.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,69 +107,69 @@
"coordinates": [
[
[-180, -7],
[-176.738849, -6.999277],
[-173.477813, -6.997315],
[-170.216821, -6.994743],
[-166.95618, -6.992655],
[-163.69532, -6.992682],
[-160.434971, -6.997114],
[-157.1736, -7.009093],
[-153.912019, -7.03292],
[-150.651306, -7.074538],
[-147.389796, -7.142453],
[-144.129317, -7.24924],
[-140.869431, -7.41491],
[-137.612939, -7.674292],
[-134.370698, -8.097871],
[-131.193938, -8.873656],
[-179.012909, -6.999932],
[-178.007657, -6.999726],
[-176.964769, -6.999372],
[-175.861944, -6.998853],
[-174.672095, -6.998147],
[-173.36058, -6.997228],
[-171.881019, -6.996076],
[-170.168666, -6.994705],
[-168.12949, -6.993261],
[-165.621642, -6.992297],
[-162.42371, -6.993735],
[-158.183237, -7.004346],
[-152.358412, -7.050082],
[-144.326578, -7.241357],
[-134.633424, -8.05423],
[-128.744776, -10.832176],
[-130.085087, -13.650444],
[-132.686206, -15.685771],
[-135.569995, -17.374365],
[-138.601438, -18.853757],
[-141.736897, -20.175837],
[-144.956526, -21.3648],
[-148.250042, -22.433239],
[-151.607646, -23.386802],
[-155.024266, -24.22889],
[-158.492384, -24.960237],
[-162.004653, -25.580714],
[-165.555992, -26.090075],
[-169.138528, -26.487393],
[-172.745429, -26.771923],
[-176.368571, -26.94294],
[-132.913393, -15.833284],
[-141.929439, -20.251391],
[-150.000227, -22.946517],
[-156.092677, -24.46711],
[-160.62983, -25.351901],
[-164.098361, -25.895108],
[-166.841894, -26.24599],
[-169.085426, -26.482344],
[-170.976743, -26.646744],
[-172.615433, -26.763657],
[-174.070866, -26.847757],
[-175.393155, -26.908141],
[-176.619973, -26.950571],
[-177.78092, -26.9787],
[-178.900458, -26.994771],
[-180, -27],
[-183.631429, -26.94294],
[-187.254571, -26.771923],
[-190.861472, -26.487393],
[-194.444008, -26.090075],
[-197.995347, -25.580714],
[-201.507616, -24.960237],
[-204.975734, -24.22889],
[-208.392354, -23.386802],
[-211.749958, -22.433239],
[-215.043474, -21.3648],
[-218.263103, -20.175837],
[-221.398562, -18.853757],
[-224.430005, -17.374365],
[-227.313794, -15.685771],
[-229.914913, -13.650444],
[-181.099542, -26.994771],
[-182.21908, -26.9787],
[-183.380027, -26.950571],
[-184.606845, -26.908141],
[-185.929134, -26.847757],
[-187.384567, -26.763657],
[-189.023257, -26.646744],
[-190.914574, -26.482344],
[-193.158106, -26.24599],
[-195.901639, -25.895108],
[-199.37017, -25.351901],
[-203.907323, -24.46711],
[-209.999773, -22.946517],
[-218.070561, -20.251391],
[-227.086607, -15.833284],
[-231.255224, -10.832176],
[-228.806062, -8.873656],
[-225.629302, -8.097871],
[-222.387061, -7.674292],
[-219.130569, -7.41491],
[-215.870683, -7.24924],
[-212.610204, -7.142453],
[-209.348694, -7.074538],
[-206.087981, -7.03292],
[-202.8264, -7.009093],
[-199.565029, -6.997114],
[-196.30468, -6.992682],
[-193.04382, -6.992655],
[-189.783179, -6.994743],
[-186.522187, -6.997315],
[-183.261151, -6.999277],
[-225.366576, -8.05423],
[-215.673422, -7.241357],
[-207.641588, -7.050082],
[-201.816763, -7.004346],
[-197.57629, -6.993735],
[-194.378358, -6.992297],
[-191.87051, -6.993261],
[-189.831334, -6.994705],
[-188.118981, -6.996076],
[-186.63942, -6.997228],
[-185.327905, -6.998147],
[-184.138056, -6.998853],
[-183.035231, -6.999372],
[-181.992343, -6.999726],
[-180.987091, -6.999932],
[-180, -7]
]
]
Expand All @@ -188,69 +188,69 @@
"coordinates": [
[
[-180, 33],
[-177.140393, 31.055266],
[-175.597566, 28.11005],
[-174.534874, 25.013207],
[-173.72227, 21.861462],
[-173.066567, 18.682944],
[-172.519156, 15.488953],
[-172.050878, 12.283875],
[-171.64316, 9.072469],
[-171.282867, 5.855031],
[-170.960895, 2.633936],
[-170.670524, -0.589097],
[-170.406554, -3.814932],
[-170.165253, -7.042382],
[-169.943765, -10.271676],
[-169.740098, -13.502271],
[-175.497882, 27.861418],
[-173.030729, 18.490068],
[-171.830809, 10.60333],
[-171.179456, 4.858227],
[-170.780383, 0.668263],
[-170.511657, -2.494484],
[-170.317281, -4.976107],
[-170.168666, -6.994705],
[-170.049885, -8.690233],
[-169.951409, -10.15556],
[-169.867192, -11.454674],
[-169.7932, -12.633439],
[-169.726611, -13.726124],
[-169.665366, -14.759536],
[-169.607893, -15.755753],
[-169.55293, -16.734064],
[-169.381609, -19.966817],
[-169.226157, -23.200324],
[-169.087344, -26.434579],
[-168.966868, -29.669207],
[-168.867575, -32.904694],
[-168.79396, -36.140205],
[-168.752764, -39.377096],
[-168.754199, -42.614301],
[-168.813714, -45.850315],
[-168.955371, -49.086046],
[-169.217769, -52.318336],
[-169.666488, -55.545023],
[-170.421106, -58.757802],
[-171.726422, -61.932319],
[-174.201492, -64.97435],
[-169.499415, -17.712463],
[-169.446396, -18.70895],
[-169.39297, -19.742835],
[-169.338231, -20.836238],
[-169.281216, -22.016028],
[-169.220871, -23.316582],
[-169.156026, -24.783931],
[-169.085426, -26.482344],
[-169.007959, -28.505179],
[-168.923458, -30.993289],
[-168.835498, -34.16656],
[-168.761519, -38.375012],
[-168.77409, -44.156217],
[-169.197442, -52.122889],
[-171.589247, -61.67665],
[-180, -67],
[-185.798508, -64.97435],
[-188.273578, -61.932319],
[-189.578894, -58.757802],
[-190.333512, -55.545023],
[-190.782231, -52.318336],
[-191.044629, -49.086046],
[-191.186286, -45.850315],
[-191.245801, -42.614301],
[-191.247236, -39.377096],
[-191.20604, -36.140205],
[-191.132425, -32.904694],
[-191.033132, -29.669207],
[-190.912656, -26.434579],
[-190.773843, -23.200324],
[-190.618391, -19.966817],
[-188.410753, -61.67665],
[-190.802558, -52.122889],
[-191.22591, -44.156217],
[-191.238481, -38.375012],
[-191.164502, -34.16656],
[-191.076542, -30.993289],
[-190.992041, -28.505179],
[-190.914574, -26.482344],
[-190.843974, -24.783931],
[-190.779129, -23.316582],
[-190.718784, -22.016028],
[-190.661769, -20.836238],
[-190.60703, -19.742835],
[-190.553604, -18.70895],
[-190.500585, -17.712463],
[-190.44707, -16.734064],
[-190.259902, -13.502271],
[-190.056235, -10.271676],
[-189.834747, -7.042382],
[-189.593446, -3.814932],
[-189.329476, -0.589097],
[-189.039105, 2.633936],
[-188.717133, 5.855031],
[-188.35684, 9.072469],
[-187.949122, 12.283875],
[-187.480844, 15.488953],
[-186.933433, 18.682944],
[-186.27773, 21.861462],
[-185.465126, 25.013207],
[-184.402434, 28.11005],
[-182.859607, 31.055266],
[-190.392107, -15.755753],
[-190.334634, -14.759536],
[-190.273389, -13.726124],
[-190.2068, -12.633439],
[-190.132808, -11.454674],
[-190.048591, -10.15556],
[-189.950115, -8.690233],
[-189.831334, -6.994705],
[-189.682719, -4.976107],
[-189.488343, -2.494484],
[-189.219617, 0.668263],
[-188.820544, 4.858227],
[-188.169191, 10.60333],
[-186.969271, 18.490068],
[-184.502118, 27.861418],
[-180, 33]
]
]
Expand Down
Loading

0 comments on commit f4ed1c5

Please sign in to comment.