From 47af8c9119a7f93ba501af62a7a861c29cd13d45 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 11 Jan 2016 11:08:44 -0800 Subject: [PATCH] =?UTF-8?q?Export=20symbols=20with=20=E2=80=9Cpolygon?= =?UTF-8?q?=E2=80=9D=20prefix.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++------ index.js | 10 +++++----- package.json | 5 ++++- src/{inside.js => contains.js} | 0 src/{perimeter.js => length.js} | 0 test/area-test.js | 24 ++++++++++++------------ test/centroid-test.js | 24 ++++++++++++------------ test/contains-test.js | 28 ++++++++++++++++++++++++++++ test/hull-test.js | 30 +++++++++++++++--------------- test/inside-test.js | 28 ---------------------------- test/length-test.js | 24 ++++++++++++++++++++++++ test/perimeter-test.js | 24 ------------------------ 12 files changed, 106 insertions(+), 103 deletions(-) rename src/{inside.js => contains.js} (100%) rename src/{perimeter.js => length.js} (100%) create mode 100644 test/contains-test.js delete mode 100644 test/inside-test.js create mode 100644 test/length-test.js delete mode 100644 test/perimeter-test.js diff --git a/README.md b/README.md index f884700..af04b94 100644 --- a/README.md +++ b/README.md @@ -7,31 +7,31 @@ This module provides a few basic geometric operations for two-dimensional polygo If you use NPM, `npm install d3-polygon`. Otherwise, download the [latest release](https://github.com/d3/d3-polygon/releases/latest). The released bundle supports AMD, CommonJS, and vanilla environments. Create a custom build using [Rollup](https://github.com/rollup/rollup) or your preferred bundler. You can also load directly from [d3js.org](https://d3js.org): ```html - + ``` In a vanilla environment, a `d3_polygon` global is exported. [Try d3-polygon in your browser.](https://tonicdev.com/npm/d3-polygon) ## API Reference -# d3_polygon.area(polygon) +# d3.polygonArea(polygon) Returns the signed area of the specified *polygon*. If the vertices of the polygon are in counterclockwise order (assuming a coordinate system where the origin ⟨0,0⟩ is in the top-left corner), the returned area is positive; otherwise it is negative, or zero. -# d3_polygon.centroid(polygon) +# d3.polygonCentroid(polygon) Returns the [centroid](https://en.wikipedia.org/wiki/Centroid) of the specified *polygon*. -# d3_polygon.hull(points) +# d3.polygonHull(points) Returns the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of the specified *points* using [Andrew’s monotone chain algorithm](http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain). The returned hull is represented as an array containing a subset of the input *points* arranged in counterclockwise order. Returns null if *points* has fewer than three elements. -# d3_polygon.inside(polygon, point) +# d3.polygonContains(polygon, point) Returns true if and only if the specified *point* is [inside the specified *polygon*](https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html). -# d3_polygon.perimeter(polygon) +# d3.polygonLength(polygon) Returns the length of the perimeter of the specified *polygon*. diff --git a/index.js b/index.js index 7f02219..ffabecc 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ -export {default as area} from "./src/area"; -export {default as centroid} from "./src/centroid"; -export {default as hull} from "./src/hull"; -export {default as inside} from "./src/inside"; -export {default as perimeter} from "./src/perimeter"; +export {default as polygonArea} from "./src/area"; +export {default as polygonCentroid} from "./src/centroid"; +export {default as polygonHull} from "./src/hull"; +export {default as polygonContains} from "./src/contains"; +export {default as polygonLength} from "./src/length"; diff --git a/package.json b/package.json index bc1c940..b49ae71 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,12 @@ { "name": "d3-polygon", - "version": "0.1.0", + "version": "0.2.0", "description": "Operations for two-dimensional polygons.", "keywords": [ "d3", + "polygon", + "hull", + "geometry", "graphics" ], "homepage": "https://github.com/d3/d3-polygon", diff --git a/src/inside.js b/src/contains.js similarity index 100% rename from src/inside.js rename to src/contains.js diff --git a/src/perimeter.js b/src/length.js similarity index 100% rename from src/perimeter.js rename to src/length.js diff --git a/test/area-test.js b/test/area-test.js index 4a41c1b..55f607e 100644 --- a/test/area-test.js +++ b/test/area-test.js @@ -1,29 +1,29 @@ var tape = require("tape"), polygon = require("../"); -tape("area(polygon) returns the expected value for closed counterclockwise polygons", function(test) { - test.equal(polygon.area([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), 1); +tape("polygonArea(polygon) returns the expected value for closed counterclockwise polygons", function(test) { + test.equal(polygon.polygonArea([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), 1); test.end(); }); -tape("area(polygon) returns the expected value for closed clockwise polygons", function(test) { - test.equal(polygon.area([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), -1); - test.equal(polygon.area([[1, 1], [3, 2], [2, 3], [1, 1]]), -1.5); +tape("polygonArea(polygon) returns the expected value for closed clockwise polygons", function(test) { + test.equal(polygon.polygonArea([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), -1); + test.equal(polygon.polygonArea([[1, 1], [3, 2], [2, 3], [1, 1]]), -1.5); test.end(); }); -tape("area(polygon) returns the expected value for open counterclockwise polygons", function(test) { - test.equal(polygon.area([[0, 0], [0, 1], [1, 1], [1, 0]]), 1); +tape("polygonArea(polygon) returns the expected value for open counterclockwise polygons", function(test) { + test.equal(polygon.polygonArea([[0, 0], [0, 1], [1, 1], [1, 0]]), 1); test.end(); }); -tape("area(polygon) returns the expected value for open clockwise polygons", function(test) { - test.equal(polygon.area([[0, 0], [1, 0], [1, 1], [0, 1]]), -1); - test.equal(polygon.area([[1, 1], [3, 2], [2, 3]]), -1.5); +tape("polygonArea(polygon) returns the expected value for open clockwise polygons", function(test) { + test.equal(polygon.polygonArea([[0, 0], [1, 0], [1, 1], [0, 1]]), -1); + test.equal(polygon.polygonArea([[1, 1], [3, 2], [2, 3]]), -1.5); test.end(); }); -tape("area(polygon) returns the expected value for a very large polygon", function(test) { +tape("polygonArea(polygon) returns the expected value for a very large polygon", function(test) { var start = 0, stop = 1e8, step = 1e4, @@ -32,6 +32,6 @@ tape("area(polygon) returns the expected value for a very large polygon", functi for (var value = 0; value < stop; value += step) points.push([value, stop]); for (var value = stop - step; value >= 0; value -= step) points.push([stop, value]); for (var value = stop - step; value >= 0; value -= step) points.push([value, 0]); - test.equal(polygon.area(points), 1e16 - 5e7); + test.equal(polygon.polygonArea(points), 1e16 - 5e7); test.end(); }); diff --git a/test/centroid-test.js b/test/centroid-test.js index 5e20d4b..1d16e69 100644 --- a/test/centroid-test.js +++ b/test/centroid-test.js @@ -1,29 +1,29 @@ var tape = require("tape"), polygon = require("../"); -tape("centroid(points) returns the expected value for closed counterclockwise polygons", function(test) { - test.deepEqual(polygon.centroid([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), [.5, .5]); +tape("polygonCentroid(points) returns the expected value for closed counterclockwise polygons", function(test) { + test.deepEqual(polygon.polygonCentroid([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), [.5, .5]); test.end(); }); -tape("centroid(points) returns the expected value for closed clockwise polygons", function(test) { - test.deepEqual(polygon.centroid([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), [.5, .5]); - test.deepEqual(polygon.centroid([[1, 1], [3, 2], [2, 3], [1, 1]]), [2, 2]); +tape("polygonCentroid(points) returns the expected value for closed clockwise polygons", function(test) { + test.deepEqual(polygon.polygonCentroid([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), [.5, .5]); + test.deepEqual(polygon.polygonCentroid([[1, 1], [3, 2], [2, 3], [1, 1]]), [2, 2]); test.end(); }); -tape("centroid(points) returns the expected value for open counterclockwise polygons", function(test) { - test.deepEqual(polygon.centroid([[0, 0], [0, 1], [1, 1], [1, 0]]), [.5, .5]); +tape("polygonCentroid(points) returns the expected value for open counterclockwise polygons", function(test) { + test.deepEqual(polygon.polygonCentroid([[0, 0], [0, 1], [1, 1], [1, 0]]), [.5, .5]); test.end(); }); -tape("centroid(points) returns the expected value for closed counterclockwise polygons", function(test) { - test.deepEqual(polygon.centroid([[0, 0], [1, 0], [1, 1], [0, 1]]), [.5, .5]); - test.deepEqual(polygon.centroid([[1, 1], [3, 2], [2, 3]]), [2, 2]); +tape("polygonCentroid(points) returns the expected value for closed counterclockwise polygons", function(test) { + test.deepEqual(polygon.polygonCentroid([[0, 0], [1, 0], [1, 1], [0, 1]]), [.5, .5]); + test.deepEqual(polygon.polygonCentroid([[1, 1], [3, 2], [2, 3]]), [2, 2]); test.end(); }); -tape("centroid(polygon) returns the expected value for a very large polygon", function(test) { +tape("polygonCentroid(polygon) returns the expected value for a very large polygon", function(test) { var start = 0, stop = 1e8, step = 1e4, @@ -32,6 +32,6 @@ tape("centroid(polygon) returns the expected value for a very large polygon", fu for (var value = 0; value < stop; value += step) points.push([value, stop]); for (var value = stop - step; value >= 0; value -= step) points.push([stop, value]); for (var value = stop - step; value >= 0; value -= step) points.push([value, 0]); - test.deepEqual(polygon.centroid(points), [49999999.75000187, 49999999.75001216]); + test.deepEqual(polygon.polygonCentroid(points), [49999999.75000187, 49999999.75001216]); test.end(); }); diff --git a/test/contains-test.js b/test/contains-test.js new file mode 100644 index 0000000..0f3315d --- /dev/null +++ b/test/contains-test.js @@ -0,0 +1,28 @@ +var tape = require("tape"), + polygon = require("../"); + +tape("polygonContains(polygon, point) returns the expected value for closed counterclockwise polygons", function(test) { + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, 0.5]), true); + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [1.5, 0.5]), false); + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [-0.5, 0.5]), false); + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, 1.5]), false); + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, -0.5]), false); + test.end(); +}); + +tape("polygonContains(polygon, point) returns the expected value for closed clockwise polygons", function(test) { + test.equal(polygon.polygonContains([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]], [0.5, 0.5]), true); + test.equal(polygon.polygonContains([[1, 1], [3, 2], [2, 3], [1, 1]], [1.5, 1.5]), true); + test.end(); +}); + +tape("polygonContains(polygon, point) returns the expected value for open counterclockwise polygons", function(test) { + test.equal(polygon.polygonContains([[0, 0], [0, 1], [1, 1], [1, 0]], [0.5, 0.5]), true); + test.end(); +}); + +tape("polygonContains(polygon, point) returns the expected value for open clockwise polygons", function(test) { + test.equal(polygon.polygonContains([[0, 0], [1, 0], [1, 1], [0, 1]], [0.5, 0.5]), true); + test.equal(polygon.polygonContains([[1, 1], [3, 2], [2, 3]], [1.5, 1.5]), true); + test.end(); +}); diff --git a/test/hull-test.js b/test/hull-test.js index 49c868b..73b834b 100644 --- a/test/hull-test.js +++ b/test/hull-test.js @@ -1,33 +1,33 @@ var tape = require("tape"), polygon = require("../"); -tape("hull(points) returns null if points has fewer than three elements", function(test) { - test.equal(polygon.hull([]), null); - test.equal(polygon.hull([[0, 1]]), null); - test.equal(polygon.hull([[0, 1], [1, 0]]), null); +tape("polygonHull(points) returns null if points has fewer than three elements", function(test) { + test.equal(polygon.polygonHull([]), null); + test.equal(polygon.polygonHull([[0, 1]]), null); + test.equal(polygon.polygonHull([[0, 1], [1, 0]]), null); test.end(); }); -tape("hull(points) returns the convex hull of the specified points", function(test) { - test.deepEqual(polygon.hull([[200, 200], [760, 300], [500, 500]]), [[760, 300], [200, 200], [500, 500]]); - test.deepEqual(polygon.hull([[200, 200], [760, 300], [500, 500], [400, 400]]), [[760, 300], [200, 200], [500, 500]]); +tape("polygonHull(points) returns the convex hull of the specified points", function(test) { + test.deepEqual(polygon.polygonHull([[200, 200], [760, 300], [500, 500]]), [[760, 300], [200, 200], [500, 500]]); + test.deepEqual(polygon.polygonHull([[200, 200], [760, 300], [500, 500], [400, 400]]), [[760, 300], [200, 200], [500, 500]]); test.end(); }); -tape("hull(points) handles points with duplicate ordinates", function(test) { - test.deepEqual(polygon.hull([[-10, -10], [10, 10], [10, -10], [-10, 10]]), [[10, 10], [10, -10], [-10, -10], [-10, 10]]); +tape("polygonHull(points) handles points with duplicate ordinates", function(test) { + test.deepEqual(polygon.polygonHull([[-10, -10], [10, 10], [10, -10], [-10, 10]]), [[10, 10], [10, -10], [-10, -10], [-10, 10]]); test.end(); }); -tape("hull(points) handles overlapping upper and lower hulls", function(test) { - test.deepEqual(polygon.hull([[0, -10], [0, 10], [0, 0], [10, 0], [-10, 0]]), [[10, 0], [0, -10], [-10, 0], [0, 10]]); +tape("polygonHull(points) handles overlapping upper and lower hulls", function(test) { + test.deepEqual(polygon.polygonHull([[0, -10], [0, 10], [0, 0], [10, 0], [-10, 0]]), [[10, 0], [0, -10], [-10, 0], [0, 10]]); test.end(); }); // Cases below taken from http://uva.onlinejudge.org/external/6/681.html -tape("hull(points) handles various non-trivial hulls", function(test) { - test.deepEqual(polygon.hull([[60, 20], [250, 140], [180, 170], [79, 140], [50, 60], [60, 20]]), [[250, 140], [60, 20], [50, 60], [79, 140], [180, 170]]); - test.deepEqual(polygon.hull([[50, 60], [60, 20], [70, 45], [100, 70], [125, 90], [200, 113], [250, 140], [180, 170], [105, 140], [79, 140], [60, 85], [50, 60]]), [[250, 140], [60, 20], [50, 60], [79, 140], [180, 170]]); - test.deepEqual(polygon.hull([[30, 30], [50, 60], [60, 20], [70, 45], [86, 39], [112, 60], [200, 113], [250, 50], [300, 200], [130, 240], [76, 150], [47, 76], [36, 40], [33, 35], [30, 30]]), [[300, 200], [250, 50], [60, 20], [30, 30], [47, 76], [76, 150], [130, 240]]); +tape("polygonHull(points) handles various non-trivial hulls", function(test) { + test.deepEqual(polygon.polygonHull([[60, 20], [250, 140], [180, 170], [79, 140], [50, 60], [60, 20]]), [[250, 140], [60, 20], [50, 60], [79, 140], [180, 170]]); + test.deepEqual(polygon.polygonHull([[50, 60], [60, 20], [70, 45], [100, 70], [125, 90], [200, 113], [250, 140], [180, 170], [105, 140], [79, 140], [60, 85], [50, 60]]), [[250, 140], [60, 20], [50, 60], [79, 140], [180, 170]]); + test.deepEqual(polygon.polygonHull([[30, 30], [50, 60], [60, 20], [70, 45], [86, 39], [112, 60], [200, 113], [250, 50], [300, 200], [130, 240], [76, 150], [47, 76], [36, 40], [33, 35], [30, 30]]), [[300, 200], [250, 50], [60, 20], [30, 30], [47, 76], [76, 150], [130, 240]]); test.end(); }); diff --git a/test/inside-test.js b/test/inside-test.js deleted file mode 100644 index d4e8003..0000000 --- a/test/inside-test.js +++ /dev/null @@ -1,28 +0,0 @@ -var tape = require("tape"), - polygon = require("../"); - -tape("inside(polygon, point) returns the expected value for closed counterclockwise polygons", function(test) { - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, 0.5]), true); - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [1.5, 0.5]), false); - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [-0.5, 0.5]), false); - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, 1.5]), false); - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]], [0.5, -0.5]), false); - test.end(); -}); - -tape("inside(polygon, point) returns the expected value for closed clockwise polygons", function(test) { - test.equal(polygon.inside([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]], [0.5, 0.5]), true); - test.equal(polygon.inside([[1, 1], [3, 2], [2, 3], [1, 1]], [1.5, 1.5]), true); - test.end(); -}); - -tape("inside(polygon, point) returns the expected value for open counterclockwise polygons", function(test) { - test.equal(polygon.inside([[0, 0], [0, 1], [1, 1], [1, 0]], [0.5, 0.5]), true); - test.end(); -}); - -tape("inside(polygon, point) returns the expected value for open clockwise polygons", function(test) { - test.equal(polygon.inside([[0, 0], [1, 0], [1, 1], [0, 1]], [0.5, 0.5]), true); - test.equal(polygon.inside([[1, 1], [3, 2], [2, 3]], [1.5, 1.5]), true); - test.end(); -}); diff --git a/test/length-test.js b/test/length-test.js new file mode 100644 index 0000000..3cf1178 --- /dev/null +++ b/test/length-test.js @@ -0,0 +1,24 @@ +var tape = require("tape"), + polygon = require("../"); + +tape("polygonLength(polygon) returns the expected value for closed counterclockwise polygons", function(test) { + test.equal(polygon.polygonLength([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), 4); + test.end(); +}); + +tape("polygonLength(polygon) returns the expected value for closed clockwise polygons", function(test) { + test.equal(polygon.polygonLength([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), 4); + test.equal(polygon.polygonLength([[1, 1], [3, 2], [2, 3], [1, 1]]), Math.sqrt(20) + Math.sqrt(2)); + test.end(); +}); + +tape("polygonLength(polygon) returns the expected value for open counterclockwise polygons", function(test) { + test.equal(polygon.polygonLength([[0, 0], [0, 1], [1, 1], [1, 0]]), 4); + test.end(); +}); + +tape("polygonLength(polygon) returns the expected value for open clockwise polygons", function(test) { + test.equal(polygon.polygonLength([[0, 0], [1, 0], [1, 1], [0, 1]]), 4); + test.equal(polygon.polygonLength([[1, 1], [3, 2], [2, 3]]), Math.sqrt(20) + Math.sqrt(2)); + test.end(); +}); diff --git a/test/perimeter-test.js b/test/perimeter-test.js deleted file mode 100644 index e6b13df..0000000 --- a/test/perimeter-test.js +++ /dev/null @@ -1,24 +0,0 @@ -var tape = require("tape"), - polygon = require("../"); - -tape("perimeter(polygon) returns the expected value for closed counterclockwise polygons", function(test) { - test.equal(polygon.perimeter([[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]), 4); - test.end(); -}); - -tape("perimeter(polygon) returns the expected value for closed clockwise polygons", function(test) { - test.equal(polygon.perimeter([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]), 4); - test.equal(polygon.perimeter([[1, 1], [3, 2], [2, 3], [1, 1]]), Math.sqrt(20) + Math.sqrt(2)); - test.end(); -}); - -tape("perimeter(polygon) returns the expected value for open counterclockwise polygons", function(test) { - test.equal(polygon.perimeter([[0, 0], [0, 1], [1, 1], [1, 0]]), 4); - test.end(); -}); - -tape("perimeter(polygon) returns the expected value for open clockwise polygons", function(test) { - test.equal(polygon.perimeter([[0, 0], [1, 0], [1, 1], [0, 1]]), 4); - test.equal(polygon.perimeter([[1, 1], [3, 2], [2, 3]]), Math.sqrt(20) + Math.sqrt(2)); - test.end(); -});