@thi.ng/geom-clip-line 2.3.49 → 2.3.51
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/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/clip-poly.js +60 -81
- package/clip-with.js +29 -66
- package/liang-barsky.js +57 -82
- package/package.json +9 -6
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/clip-poly.js
CHANGED
|
@@ -2,91 +2,70 @@ import { intersectLinePolylineAll } from "@thi.ng/geom-isec/line-poly";
|
|
|
2
2
|
import { pointInPolygon2 } from "@thi.ng/geom-isec/point";
|
|
3
3
|
import { intersectRayPolylineAll } from "@thi.ng/geom-isec/ray-poly";
|
|
4
4
|
import { direction2 } from "@thi.ng/vectors/direction";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* intersections are desired, use {@link clipLineSegmentPoly} instead.
|
|
14
|
-
*
|
|
15
|
-
* @param a
|
|
16
|
-
* @param b
|
|
17
|
-
* @param poly
|
|
18
|
-
*/
|
|
19
|
-
export const clipLinePoly = (a, b, poly) => {
|
|
20
|
-
const isecs = intersectRayPolylineAll(a, direction2([], a, b), poly, true).isec;
|
|
21
|
-
return isecs ? collectSegments(isecs) : undefined;
|
|
5
|
+
const clipLinePoly = (a, b, poly) => {
|
|
6
|
+
const isecs = intersectRayPolylineAll(
|
|
7
|
+
a,
|
|
8
|
+
direction2([], a, b),
|
|
9
|
+
poly,
|
|
10
|
+
true
|
|
11
|
+
).isec;
|
|
12
|
+
return isecs ? collectSegments(isecs) : void 0;
|
|
22
13
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
const clipLineSegmentPoly = (a, b, poly) => {
|
|
15
|
+
const isecs = intersectLinePolylineAll(a, b, poly, true).isec;
|
|
16
|
+
const isAInside = pointInPolygon2(a, poly);
|
|
17
|
+
const isBInside = pointInPolygon2(b, poly);
|
|
18
|
+
if (!isecs) {
|
|
19
|
+
return isAInside && isBInside ? [[a, b]] : void 0;
|
|
20
|
+
}
|
|
21
|
+
isAInside && isecs.unshift(a);
|
|
22
|
+
isBInside && isecs.push(b);
|
|
23
|
+
return collectSegments(isecs);
|
|
24
|
+
};
|
|
25
|
+
const clipPolylinePoly = (pts, poly) => {
|
|
26
|
+
let res = [];
|
|
27
|
+
if (pts.length < 2)
|
|
28
|
+
return res;
|
|
29
|
+
let isAInside = pointInPolygon2(pts[0], poly);
|
|
30
|
+
for (let i = 0, n = pts.length - 1; i < n; i++) {
|
|
31
|
+
const a = pts[i];
|
|
32
|
+
const b = pts[i + 1];
|
|
34
33
|
const isBInside = pointInPolygon2(b, poly);
|
|
34
|
+
const isecs = intersectLinePolylineAll(a, b, poly, true).isec;
|
|
35
35
|
if (!isecs) {
|
|
36
|
-
|
|
36
|
+
if (isAInside && isBInside) {
|
|
37
|
+
if (res.length)
|
|
38
|
+
res[res.length - 1].push(b);
|
|
39
|
+
else
|
|
40
|
+
res.push([a, b]);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
isAInside && isecs.unshift(a);
|
|
44
|
+
isBInside && isecs.push(b);
|
|
45
|
+
const [first, ...segments] = collectSegments(isecs);
|
|
46
|
+
if (isAInside) {
|
|
47
|
+
if (res.length)
|
|
48
|
+
res[res.length - 1].push(first[1]);
|
|
49
|
+
else
|
|
50
|
+
res.push(first);
|
|
51
|
+
} else {
|
|
52
|
+
res.push(first);
|
|
53
|
+
}
|
|
54
|
+
res.push(...segments);
|
|
37
55
|
}
|
|
38
|
-
isAInside
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Similar to {@link clipLineSegmentPoly}, but for polylines. Returns array of
|
|
44
|
-
* new vertex chunks where the given polyline is inside the given bounding poly.
|
|
45
|
-
*
|
|
46
|
-
* @param pts
|
|
47
|
-
* @param poly
|
|
48
|
-
*/
|
|
49
|
-
export const clipPolylinePoly = (pts, poly) => {
|
|
50
|
-
let res = [];
|
|
51
|
-
if (pts.length < 2)
|
|
52
|
-
return res;
|
|
53
|
-
let isAInside = pointInPolygon2(pts[0], poly);
|
|
54
|
-
for (let i = 0, n = pts.length - 1; i < n; i++) {
|
|
55
|
-
const a = pts[i];
|
|
56
|
-
const b = pts[i + 1];
|
|
57
|
-
const isBInside = pointInPolygon2(b, poly);
|
|
58
|
-
const isecs = intersectLinePolylineAll(a, b, poly, true).isec;
|
|
59
|
-
if (!isecs) {
|
|
60
|
-
if (isAInside && isBInside) {
|
|
61
|
-
if (res.length)
|
|
62
|
-
res[res.length - 1].push(b);
|
|
63
|
-
else
|
|
64
|
-
res.push([a, b]);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
isAInside && isecs.unshift(a);
|
|
69
|
-
isBInside && isecs.push(b);
|
|
70
|
-
const [first, ...segments] = collectSegments(isecs);
|
|
71
|
-
if (isAInside) {
|
|
72
|
-
if (res.length)
|
|
73
|
-
res[res.length - 1].push(first[1]);
|
|
74
|
-
else
|
|
75
|
-
res.push(first);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
res.push(first);
|
|
79
|
-
}
|
|
80
|
-
res.push(...segments);
|
|
81
|
-
}
|
|
82
|
-
isAInside = isBInside;
|
|
83
|
-
}
|
|
84
|
-
return res;
|
|
56
|
+
isAInside = isBInside;
|
|
57
|
+
}
|
|
58
|
+
return res;
|
|
85
59
|
};
|
|
86
60
|
const collectSegments = (isecs) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
const segments = [];
|
|
62
|
+
for (let i = 0, n = isecs.length - 1; i < n; i += 2) {
|
|
63
|
+
segments.push([isecs[i], isecs[i + 1]]);
|
|
64
|
+
}
|
|
65
|
+
return segments;
|
|
66
|
+
};
|
|
67
|
+
export {
|
|
68
|
+
clipLinePoly,
|
|
69
|
+
clipLineSegmentPoly,
|
|
70
|
+
clipPolylinePoly
|
|
92
71
|
};
|
package/clip-with.js
CHANGED
|
@@ -1,68 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* other vertex, that entire chunk will be discarded.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* const pts = [[0, 0], [1, 0], [1, 1], [2, 1], [3, 1], [4, 0], [5, 0]];
|
|
16
|
-
*
|
|
17
|
-
* // isolate horizontal chunks
|
|
18
|
-
* clipPolylineWith((a, b) => a[1] == b[1], pts)
|
|
19
|
-
* // [
|
|
20
|
-
* // [[0, 0], [1, 0]],
|
|
21
|
-
* // [[1, 1], [2, 1], [3, 1]],
|
|
22
|
-
* // [[4, 0], [5, 0]]
|
|
23
|
-
* // ]
|
|
24
|
-
*
|
|
25
|
-
* // isolate sloped chunks
|
|
26
|
-
* clipPolylineWith((a, b) => a[1] != b[1], pts)
|
|
27
|
-
* // [
|
|
28
|
-
* // [[1, 0], [1, 1]],
|
|
29
|
-
* // [[3, 1], [4, 0]]
|
|
30
|
-
* // ]
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* @param pred
|
|
34
|
-
* @param pts
|
|
35
|
-
* @param step
|
|
36
|
-
* @param keepLast
|
|
37
|
-
*/
|
|
38
|
-
export const clipPolylineWith = (pred, pts, step = 1, keepLast = true) => {
|
|
39
|
-
const segs = [];
|
|
40
|
-
let last = -1;
|
|
41
|
-
const $terminate = (i) => {
|
|
42
|
-
if (last !== -1) {
|
|
43
|
-
if (keepLast) {
|
|
44
|
-
segs[segs.length - 1].push(pts[i]);
|
|
45
|
-
}
|
|
46
|
-
else if (segs[segs.length - 1].length < 2) {
|
|
47
|
-
segs.pop();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
last = -1;
|
|
51
|
-
};
|
|
52
|
-
for (let i = 0, n = pts.length - step; i < n; i++) {
|
|
53
|
-
if (pred(pts[i], pts[i + step])) {
|
|
54
|
-
if (last === -1) {
|
|
55
|
-
segs.push([pts[i]]);
|
|
56
|
-
last = i;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
segs[segs.length - 1].push(pts[i]);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
$terminate(i);
|
|
64
|
-
}
|
|
1
|
+
const clipPolylineWith = (pred, pts, step = 1, keepLast = true) => {
|
|
2
|
+
const segs = [];
|
|
3
|
+
let last = -1;
|
|
4
|
+
const $terminate = (i) => {
|
|
5
|
+
if (last !== -1) {
|
|
6
|
+
if (keepLast) {
|
|
7
|
+
segs[segs.length - 1].push(pts[i]);
|
|
8
|
+
} else if (segs[segs.length - 1].length < 2) {
|
|
9
|
+
segs.pop();
|
|
10
|
+
}
|
|
65
11
|
}
|
|
66
|
-
|
|
67
|
-
|
|
12
|
+
last = -1;
|
|
13
|
+
};
|
|
14
|
+
for (let i = 0, n = pts.length - step; i < n; i++) {
|
|
15
|
+
if (pred(pts[i], pts[i + step])) {
|
|
16
|
+
if (last === -1) {
|
|
17
|
+
segs.push([pts[i]]);
|
|
18
|
+
last = i;
|
|
19
|
+
} else {
|
|
20
|
+
segs[segs.length - 1].push(pts[i]);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
$terminate(i);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
$terminate(pts.length - step);
|
|
27
|
+
return segs;
|
|
28
|
+
};
|
|
29
|
+
export {
|
|
30
|
+
clipPolylineWith
|
|
68
31
|
};
|
package/liang-barsky.js
CHANGED
|
@@ -1,84 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
export const liangBarsky2 = (a, b, min, max, ca = [], cb = []) => {
|
|
21
|
-
const res = liangBarsky2Raw(a[0], a[1], b[0], b[1], min[0], min[1], max[0], max[1]);
|
|
22
|
-
if (!res)
|
|
23
|
-
return;
|
|
24
|
-
ca[0] = res[0];
|
|
25
|
-
ca[1] = res[1];
|
|
26
|
-
cb[0] = res[2];
|
|
27
|
-
cb[1] = res[3];
|
|
28
|
-
return [ca, cb, res[4], res[5]];
|
|
1
|
+
const liangBarsky2 = (a, b, min, max, ca = [], cb = []) => {
|
|
2
|
+
const res = liangBarsky2Raw(
|
|
3
|
+
a[0],
|
|
4
|
+
a[1],
|
|
5
|
+
b[0],
|
|
6
|
+
b[1],
|
|
7
|
+
min[0],
|
|
8
|
+
min[1],
|
|
9
|
+
max[0],
|
|
10
|
+
max[1]
|
|
11
|
+
);
|
|
12
|
+
if (!res)
|
|
13
|
+
return;
|
|
14
|
+
ca[0] = res[0];
|
|
15
|
+
ca[1] = res[1];
|
|
16
|
+
cb[0] = res[2];
|
|
17
|
+
cb[1] = res[3];
|
|
18
|
+
return [ca, cb, res[4], res[5]];
|
|
29
19
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return true;
|
|
70
|
-
};
|
|
71
|
-
return clip(-dx, ax - minx) &&
|
|
72
|
-
clip(dx, maxx - ax) &&
|
|
73
|
-
clip(-dy, ay - miny) &&
|
|
74
|
-
clip(dy, maxy - ay)
|
|
75
|
-
? [
|
|
76
|
-
alpha * dx + ax,
|
|
77
|
-
alpha * dy + ay,
|
|
78
|
-
beta * dx + ax,
|
|
79
|
-
beta * dy + ay,
|
|
80
|
-
alpha,
|
|
81
|
-
beta,
|
|
82
|
-
]
|
|
83
|
-
: undefined;
|
|
20
|
+
const liangBarsky2Raw = (ax, ay, bx, by, minx, miny, maxx, maxy) => {
|
|
21
|
+
const dx = bx - ax;
|
|
22
|
+
const dy = by - ay;
|
|
23
|
+
let alpha = 0;
|
|
24
|
+
let beta = 1;
|
|
25
|
+
const clip = (p, q) => {
|
|
26
|
+
if (p < 0) {
|
|
27
|
+
const r = q / p;
|
|
28
|
+
if (r > beta) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (r > alpha) {
|
|
32
|
+
alpha = r;
|
|
33
|
+
}
|
|
34
|
+
} else if (p > 0) {
|
|
35
|
+
const r = q / p;
|
|
36
|
+
if (r < alpha) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (r < beta) {
|
|
40
|
+
beta = r;
|
|
41
|
+
}
|
|
42
|
+
} else if (q < 0) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
};
|
|
47
|
+
return clip(-dx, ax - minx) && clip(dx, maxx - ax) && clip(-dy, ay - miny) && clip(dy, maxy - ay) ? [
|
|
48
|
+
alpha * dx + ax,
|
|
49
|
+
alpha * dy + ay,
|
|
50
|
+
beta * dx + ax,
|
|
51
|
+
beta * dy + ay,
|
|
52
|
+
alpha,
|
|
53
|
+
beta
|
|
54
|
+
] : void 0;
|
|
55
|
+
};
|
|
56
|
+
export {
|
|
57
|
+
liangBarsky2,
|
|
58
|
+
liangBarsky2Raw
|
|
84
59
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/geom-clip-line",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.51",
|
|
4
4
|
"description": "2D line clipping (Liang-Barsky)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,12 +35,13 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/api": "^8.9.
|
|
37
|
-
"@thi.ng/geom-isec": "^2.1.
|
|
38
|
-
"@thi.ng/vectors": "^7.8.
|
|
38
|
+
"@thi.ng/api": "^8.9.12",
|
|
39
|
+
"@thi.ng/geom-isec": "^2.1.93",
|
|
40
|
+
"@thi.ng/vectors": "^7.8.10"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@microsoft/api-extractor": "^7.38.3",
|
|
44
|
+
"esbuild": "^0.19.8",
|
|
42
45
|
"rimraf": "^5.0.5",
|
|
43
46
|
"tools": "^0.0.1",
|
|
44
47
|
"typedoc": "^0.25.4",
|
|
@@ -85,5 +88,5 @@
|
|
|
85
88
|
],
|
|
86
89
|
"year": 2013
|
|
87
90
|
},
|
|
88
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "22e36fa838e5431d40165384918b395603bbd92f\n"
|
|
89
92
|
}
|