@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.
- package/README.md +216 -0
- package/es/index.js +15 -0
- package/es/src/ckmeans.js +204 -0
- package/es/src/closest.js +19 -0
- package/es/src/largestRect.js +324 -0
- package/es/src/lineIntersection.js +22 -0
- package/es/src/path2polygon.js +23 -0
- package/es/src/pointDistance.js +10 -0
- package/es/src/pointDistanceSquared.js +10 -0
- package/es/src/pointRotate.js +18 -0
- package/es/src/polygonInside.js +26 -0
- package/es/src/polygonRayCast.js +101 -0
- package/es/src/polygonRotate.js +17 -0
- package/es/src/segmentBoxContains.js +57 -0
- package/es/src/segmentsIntersect.js +15 -0
- package/es/src/shapeEdgePoint.js +45 -0
- package/es/src/simplify.js +96 -0
- package/package.json +40 -0
- package/umd/d3plus-math.full.js +1024 -0
- package/umd/d3plus-math.full.js.map +1 -0
- package/umd/d3plus-math.full.min.js +289 -0
- package/umd/d3plus-math.js +939 -0
- package/umd/d3plus-math.js.map +1 -0
- package/umd/d3plus-math.min.js +289 -0
|
@@ -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
|
+
}
|