From 220140201e0c28270b7e1e51957e078998049120 Mon Sep 17 00:00:00 2001 From: rowanwins Date: Thu, 14 May 2020 19:38:37 +1000 Subject: [PATCH 1/4] replace robust-orientation with robust-predicates, and monotone-convex-hull-2d with monotone-chain-convex-hull --- index.js | 15 +++++---------- package.json | 6 ++++-- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index bfd9890..512e8e0 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,10 @@ 'use strict'; var RBush = require('rbush'); -var convexHull = require('monotone-convex-hull-2d'); var Queue = require('tinyqueue'); var pointInPolygon = require('point-in-polygon'); -var orient = require('robust-orientation')[3]; +const orient = require('robust-predicates/umd/orient2d.min.js').orient2d; +const monotoneChainConvexHull = require('monotone-chain-convex-hull'); module.exports = concaveman; module.exports.default = concaveman; @@ -173,8 +173,8 @@ function noIntersections(a, b, segTree) { // check if the edges (p1,q1) and (p2,q2) intersect function intersects(p1, q1, p2, q2) { return p1 !== q2 && q1 !== p2 && - orient(p1, q1, p2) > 0 !== orient(p1, q1, q2) > 0 && - orient(p2, q2, p1) > 0 !== orient(p2, q2, q1) > 0; + orient(p1[0], p1[1], q1[0], q1[1], p2[0], p2[1]) > 0 !== orient(p1[0], p1[1], q1[0], q1[1], q2[0], q2[1]) > 0 && + orient(p2[0], p2[1], q2[0], q2[1], p1[0], p1[1]) > 0 !== orient(p2[0], p2[1], q2[0], q2[1], q1[0], q1[1]) > 0; } // update the bounding box of a node's edge @@ -212,12 +212,7 @@ function fastConvexHull(points) { } // get convex hull around the filtered points - var indices = convexHull(filtered); - - // return the hull as array of points (rather than indices) - var hull = []; - for (i = 0; i < indices.length; i++) hull.push(filtered[indices[i]]); - return hull; + return monotoneChainConvexHull(filtered); } // create a new node in a doubly linked list diff --git a/package.json b/package.json index 3c0c660..f73fb95 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,20 @@ "description": "Fast 2D concave hull algorithm in JavaScript (generates an outline of a point set)", "main": "index.js", "dependencies": { - "monotone-convex-hull-2d": "^1.0.1", + "monotone-chain-convex-hull": "^1.0.0", "point-in-polygon": "^1.0.1", "rbush": "^3.0.0", - "robust-orientation": "^1.1.3", + "robust-predicates": "^2.0.4", "tinyqueue": "^2.0.3" }, "devDependencies": { "eslint": "^4.19.1", "eslint-config-mourner": "^2.0.1", + "benchmark": "^2.1.4", "tape": "^4.10.2" }, "scripts": { + "bench": "node test/bench.js", "pretest": "eslint index.js test/*.js", "test": "tape test/test.js" }, From 3a18de7104c2c17d453ac79fae3c9fd8cebb6d1d Mon Sep 17 00:00:00 2001 From: rowanwins Date: Thu, 14 May 2020 20:13:37 +1000 Subject: [PATCH 2/4] remove references to bench --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index f73fb95..a349c28 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,9 @@ "devDependencies": { "eslint": "^4.19.1", "eslint-config-mourner": "^2.0.1", - "benchmark": "^2.1.4", "tape": "^4.10.2" }, "scripts": { - "bench": "node test/bench.js", "pretest": "eslint index.js test/*.js", "test": "tape test/test.js" }, From b4b6e2281a3a4504f844faa6dbd88dbc8b0275b0 Mon Sep 17 00:00:00 2001 From: rowanwins Date: Fri, 15 May 2020 21:23:07 +1000 Subject: [PATCH 3/4] remove monotone-chain-convex-hull dependency --- index.js | 33 +++++++++++++++++++++++++++++++-- package.json | 1 - 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 512e8e0..eea2240 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,6 @@ var RBush = require('rbush'); var Queue = require('tinyqueue'); var pointInPolygon = require('point-in-polygon'); const orient = require('robust-predicates/umd/orient2d.min.js').orient2d; -const monotoneChainConvexHull = require('monotone-chain-convex-hull'); module.exports = concaveman; module.exports.default = concaveman; @@ -212,7 +211,7 @@ function fastConvexHull(points) { } // get convex hull around the filtered points - return monotoneChainConvexHull(filtered); + return convexHull(filtered); } // create a new node in a doubly linked list @@ -345,3 +344,33 @@ function sqSegSegDist(x0, y0, x1, y1, x2, y2, x3, y3) { return dx * dx + dy * dy; } + +function cross(p1, p2, p3) { + return orient(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +} + +function convexHull(points) { + points.sort(function (a, b) { + return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]; + }); + + var lower = []; + for (var i = 0; i < points.length; i++) { + while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0) { + lower.pop(); + } + lower.push(points[i]); + } + + var upper = []; + for (var ii = points.length - 1; ii >= 0; ii--) { + while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], points[ii]) <= 0) { + upper.pop(); + } + upper.push(points[ii]); + } + + upper.pop(); + lower.pop(); + return lower.concat(upper); +} diff --git a/package.json b/package.json index a349c28..0adff92 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,6 @@ "description": "Fast 2D concave hull algorithm in JavaScript (generates an outline of a point set)", "main": "index.js", "dependencies": { - "monotone-chain-convex-hull": "^1.0.0", "point-in-polygon": "^1.0.1", "rbush": "^3.0.0", "robust-predicates": "^2.0.4", From eedd231514d105c80d920faddd063e8633bd52e3 Mon Sep 17 00:00:00 2001 From: rowanwins Date: Fri, 15 May 2020 22:05:03 +1000 Subject: [PATCH 4/4] address feedback --- index.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index eea2240..034e348 100644 --- a/index.js +++ b/index.js @@ -169,11 +169,15 @@ function noIntersections(a, b, segTree) { return true; } +function cross(p1, p2, p3) { + return orient(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +} + // check if the edges (p1,q1) and (p2,q2) intersect function intersects(p1, q1, p2, q2) { return p1 !== q2 && q1 !== p2 && - orient(p1[0], p1[1], q1[0], q1[1], p2[0], p2[1]) > 0 !== orient(p1[0], p1[1], q1[0], q1[1], q2[0], q2[1]) > 0 && - orient(p2[0], p2[1], q2[0], q2[1], p1[0], p1[1]) > 0 !== orient(p2[0], p2[1], q2[0], q2[1], q1[0], q1[1]) > 0; + cross(p1, q1, p2) > 0 !== cross(p1, q1, q2) > 0 && + cross(p2, q2, p1) > 0 !== cross(p2, q2, q1) > 0; } // update the bounding box of a node's edge @@ -345,14 +349,12 @@ function sqSegSegDist(x0, y0, x1, y1, x2, y2, x3, y3) { return dx * dx + dy * dy; } -function cross(p1, p2, p3) { - return orient(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +function compareByX(a, b) { + return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]; } function convexHull(points) { - points.sort(function (a, b) { - return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]; - }); + points.sort(compareByX); var lower = []; for (var i = 0; i < points.length; i++) {