diff --git a/packages/turf-angle/index.ts b/packages/turf-angle/index.ts index c7a386c5b7..8eb2dd914d 100644 --- a/packages/turf-angle/index.ts +++ b/packages/turf-angle/index.ts @@ -49,19 +49,23 @@ function angle( const B = endPoint; // Main - const azimuthAO = bearingToAzimuth( - options.mercator !== true ? bearing(A, O) : rhumbBearing(A, O) + const azimuthOA = bearingToAzimuth( + options.mercator !== true ? bearing(O, A) : rhumbBearing(O, A) ); - const azimuthBO = bearingToAzimuth( - options.mercator !== true ? bearing(B, O) : rhumbBearing(B, O) + let azimuthOB = bearingToAzimuth( + options.mercator !== true ? bearing(O, B) : rhumbBearing(O, B) ); - const angleAO = Math.abs(azimuthAO - azimuthBO); + // If OB "trails" OA advance OB one revolution so we get the clockwise angle. + if (azimuthOB < azimuthOA) { + azimuthOB = azimuthOB + 360; + } + const angleAOB = azimuthOB - azimuthOA; // Explementary angle if (options.explementary === true) { - return 360 - angleAO; + return 360 - angleAOB; } - return angleAO; + return angleAOB; } export { angle }; diff --git a/packages/turf-angle/test.ts b/packages/turf-angle/test.ts index a90afb5bb0..5b7985117e 100644 --- a/packages/turf-angle/test.ts +++ b/packages/turf-angle/test.ts @@ -1,101 +1,186 @@ import test from "tape"; -import path from "path"; -import { fileURLToPath } from "url"; -import { glob } from "glob"; -import { loadJsonFileSync } from "load-json-file"; -import { writeJsonFileSync } from "write-json-file"; -import { sector } from "@turf/sector"; -import { bearing } from "@turf/bearing"; -import { truncate } from "@turf/truncate"; -import { distance } from "@turf/distance"; -import { point, round, lineString, featureCollection } from "@turf/helpers"; +import { point, round } from "@turf/helpers"; import { angle } from "./index.js"; -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -test("turf-angle", (t) => { - glob - .sync(path.join(__dirname, "test", "in", "*.json")) - .forEach((filepath) => { - // Input - const { name } = path.parse(filepath); - const geojson = loadJsonFileSync(filepath); - const [start, mid, end] = geojson.features; - - // Results - const angleProperties = { - interiorAngle: round(angle(start, mid, end), 6), - interiorMercatorAngle: round( - angle(start, mid, end, { mercator: true }), - 6 - ), - explementary: false, - fill: "#F00", - stroke: "#F00", - "fill-opacity": 0.3, - }; - const angleExplementaryProperties = { - explementaryAngle: round( - angle(start, mid, end, { explementary: true }), - 6 - ), - explementaryMercatorAngle: round( - angle(start, mid, end, { explementary: true, mercator: true }), - 6 - ), +test("turf-angle -- across 0 bearing", (t) => { + t.equal(round(angle([-1, 1], [0, 0], [1, 1])), 90, "90 degrees"); + + t.end(); +}); + +test("turf-angle -- 90 degrees", (t) => { + t.equal( + round(angle([124, -17], [124, -22], [131, -22]), 6), + 91.312527, + "91.312527 degrees" + ); + t.equal( + round(angle([124, -17], [124, -22], [131, -22], { explementary: true }), 6), + 268.687473, + "268.687473 degrees explementary" + ); + t.equal( + round(angle([124, -17], [124, -22], [131, -22], { mercator: true }), 6), + 90, + "90 degrees mercator" + ); + t.equal( + round( + angle([124, -17], [124, -22], [131, -22], { + explementary: true, + mercator: true, + }), + 6 + ), + 270, + "270 degrees explementary mercator" + ); + t.end(); +}); + +test("turf-angle -- 180 degrees", (t) => { + t.equal(round(angle([3, -1], [2, 0], [1, 1]), 6), 180, "180 degrees"); + + t.end(); +}); + +test("turf-angle -- obtuse", (t) => { + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [59, 15.5]), 6), + 218.715175, + "218.715175 degrees" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [59, 15.5], { explementary: true }), + 6 + ), + 141.284825, + "141.284825 degrees explementary" + ); + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [59, 15.5], { mercator: true }), 6), + 219.826106, + "219.826106 degrees mercator" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [59, 15.5], { + explementary: true, + mercator: true, + }), + 6 + ), + 140.173894, + "140.173894 degrees explementary mercator" + ); + t.end(); +}); + +test("turf-angle -- obtuse bigger", (t) => { + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [46.5, 19]), 6), + 121.330117, + "121.330117 degrees" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [46.5, 19], { explementary: true }), + 6 + ), + 238.669883, + "238.669883 degrees explementary" + ); + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [46.5, 19], { mercator: true }), 6), + 120.970546, + "120.970546" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [46.5, 19], { + explementary: true, + mercator: true, + }), + 6 + ), + 239.029454, + "239.029454 degrees explementary mercator" + ); + t.end(); +}); + +test("turf-angle -- acute", (t) => { + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5]), 6), + 53.608314, + "53.608314 degrees" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { explementary: true }), + 6 + ), + 306.391686, + "306.391686 degrees explementary" + ); + t.equal( + round(angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { mercator: true }), 6), + 53.166357, + "53.166357 degrees mercator" + ); + t.equal( + round( + angle([48.5, 5.5], [51.5, 12], [44.5, 10.5], { explementary: true, - fill: "#00F", - stroke: "#00F", - "fill-opacity": 0.3, - }; - const results = featureCollection([ - truncate( - sector( - mid, - distance(mid, start) / 3, - bearing(mid, start), - bearing(mid, end), - { properties: angleProperties } - ) - ), - truncate( - sector( - mid, - distance(mid, start) / 2, - bearing(mid, end), - bearing(mid, start), - { properties: angleExplementaryProperties } - ) - ), - lineString( - [ - start.geometry.coordinates, - mid.geometry.coordinates, - end.geometry.coordinates, - ], - { "stroke-width": 4, stroke: "#222" } - ), - start, - mid, - end, - ]); - - // Save results - const expected = filepath.replace( - path.join("test", "in"), - path.join("test", "out") - ); - if (process.env.REGEN) writeJsonFileSync(expected, results); - t.deepEqual(results, loadJsonFileSync(expected), name); - }); + mercator: true, + }), + 6 + ), + 306.833643, + "306.833643 degrees explementary mercator" + ); + t.end(); +}); + +test("turf-angle -- acute inverse", (t) => { + t.equal( + round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5]), 6), + 306.391686, + "306.391686 degrees" + ); + t.equal( + round( + angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { explementary: true }), + 6 + ), + 53.608314, + "53.608314 degrees explementary" + ); + t.equal( + round(angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { mercator: true }), 6), + 306.833643, + "306.833643 degrees mercator" + ); + t.equal( + round( + angle([44.5, 10.5], [51.5, 12], [48.5, 5.5], { + explementary: true, + mercator: true, + }), + 6 + ), + 53.166357, + "53.166357 degrees explementary mercator" + ); t.end(); }); test("turf-angle -- simple", (t) => { t.equal(round(angle([5, 5], [5, 6], [3, 4])), 45, "45 degrees"); - t.equal(round(angle([3, 4], [5, 6], [5, 5])), 45, "45 degrees -- inverse"); + t.equal(round(angle([3, 4], [5, 6], [5, 5])), 315, "315 degrees -- inverse"); t.equal( - round(angle([3, 4], [5, 6], [5, 5], { explementary: true })), + round(angle([5, 5], [5, 6], [3, 4], { explementary: true })), 360 - 45, "explementary angle" ); @@ -139,3 +224,19 @@ test("turf-angle -- throws", (t) => { t.end(); }); + +test("turf-angle -- 2703", (t) => { + const start = [0, 1]; + const mid = [0, 0]; + const end = [1, 0]; + const a = angle(start, mid, end); + t.equal(a, 90, "90 clockwise"); + + const start2 = [0, 1]; + const mid2 = [0, 0]; + const end2 = [-1, 0]; + const a2 = angle(start2, mid2, end2); + t.equal(a2, 270, "270 clockwise"); + + t.end(); +}); diff --git a/packages/turf-angle/test/in/90-degrees.json b/packages/turf-angle/test/in/90-degrees.json deleted file mode 100644 index d0040b7120..0000000000 --- a/packages/turf-angle/test/in/90-degrees.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [124, -17] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [124, -22] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [131, -22] - } - } - ] -} diff --git a/packages/turf-angle/test/in/acute-inverse.json b/packages/turf-angle/test/in/acute-inverse.json deleted file mode 100644 index 9d13168b4f..0000000000 --- a/packages/turf-angle/test/in/acute-inverse.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [44.5, 10.5] - } - } - ] -} diff --git a/packages/turf-angle/test/in/acute.json b/packages/turf-angle/test/in/acute.json deleted file mode 100644 index 50a544abcd..0000000000 --- a/packages/turf-angle/test/in/acute.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [44.5, 10.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - } - ] -} diff --git a/packages/turf-angle/test/in/obtuse-bigger.json b/packages/turf-angle/test/in/obtuse-bigger.json deleted file mode 100644 index b5fb55dbfc..0000000000 --- a/packages/turf-angle/test/in/obtuse-bigger.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [46.5, 19] - } - } - ] -} diff --git a/packages/turf-angle/test/in/obtuse.json b/packages/turf-angle/test/in/obtuse.json deleted file mode 100644 index 39c54b171d..0000000000 --- a/packages/turf-angle/test/in/obtuse.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [59, 15.5] - } - } - ] -} diff --git a/packages/turf-angle/test/out/90-degrees.json b/packages/turf-angle/test/out/90-degrees.json deleted file mode 100644 index 4265337bb9..0000000000 --- a/packages/turf-angle/test/out/90-degrees.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "interiorAngle": 88.687473, - "interiorMercatorAngle": 90, - "explementary": false, - "fill": "#F00", - "stroke": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [124, -22], - [124, -20.333333], - [124.04425, -20.333844], - [124.088474, -20.335376], - [124.132644, -20.337929], - [124.176735, -20.341501], - [124.22072, -20.346089], - [124.264573, -20.351692], - [124.308266, -20.358305], - [124.351775, -20.365925], - [124.395073, -20.374547], - [124.438134, -20.384166], - [124.480932, -20.394777], - [124.523441, -20.406372], - [124.565636, -20.418945], - [124.607491, -20.432488], - [124.648981, -20.446993], - [124.690081, -20.462452], - [124.730767, -20.478855], - [124.771013, -20.496192], - [124.810795, -20.514453], - [124.850089, -20.533627], - [124.888872, -20.553702], - [124.92712, -20.574667], - [124.964809, -20.596508], - [125.001917, -20.619212], - [125.038421, -20.642766], - [125.074299, -20.667156], - [125.109529, -20.692366], - [125.144089, -20.718382], - [125.177958, -20.745187], - [125.211115, -20.772767], - [125.24354, -20.801103], - [125.275212, -20.830179], - [125.306113, -20.859977], - [125.336223, -20.89048], - [125.365524, -20.921668], - [125.393996, -20.953523], - [125.421623, -20.986025], - [125.448387, -21.019156], - [125.474271, -21.052893], - [125.499259, -21.087218], - [125.523336, -21.122109], - [125.546485, -21.157546], - [125.568692, -21.193505], - [125.589943, -21.229966], - [125.610224, -21.266907], - [125.629523, -21.304304], - [125.647826, -21.342135], - [125.665122, -21.380377], - [125.681399, -21.419006], - [125.696646, -21.457999], - [125.710855, -21.497332], - [125.724014, -21.536981], - [125.736115, -21.576922], - [125.74715, -21.617129], - [125.757111, -21.657579], - [125.76599, -21.698246], - [125.773783, -21.739105], - [125.780482, -21.780132], - [125.786084, -21.8213], - [125.790582, -21.862586], - [125.793975, -21.903962], - [125.796258, -21.945403], - [125.797429, -21.986885], - [125.797488, -22.028381], - [124, -22] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "explementaryAngle": 271.312527, - "explementaryMercatorAngle": 270, - "explementary": true, - "fill": "#00F", - "stroke": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [124, -22], - [126.696439, -22.035218], - [126.688162, -22.218141], - [126.665416, -22.400012], - [126.628265, -22.579849], - [126.576855, -22.75668], - [126.511409, -22.929545], - [126.43223, -23.097499], - [126.339701, -23.259623], - [126.234279, -23.415026], - [126.116502, -23.56285], - [125.986979, -23.702275], - [125.846392, -23.832527], - [125.695492, -23.952877], - [125.535093, -24.062653], - [125.366071, -24.161238], - [125.189356, -24.248076], - [125.005929, -24.322678], - [124.816814, -24.384621], - [124.623073, -24.433554], - [124.4258, -24.4692], - [124.22611, -24.491355], - [124.025137, -24.499893], - [123.82402, -24.494767], - [123.623903, -24.476005], - [123.425921, -24.443714], - [123.231195, -24.398077], - [123.040823, -24.339354], - [122.855878, -24.267878], - [122.677392, -24.184053], - [122.506359, -24.088353], - [122.343722, -23.981317], - [122.19037, -23.863547], - [122.047134, -23.735703], - [121.91478, -23.598499], - [121.794008, -23.452698], - [121.685447, -23.29911], - [121.589651, -23.138582], - [121.507098, -22.971999], - [121.43819, -22.800274], - [121.383249, -22.624344], - [121.34252, -22.445167], - [121.316165, -22.263713], - [121.304272, -22.080961], - [121.306846, -21.897892], - [121.323819, -21.715488], - [121.355046, -21.53472], - [121.400308, -21.356549], - [121.459317, -21.181918], - [121.531712, -21.011749], - [121.617071, -20.846936], - [121.714905, -20.688343], - [121.824667, -20.5368], - [121.94575, -20.393097], - [122.077498, -20.25798], - [122.2192, -20.132151], - [122.370104, -20.016261], - [122.529412, -19.910908], - [122.696289, -19.816638], - [122.869865, -19.733934], - [123.049239, -19.663222], - [123.233486, -19.604865], - [123.421658, -19.559163], - [123.612788, -19.526351], - [123.805898, -19.506596], - [124, -19.5], - [124, -22] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke-width": 4, - "stroke": "#222" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [124, -17], - [124, -22], - [131, -22] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [124, -17] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [124, -22] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [131, -22] - } - } - ] -} diff --git a/packages/turf-angle/test/out/acute-inverse.json b/packages/turf-angle/test/out/acute-inverse.json deleted file mode 100644 index e92c2c4b96..0000000000 --- a/packages/turf-angle/test/out/acute-inverse.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "interiorAngle": 52.698136, - "interiorMercatorAngle": 53.166357, - "explementary": false, - "fill": "#F00", - "stroke": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [50.487833, 9.836074], - [50.455818, 9.850776], - [50.424022, 9.865934], - [50.392451, 9.881546], - [50.361111, 9.897607], - [50.33001, 9.914115], - [50.299154, 9.931065], - [50.268549, 9.948455], - [50.238202, 9.966281], - [50.20812, 9.984538], - [50.178308, 10.003224], - [50.148772, 10.022334], - [50.11952, 10.041864], - [50.090557, 10.06181], - [50.06189, 10.082168], - [50.033523, 10.102934], - [50.005465, 10.124103], - [49.977719, 10.145671], - [49.950293, 10.167633], - [49.923192, 10.189986], - [49.896422, 10.212723], - [49.869988, 10.23584], - [49.843896, 10.259333], - [49.818152, 10.283196], - [49.792761, 10.307425], - [49.767728, 10.332014], - [49.743059, 10.356958], - [49.718759, 10.382253], - [49.694834, 10.407892], - [49.671288, 10.43387], - [49.648126, 10.460182], - [49.625353, 10.486822], - [49.602975, 10.513785], - [49.580996, 10.541065], - [49.559421, 10.568656], - [49.538254, 10.596553], - [49.5175, 10.624749], - [49.497163, 10.653239], - [49.477248, 10.682016], - [49.45776, 10.711075], - [49.438701, 10.740409], - [49.420077, 10.770013], - [49.401892, 10.79988], - [49.384149, 10.830003], - [49.366852, 10.860377], - [49.350005, 10.890995], - [49.333613, 10.92185], - [49.317677, 10.952936], - [49.302203, 10.984247], - [49.287192, 11.015775], - [49.27265, 11.047515], - [49.258578, 11.079459], - [49.24498, 11.1116], - [49.231858, 11.143933], - [49.219217, 11.17645], - [49.207059, 11.209144], - [49.195385, 11.242008], - [49.1842, 11.275035], - [49.173506, 11.308219], - [49.163304, 11.341552], - [49.153598, 11.375027], - [49.144389, 11.408638], - [49.13568, 11.442376], - [49.127473, 11.476235], - [49.119769, 11.510208], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "explementaryAngle": 307.301864, - "explementaryMercatorAngle": 306.833643, - "explementary": true, - "fill": "#00F", - "stroke": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [47.932822, 11.25803], - [47.880206, 11.551701], - [47.852657, 11.848643], - [47.850444, 12.1468], - [47.873667, 12.4441], - [47.922251, 12.738471], - [47.995945, 13.027852], - [48.094321, 13.310212], - [48.216776, 13.583558], - [48.362528, 13.845956], - [48.530626, 14.095541], - [48.719947, 14.330532], - [48.929209, 14.549244], - [49.156971, 14.750105], - [49.401646, 14.931665], - [49.661512, 15.092608], - [49.934722, 15.231766], - [50.21932, 15.348124], - [50.513252, 15.440832], - [50.814387, 15.509212], - [51.120533, 15.552762], - [51.429455, 15.571163], - [51.738892, 15.564279], - [52.046582, 15.532161], - [52.350276, 15.475046], - [52.647759, 15.393351], - [52.93687, 15.287676], - [53.215519, 15.158792], - [53.481702, 15.007641], - [53.733522, 14.835322], - [53.969197, 14.643085], - [54.187077, 14.43232], - [54.385654, 14.204546], - [54.563573, 13.961397], - [54.719638, 13.704611], - [54.852817, 13.436018], - [54.962251, 13.157522], - [55.047257, 12.871091], - [55.107326, 12.57874], - [55.142126, 12.282518], - [55.151503, 11.984494], - [55.135477, 11.686742], - [55.094241, 11.391327], - [55.028156, 11.100292], - [54.93775, 10.815644], - [54.823708, 10.539341], - [54.68687, 10.27328], - [54.528225, 10.019281], - [54.3489, 9.779083], - [54.150154, 9.554324], - [53.933373, 9.346538], - [53.700055, 9.157138], - [53.451804, 8.987415], - [53.190318, 8.838522], - [52.917382, 8.71147], - [52.634852, 8.607124], - [52.344643, 8.526191], - [52.048723, 8.46922], - [51.749093, 8.4366], - [51.447779, 8.42855], - [51.146818, 8.445126], - [50.848244, 8.486215], - [50.554078, 8.551539], - [50.266308, 8.640653], - [49.986887, 8.752953], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke-width": 4, - "stroke": "#222" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [48.5, 5.5], - [51.5, 12], - [44.5, 10.5] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [44.5, 10.5] - } - } - ] -} diff --git a/packages/turf-angle/test/out/acute.json b/packages/turf-angle/test/out/acute.json deleted file mode 100644 index a71ae6582f..0000000000 --- a/packages/turf-angle/test/out/acute.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "interiorAngle": 52.698136, - "interiorMercatorAngle": 53.166357, - "explementary": false, - "fill": "#F00", - "stroke": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [49.15854, 11.518357], - [49.124843, 11.711158], - [49.107647, 11.906037], - [49.107107, 12.101642], - [49.123262, 12.296609], - [49.156037, 12.489577], - [49.205239, 12.679197], - [49.27056, 12.864137], - [49.351579, 13.043099], - [49.447757, 13.214821], - [49.55845, 13.37809], - [49.682904, 13.531749], - [49.820264, 13.674709], - [49.969578, 13.805952], - [50.129802, 13.924543], - [50.299812, 14.029634], - [50.478406, 14.120476], - [50.664316, 14.196415], - [50.856218, 14.256907], - [51.052739, 14.301518], - [51.252473, 14.329928], - [51.453985, 14.34193], - [51.655827, 14.33744], - [51.85655, 14.31649], - [52.054711, 14.279229], - [52.248891, 14.225927], - [52.437699, 14.156966], - [52.619788, 14.072842], - [52.793863, 13.974157], - [52.958691, 13.861619], - [53.113112, 13.736031], - [53.256043, 13.598289], - [53.38649, 13.449375], - [53.503554, 13.290346], - [53.606434, 13.122329], - [53.694435, 12.946513], - [53.766969, 12.764138], - [53.823562, 12.576487], - [53.863854, 12.384879], - [53.887599, 12.190654], - [53.894669, 11.995171], - [53.885052, 11.799792], - [53.858849, 11.605877], - [53.816276, 11.414772], - [53.757661, 11.227801], - [53.683439, 11.046258], - [53.594149, 10.871395], - [53.490431, 10.704419], - [53.373021, 10.54648], - [53.242743, 10.398663], - [53.100509, 10.261983], - [52.947306, 10.137378], - [52.784194, 10.025703], - [52.612299, 9.927722], - [52.4328, 9.844107], - [52.246931, 9.775428], - [52.055961, 9.722157], - [51.861198, 9.684656], - [51.66397, 9.663183], - [51.465624, 9.657885], - [51.267512, 9.668796], - [51.070987, 9.695843], - [50.877388, 9.738842], - [50.688039, 9.797497], - [50.504234, 9.871408], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "explementaryAngle": 307.301864, - "explementaryMercatorAngle": 306.833643, - "explementary": true, - "fill": "#00F", - "stroke": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [50.011338, 8.805989], - [49.964224, 8.827611], - [49.917429, 8.849905], - [49.870962, 8.872865], - [49.824834, 8.896487], - [49.779053, 8.920766], - [49.733629, 8.945697], - [49.688572, 8.971274], - [49.643892, 8.997493], - [49.599597, 9.024348], - [49.555696, 9.051832], - [49.5122, 9.079942], - [49.469117, 9.10867], - [49.426456, 9.138011], - [49.384226, 9.167958], - [49.342435, 9.198506], - [49.301094, 9.229647], - [49.26021, 9.261376], - [49.219792, 9.293686], - [49.179848, 9.32657], - [49.140388, 9.360022], - [49.101419, 9.394034], - [49.062949, 9.428599], - [49.024986, 9.46371], - [48.98754, 9.499359], - [48.950617, 9.53554], - [48.914225, 9.572245], - [48.878372, 9.609465], - [48.843067, 9.647194], - [48.808315, 9.685423], - [48.774125, 9.724145], - [48.740504, 9.763351], - [48.707459, 9.803033], - [48.674998, 9.843183], - [48.643126, 9.883792], - [48.611852, 9.924852], - [48.581181, 9.966355], - [48.551121, 10.008291], - [48.521677, 10.050652], - [48.492857, 10.093429], - [48.464666, 10.136613], - [48.437111, 10.180196], - [48.410197, 10.224167], - [48.38393, 10.268518], - [48.358317, 10.313239], - [48.333362, 10.358321], - [48.309072, 10.403755], - [48.285451, 10.449531], - [48.262506, 10.495639], - [48.24024, 10.54207], - [48.218658, 10.588814], - [48.197767, 10.635862], - [48.17757, 10.683202], - [48.158072, 10.730826], - [48.139277, 10.778723], - [48.121189, 10.826884], - [48.103814, 10.875298], - [48.087154, 10.923954], - [48.071213, 10.972843], - [48.055996, 11.021955], - [48.041505, 11.071279], - [48.027744, 11.120804], - [48.014717, 11.17052], - [48.002426, 11.220418], - [47.990875, 11.270485], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke-width": 4, - "stroke": "#222" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [44.5, 10.5], - [51.5, 12], - [48.5, 5.5] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [44.5, 10.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - } - ] -} diff --git a/packages/turf-angle/test/out/obtuse-bigger.json b/packages/turf-angle/test/out/obtuse-bigger.json deleted file mode 100644 index 63f0216685..0000000000 --- a/packages/turf-angle/test/out/obtuse-bigger.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "interiorAngle": 120.447846, - "interiorMercatorAngle": 120.970546, - "explementary": false, - "fill": "#F00", - "stroke": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [50.487833, 9.836074], - [50.415688, 9.870001], - [50.344705, 9.906244], - [50.274961, 9.944764], - [50.20653, 9.985519], - [50.139487, 10.028467], - [50.073904, 10.07356], - [50.009852, 10.120751], - [49.9474, 10.169988], - [49.886617, 10.221219], - [49.827567, 10.274389], - [49.770315, 10.32944], - [49.714924, 10.386313], - [49.661454, 10.444947], - [49.609964, 10.505278], - [49.56051, 10.567243], - [49.513147, 10.630774], - [49.467926, 10.695802], - [49.424898, 10.762257], - [49.384111, 10.830068], - [49.34561, 10.899161], - [49.309438, 10.969462], - [49.275636, 11.040894], - [49.244242, 11.113381], - [49.215292, 11.186844], - [49.188819, 11.261202], - [49.164853, 11.336377], - [49.143422, 11.412286], - [49.124552, 11.488846], - [49.108264, 11.565975], - [49.09458, 11.643588], - [49.083515, 11.721602], - [49.075084, 11.79993], - [49.069299, 11.878489], - [49.066168, 11.957192], - [49.065696, 12.035953], - [49.067887, 12.114687], - [49.072741, 12.193306], - [49.080254, 12.271725], - [49.090421, 12.349859], - [49.103233, 12.427621], - [49.118679, 12.504926], - [49.136743, 12.58169], - [49.157408, 12.657827], - [49.180655, 12.733254], - [49.206459, 12.807888], - [49.234795, 12.881646], - [49.265633, 12.954447], - [49.298942, 13.026211], - [49.334688, 13.096859], - [49.372832, 13.166311], - [49.413335, 13.234492], - [49.456154, 13.301325], - [49.501244, 13.366736], - [49.548555, 13.430652], - [49.598038, 13.493003], - [49.64964, 13.553719], - [49.703304, 13.612733], - [49.758972, 13.669977], - [49.816583, 13.72539], - [49.876076, 13.778908], - [49.937384, 13.830471], - [50.000441, 13.880023], - [50.065177, 13.927507], - [50.131521, 13.972871], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "explementaryAngle": 239.552154, - "explementaryMercatorAngle": 239.029454, - "explementary": true, - "fill": "#00F", - "stroke": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [49.438664, 14.956465], - [49.641509, 15.081264], - [49.85254, 15.192891], - [50.07084, 15.290851], - [50.295457, 15.374712], - [50.525406, 15.4441], - [50.759673, 15.498708], - [50.997223, 15.538293], - [51.237005, 15.562678], - [51.477954, 15.571755], - [51.719002, 15.565483], - [51.959077, 15.543891], - [52.197114, 15.507073], - [52.432059, 15.455195], - [52.662874, 15.388488], - [52.88854, 15.307247], - [53.108067, 15.211834], - [53.320497, 15.10267], - [53.524905, 14.98024], - [53.720408, 14.845083], - [53.906169, 14.697794], - [54.081395, 14.539021], - [54.245349, 14.369457], - [54.397344, 14.189844], - [54.536752, 14.000964], - [54.663004, 13.803636], - [54.775592, 13.598714], - [54.874069, 13.387083], - [54.958053, 13.169651], - [55.027225, 12.947351], - [55.081334, 12.721134], - [55.12019, 12.491961], - [55.143671, 12.260809], - [55.15172, 12.028654], - [55.144342, 11.796478], - [55.121608, 11.565259], - [55.083651, 11.33597], - [55.030665, 11.10957], - [54.962907, 10.887009], - [54.880689, 10.669215], - [54.784382, 10.457096], - [54.674414, 10.251534], - [54.551265, 10.053385], - [54.415465, 9.86347], - [54.267596, 9.682576], - [54.108285, 9.511453], - [53.938204, 9.350808], - [53.758066, 9.201305], - [53.568623, 9.063562], - [53.370664, 8.938146], - [53.165008, 8.825577], - [52.952508, 8.726317], - [52.73404, 8.640776], - [52.510503, 8.569307], - [52.282818, 8.512204], - [52.051921, 8.469703], - [51.818759, 8.441978], - [51.584289, 8.429144], - [51.349473, 8.431253], - [51.115275, 8.448297], - [50.882655, 8.480206], - [50.652569, 8.526848], - [50.42596, 8.588031], - [50.203762, 8.663503], - [49.986887, 8.752953], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke-width": 4, - "stroke": "#222" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [48.5, 5.5], - [51.5, 12], - [46.5, 19] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [46.5, 19] - } - } - ] -} diff --git a/packages/turf-angle/test/out/obtuse.json b/packages/turf-angle/test/out/obtuse.json deleted file mode 100644 index 5c2a544c57..0000000000 --- a/packages/turf-angle/test/out/obtuse.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "type": "FeatureCollection", - "features": [ - { - "type": "Feature", - "properties": { - "interiorAngle": 220.958265, - "interiorMercatorAngle": 219.826106, - "explementary": false, - "fill": "#F00", - "stroke": "#F00", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [50.487833, 9.836074], - [50.358618, 9.898909], - [50.233379, 9.969168], - [50.112553, 10.046605], - [49.996566, 10.130951], - [49.885824, 10.22191], - [49.780719, 10.319164], - [49.681622, 10.422375], - [49.588884, 10.53118], - [49.502838, 10.6452], - [49.42379, 10.764034], - [49.352026, 10.887265], - [49.287806, 11.014462], - [49.231365, 11.145177], - [49.18291, 11.278951], - [49.142624, 11.415312], - [49.11066, 11.553779], - [49.087142, 11.693864], - [49.072167, 11.835071], - [49.0658, 11.976901], - [49.068078, 12.11885], - [49.079005, 12.260414], - [49.098557, 12.401089], - [49.126679, 12.540375], - [49.163284, 12.677773], - [49.208255, 12.812793], - [49.261445, 12.944952], - [49.322676, 13.073774], - [49.391742, 13.198797], - [49.468406, 13.31957], - [49.552404, 13.435659], - [49.643443, 13.546643], - [49.741204, 13.65212], - [49.845343, 13.751709], - [49.95549, 13.845048], - [50.071254, 13.931797], - [50.192218, 14.011641], - [50.317949, 14.084288], - [50.447992, 14.149474], - [50.581878, 14.206959], - [50.719119, 14.256534], - [50.859217, 14.298017], - [51.001659, 14.331256], - [51.145927, 14.356129], - [51.291492, 14.372545], - [51.43782, 14.380443], - [51.584377, 14.379796], - [51.730624, 14.370604], - [51.876026, 14.352902], - [52.020051, 14.326755], - [52.162172, 14.292258], - [52.301869, 14.249539], - [52.438634, 14.198753], - [52.571968, 14.140087], - [52.701388, 14.073756], - [52.826426, 14], - [52.94663, 13.919091], - [53.061568, 13.831323], - [53.17083, 13.737014], - [53.274026, 13.636509], - [53.37079, 13.530172], - [53.460782, 13.418389], - [53.543687, 13.301563], - [53.619216, 13.180118], - [53.68711, 13.05449], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "explementaryAngle": 139.041735, - "explementaryMercatorAngle": 140.173894, - "explementary": true, - "fill": "#00F", - "stroke": "#00F", - "fill-opacity": 0.3 - }, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [51.5, 12], - [54.787546, 13.574894], - [54.846609, 13.449936], - [54.900628, 13.32285], - [54.949533, 13.193828], - [54.993256, 13.063064], - [55.031743, 12.930753], - [55.064944, 12.797093], - [55.092818, 12.662285], - [55.115333, 12.526529], - [55.132464, 12.390028], - [55.144195, 12.252984], - [55.150515, 12.1156], - [55.151426, 11.97808], - [55.146932, 11.840628], - [55.13705, 11.703446], - [55.121802, 11.566736], - [55.101218, 11.430701], - [55.075335, 11.29554], - [55.044199, 11.161451], - [55.007863, 11.028631], - [54.966386, 10.897275], - [54.919835, 10.767575], - [54.868285, 10.639721], - [54.811817, 10.513899], - [54.750517, 10.390292], - [54.684482, 10.269082], - [54.61381, 10.150444], - [54.538611, 10.034551], - [54.458997, 9.921571], - [54.375087, 9.81167], - [54.287007, 9.705005], - [54.194889, 9.601733], - [54.098867, 9.502002], - [53.999084, 9.405957], - [53.895687, 9.313739], - [53.788828, 9.225479], - [53.678662, 9.141306], - [53.565351, 9.061341], - [53.449059, 8.985701], - [53.329956, 8.914495], - [53.208215, 8.847825], - [53.084012, 8.785788], - [52.957528, 8.728474], - [52.828944, 8.675965], - [52.698447, 8.628338], - [52.566224, 8.585661], - [52.432468, 8.547995], - [52.29737, 8.515396], - [52.161125, 8.48791], - [52.023929, 8.465577], - [51.88598, 8.448429], - [51.747475, 8.436491], - [51.608615, 8.42978], - [51.469598, 8.428306], - [51.330626, 8.432071], - [51.191897, 8.441069], - [51.05361, 8.455288], - [50.915966, 8.474707], - [50.779162, 8.499299], - [50.643394, 8.529026], - [50.508859, 8.563847], - [50.37575, 8.603712], - [50.244259, 8.648562], - [50.114576, 8.698333], - [49.986887, 8.752953], - [51.5, 12] - ] - ] - } - }, - { - "type": "Feature", - "properties": { - "stroke-width": 4, - "stroke": "#222" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [48.5, 5.5], - [51.5, 12], - [59, 15.5] - ] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#008000", - "name": "start" - }, - "geometry": { - "type": "Point", - "coordinates": [48.5, 5.5] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#00F", - "name": "middle" - }, - "geometry": { - "type": "Point", - "coordinates": [51.5, 12] - } - }, - { - "type": "Feature", - "properties": { - "marker-color": "#F00", - "name": "end" - }, - "geometry": { - "type": "Point", - "coordinates": [59, 15.5] - } - } - ] -} diff --git a/packages/turf-bearing/index.ts b/packages/turf-bearing/index.ts index dbe25c28c7..6d72bdc60f 100644 --- a/packages/turf-bearing/index.ts +++ b/packages/turf-bearing/index.ts @@ -2,7 +2,7 @@ import { Coord, degreesToRadians, radiansToDegrees } from "@turf/helpers"; import { getCoord } from "@turf/invariant"; // http://en.wikipedia.org/wiki/Haversine_formula -// http://www.movable-type.co.uk/scripts/latlong.html +// http://www.movable-type.co.uk/scripts/latlong.html#bearing /** * Takes two {@link Point|points} and finds the geographic bearing between them, diff --git a/packages/turf-helpers/index.ts b/packages/turf-helpers/index.ts index b53cc6bd6d..8d444160f8 100644 --- a/packages/turf-helpers/index.ts +++ b/packages/turf-helpers/index.ts @@ -677,9 +677,16 @@ export function bearingToAzimuth(bearing: number): number { * @returns {number} bearing between -180 and +180 degrees */ export function azimuthToBearing(angle: number): number { + // Ignore full revolutions (multiples of 360) angle = angle % 360; - if (angle > 0) return angle > 180 ? angle - 360 : angle; - return angle < -180 ? angle + 360 : angle; + + if (angle > 180) { + return angle - 360; + } else if (angle < -180) { + return angle + 360; + } + + return angle; } /** @@ -690,8 +697,9 @@ export function azimuthToBearing(angle: number): number { * @returns {number} degrees between 0 and 360 degrees */ export function radiansToDegrees(radians: number): number { - const degrees = radians % (2 * Math.PI); - return (degrees * 180) / Math.PI; + // % (2 * Math.PI) radians in case someone passes value > 2π + const normalisedRadians = radians % (2 * Math.PI); + return (normalisedRadians * 180) / Math.PI; } /** @@ -702,8 +710,9 @@ export function radiansToDegrees(radians: number): number { * @returns {number} angle in radians */ export function degreesToRadians(degrees: number): number { - const radians = degrees % 360; - return (radians * Math.PI) / 180; + // % 360 degrees in case someone passes value > 360 + const normalisedDegrees = degrees % 360; + return (normalisedDegrees * Math.PI) / 180; } /**