@d3plus/math 3.0.0-alpha.0

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.
@@ -0,0 +1,45 @@
1
+ var pi = Math.PI;
2
+ /**
3
+ @function shapeEdgePoint
4
+ @desc Calculates the x/y position of a point at the edge of a shape, from the center of the shape, given a specified pixel distance and radian angle.
5
+ @param {Number} angle The angle, in radians, of the offset point.
6
+ @param {Number} distance The pixel distance away from the origin.
7
+ @returns {String} [shape = "circle"] The type of shape, which can be either "circle" or "square".
8
+ */ export default function(angle, distance) {
9
+ var shape = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "circle";
10
+ if (angle < 0) angle = pi * 2 + angle;
11
+ if (shape === "square") {
12
+ var diagonal = 45 * (pi / 180);
13
+ var x = 0, y = 0;
14
+ if (angle < pi / 2) {
15
+ var tan = Math.tan(angle);
16
+ x += angle < diagonal ? distance : distance / tan;
17
+ y += angle < diagonal ? tan * distance : distance;
18
+ } else if (angle <= pi) {
19
+ var tan1 = Math.tan(pi - angle);
20
+ x -= angle < pi - diagonal ? distance / tan1 : distance;
21
+ y += angle < pi - diagonal ? distance : tan1 * distance;
22
+ } else if (angle < diagonal + pi) {
23
+ x -= distance;
24
+ y -= Math.tan(angle - pi) * distance;
25
+ } else if (angle < 3 * pi / 2) {
26
+ x -= distance / Math.tan(angle - pi);
27
+ y -= distance;
28
+ } else if (angle < 2 * pi - diagonal) {
29
+ x += distance / Math.tan(2 * pi - angle);
30
+ y -= distance;
31
+ } else {
32
+ x += distance;
33
+ y -= Math.tan(2 * pi - angle) * distance;
34
+ }
35
+ return [
36
+ x,
37
+ y
38
+ ];
39
+ } else if (shape === "circle") {
40
+ return [
41
+ distance * Math.cos(angle),
42
+ distance * Math.sin(angle)
43
+ ];
44
+ } else return null;
45
+ };
@@ -0,0 +1,96 @@
1
+ import pointDistanceSquared from "./pointDistanceSquared.js";
2
+ /**
3
+ @desc square distance from a point to a segment
4
+ @param {Array} point
5
+ @param {Array} segmentAnchor1
6
+ @param {Array} segmentAnchor2
7
+ @private
8
+ */ function getSqSegDist(p, p1, p2) {
9
+ var x = p1[0], y = p1[1];
10
+ var dx = p2[0] - x, dy = p2[1] - y;
11
+ if (dx !== 0 || dy !== 0) {
12
+ var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy);
13
+ if (t > 1) {
14
+ x = p2[0];
15
+ y = p2[1];
16
+ } else if (t > 0) {
17
+ x += dx * t;
18
+ y += dy * t;
19
+ }
20
+ }
21
+ dx = p[0] - x;
22
+ dy = p[1] - y;
23
+ return dx * dx + dy * dy;
24
+ }
25
+ /**
26
+ @desc basic distance-based simplification
27
+ @param {Array} polygon
28
+ @param {Number} sqTolerance
29
+ @private
30
+ */ function simplifyRadialDist(poly, sqTolerance) {
31
+ var point, prevPoint = poly[0];
32
+ var newPoints = [
33
+ prevPoint
34
+ ];
35
+ for(var i = 1, len = poly.length; i < len; i++){
36
+ point = poly[i];
37
+ if (pointDistanceSquared(point, prevPoint) > sqTolerance) {
38
+ newPoints.push(point);
39
+ prevPoint = point;
40
+ }
41
+ }
42
+ if (prevPoint !== point) newPoints.push(point);
43
+ return newPoints;
44
+ }
45
+ /**
46
+ @param {Array} polygon
47
+ @param {Number} first
48
+ @param {Number} last
49
+ @param {Number} sqTolerance
50
+ @param {Array} simplified
51
+ @private
52
+ */ function simplifyDPStep(poly, first, last, sqTolerance, simplified) {
53
+ var index, maxSqDist = sqTolerance;
54
+ for(var i = first + 1; i < last; i++){
55
+ var sqDist = getSqSegDist(poly[i], poly[first], poly[last]);
56
+ if (sqDist > maxSqDist) {
57
+ index = i;
58
+ maxSqDist = sqDist;
59
+ }
60
+ }
61
+ if (maxSqDist > sqTolerance) {
62
+ if (index - first > 1) simplifyDPStep(poly, first, index, sqTolerance, simplified);
63
+ simplified.push(poly[index]);
64
+ if (last - index > 1) simplifyDPStep(poly, index, last, sqTolerance, simplified);
65
+ }
66
+ }
67
+ /**
68
+ @desc simplification using Ramer-Douglas-Peucker algorithm
69
+ @param {Array} polygon
70
+ @param {Number} sqTolerance
71
+ @private
72
+ */ function simplifyDouglasPeucker(poly, sqTolerance) {
73
+ var last = poly.length - 1;
74
+ var simplified = [
75
+ poly[0]
76
+ ];
77
+ simplifyDPStep(poly, 0, last, sqTolerance, simplified);
78
+ simplified.push(poly[last]);
79
+ return simplified;
80
+ }
81
+ /**
82
+ @function largestRect
83
+ @desc Simplifies the points of a polygon using both the Ramer-Douglas-Peucker algorithm and basic distance-based simplification. Adapted to an ES6 module from the excellent [Simplify.js](http://mourner.github.io/simplify-js/).
84
+ @author Vladimir Agafonkin
85
+ @param {Array} poly An Array of points that represent a polygon.
86
+ @param {Number} [tolerance = 1] Affects the amount of simplification (in the same metric as the point coordinates).
87
+ @param {Boolean} [highestQuality = false] Excludes distance-based preprocessing step which leads to highest quality simplification but runs ~10-20 times slower.
88
+
89
+ */ export default function(poly) {
90
+ var tolerance = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 1, highestQuality = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false;
91
+ if (poly.length <= 2) return poly;
92
+ var sqTolerance = tolerance * tolerance;
93
+ poly = highestQuality ? poly : simplifyRadialDist(poly, sqTolerance);
94
+ poly = simplifyDouglasPeucker(poly, sqTolerance);
95
+ return poly;
96
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@d3plus/math",
3
+ "version": "3.0.0-alpha.0",
4
+ "description": "Mathematical functions to aid in calculating visualizations.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": "./es/index.js",
8
+ "browser": "./umd/d3plus-math.full.js",
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "sideEffects": false,
13
+ "files": [
14
+ "umd",
15
+ "es"
16
+ ],
17
+ "homepage": "https://d3plus.org",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/d3plus/d3plus.git",
21
+ "directory": "packages/math"
22
+ },
23
+ "keywords": [
24
+ "math",
25
+ "d3",
26
+ "d3plus",
27
+ "data",
28
+ "visualization"
29
+ ],
30
+ "scripts": {
31
+ "build:esm": "node ../../scripts/build-esm.js",
32
+ "build:umd": "node ../../scripts/build-umd.js",
33
+ "dev": "node ../../scripts/dev.js",
34
+ "test": "eslint index.js src/**/*.js && eslint --global=it test && mocha 'test/**/*-test.js'"
35
+ },
36
+ "dependencies": {
37
+ "d3-array": "^3.2.4",
38
+ "d3-polygon": "^3.0.1"
39
+ }
40
+ }