@thi.ng/geom-clip-line 2.2.3 → 2.3.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-12-22T21:47:07Z
3
+ - **Last updated**: 2023-01-10T15:20:18Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,12 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [2.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-clip-line@2.3.0) (2023-01-10)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add clipPolylineWith() ([372db85](https://github.com/thi-ng/umbrella/commit/372db85))
17
+
12
18
  ## [2.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-clip-line@2.2.0) (2022-12-10)
13
19
 
14
20
  #### 🚀 Features
package/README.md CHANGED
@@ -22,11 +22,17 @@ This project is part of the
22
22
 
23
23
  2D line clipping (Liang-Barsky). This is a support package for [@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/develop/packages/geom).
24
24
 
25
- Current implementation is based on [toxiclibs](http://toxiclibs.org)
26
- (Java) and Clojure version [thi.ng/geom-clj](http://thi.ng/geom-clj).
25
+ Current implementation is partially based on [toxiclibs](http://toxiclibs.org)
26
+ (Java) and Clojure version [thi.ng/geom-clj](http://thi.ng/geom-clj). Also see
27
+ [@thi.ng/geom-clip-poly](https://github.com/thi-ng/umbrella/blob/develop/packages/geom-clip-poly)
28
+ sister package.
27
29
 
28
- This package has been extracted from the former (now obsolete)
29
- @thi.ng/geom-clip package.
30
+ The following main functions are provided:
31
+
32
+ - [`clipLinePoly()`](https://docs.thi.ng/umbrella/geom-clip-line/functions/clipLinePoly.html)
33
+ - [`clipLineSegmentPoly()`](https://docs.thi.ng/umbrella/geom-clip-line/functions/clipLineSegmentPoly.html)
34
+ - [`clipPolylinePoly()`](https://docs.thi.ng/umbrella/geom-clip-line/functions/clipPolylinePoly.html)
35
+ - [`liangBarsky2()`](https://docs.thi.ng/umbrella/geom-clip-line/functions/liangBarsky2.html)
30
36
 
31
37
  ## Status
32
38
 
@@ -58,7 +64,7 @@ For Node.js REPL:
58
64
  const geomClipLine = await import("@thi.ng/geom-clip-line");
59
65
  ```
60
66
 
61
- Package sizes (brotli'd, pre-treeshake): ESM: 661 bytes
67
+ Package sizes (brotli'd, pre-treeshake): ESM: 757 bytes
62
68
 
63
69
  ## Dependencies
64
70
 
@@ -70,12 +76,24 @@ Package sizes (brotli'd, pre-treeshake): ESM: 661 bytes
70
76
 
71
77
  [Generated API docs](https://docs.thi.ng/umbrella/geom-clip-line/)
72
78
 
73
- - `liangBarsky2`
74
- - `liangBarksy2Raw`
75
-
76
79
  ```ts
77
- import { liangBarsky2 } from "@thi.ng/geom-clip-line";
78
-
80
+ import { clipPolylinePoly, liangBarsky2 } from "@thi.ng/geom-clip-line";
81
+
82
+ clipPolylinePoly(
83
+ // polyline vertices
84
+ [[10, -50], [30, 30], [-50, 50], [150, 50], [70, 70], [90, 150]],
85
+ // boundary polygon vertices
86
+ [[0, 0], [100, 0], [100, 100], [0, 100]]
87
+ );
88
+ // result is 3 polylines:
89
+ // (since the original is temporarily leaving the poly)
90
+ // [
91
+ // [ [ 22.5, 0 ], [ 30, 30 ], [ 0, 37.5 ] ],
92
+ // [ [ 0, 50 ], [ 100, 50 ] ],
93
+ // [ [ 100, 62.5 ], [ 70, 70 ], [ 77.5, 100 ] ]
94
+ // ]
95
+
96
+ // Liang-Barsky is optimized for rectangular clipping regions
79
97
  liangBarsky2(
80
98
  // line end points
81
99
  [-10, -20], [30, 400],
@@ -111,4 +129,4 @@ If this project contributes to an academic publication, please cite it as:
111
129
 
112
130
  ## License
113
131
 
114
- © 2013 - 2022 Karsten Schmidt // Apache License 2.0
132
+ © 2013 - 2023 Karsten Schmidt // Apache License 2.0
package/clip-poly.d.ts CHANGED
@@ -1,14 +1,27 @@
1
1
  import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
2
2
  /**
3
- * Computes all intersection points of the infinite line defined by `a`,
4
- * `b` with the given polygon. Returns an array of segments where the
5
- * line is inside the polygon.
3
+ * Computes all intersection points of the **infinite** line defined by `a`, `b`
4
+ * with the given polygon. Returns an array of segments where the line is inside
5
+ * the polygon.
6
6
  *
7
- * @param a -
8
- * @param b -
9
- * @param poly -
7
+ * @remarks
8
+ * "Infinite" here means the line extends indefinitely on either side and
9
+ * intersections are found also outside the segment a..b. If only intra-segment
10
+ * intersections are desired, use {@link clipLineSegmentPoly} instead.
11
+ *
12
+ * @param a
13
+ * @param b
14
+ * @param poly
10
15
  */
11
16
  export declare const clipLinePoly: (a: ReadonlyVec, b: ReadonlyVec, poly: ReadonlyVec[]) => Vec[][] | undefined;
17
+ /**
18
+ * Similar to {@link clipLinePoly}, but only considers intersections within the
19
+ * given line segment.
20
+ *
21
+ * @param a
22
+ * @param b
23
+ * @param poly
24
+ */
12
25
  export declare const clipLineSegmentPoly: (a: ReadonlyVec, b: ReadonlyVec, poly: ReadonlyVec[]) => Vec[][] | undefined;
13
26
  /**
14
27
  * Similar to {@link clipLineSegmentPoly}, but for polylines. Returns array of
package/clip-poly.js CHANGED
@@ -3,18 +3,31 @@ 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
5
  /**
6
- * Computes all intersection points of the infinite line defined by `a`,
7
- * `b` with the given polygon. Returns an array of segments where the
8
- * line is inside the polygon.
6
+ * Computes all intersection points of the **infinite** line defined by `a`, `b`
7
+ * with the given polygon. Returns an array of segments where the line is inside
8
+ * the polygon.
9
9
  *
10
- * @param a -
11
- * @param b -
12
- * @param poly -
10
+ * @remarks
11
+ * "Infinite" here means the line extends indefinitely on either side and
12
+ * intersections are found also outside the segment a..b. If only intra-segment
13
+ * intersections are desired, use {@link clipLineSegmentPoly} instead.
14
+ *
15
+ * @param a
16
+ * @param b
17
+ * @param poly
13
18
  */
14
19
  export const clipLinePoly = (a, b, poly) => {
15
20
  const isecs = intersectRayPolylineAll(a, direction2([], a, b), poly, true).isec;
16
21
  return isecs ? collectSegments(isecs) : undefined;
17
22
  };
23
+ /**
24
+ * Similar to {@link clipLinePoly}, but only considers intersections within the
25
+ * given line segment.
26
+ *
27
+ * @param a
28
+ * @param b
29
+ * @param poly
30
+ */
18
31
  export const clipLineSegmentPoly = (a, b, poly) => {
19
32
  const isecs = intersectLinePolylineAll(a, b, poly, true).isec;
20
33
  const isAInside = pointInPolygon2(a, poly);
package/clip-with.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import type { Predicate2 } from "@thi.ng/api";
2
+ import type { ReadonlyVec } from "@thi.ng/vectors";
3
+ /**
4
+ * Segments given polyline based on given predicate and `step` size. Returns
5
+ * array of segmented vertex chunks.
6
+ *
7
+ * @remarks
8
+ * Vertices are processed pairwise using given `step` size (default: 1). As long
9
+ * as the predicate is true, vertices are collected into the current chunk. If
10
+ * the predicate returns false, the current chunk is terminated and depending on
11
+ * `keepLast`, the current vertex (i.e. for which the predicate failed) is still
12
+ * added or not. If `keepLast` is false and the current chunk only included one
13
+ * other vertex, that entire chunk will be discarded.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const pts = [[0, 0], [1, 0], [1, 1], [2, 1], [3, 1], [4, 0], [5, 0]];
18
+ *
19
+ * // isolate horizontal chunks
20
+ * clipPolylineWith((a, b) => a[1] == b[1], pts)
21
+ * // [
22
+ * // [[0, 0], [1, 0]],
23
+ * // [[1, 1], [2, 1], [3, 1]],
24
+ * // [[4, 0], [5, 0]]
25
+ * // ]
26
+ *
27
+ * // isolate sloped chunks
28
+ * clipPolylineWith((a, b) => a[1] != b[1], pts)
29
+ * // [
30
+ * // [[1, 0], [1, 1]],
31
+ * // [[3, 1], [4, 0]]
32
+ * // ]
33
+ * ```
34
+ *
35
+ * @param pred
36
+ * @param pts
37
+ * @param step
38
+ * @param keepLast
39
+ */
40
+ export declare const clipPolylineWith: (pred: Predicate2<ReadonlyVec>, pts: ReadonlyVec[], step?: number, keepLast?: boolean) => ReadonlyVec[][];
41
+ //# sourceMappingURL=clip-with.d.ts.map
package/clip-with.js ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Segments given polyline based on given predicate and `step` size. Returns
3
+ * array of segmented vertex chunks.
4
+ *
5
+ * @remarks
6
+ * Vertices are processed pairwise using given `step` size (default: 1). As long
7
+ * as the predicate is true, vertices are collected into the current chunk. If
8
+ * the predicate returns false, the current chunk is terminated and depending on
9
+ * `keepLast`, the current vertex (i.e. for which the predicate failed) is still
10
+ * added or not. If `keepLast` is false and the current chunk only included one
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
+ }
65
+ }
66
+ $terminate(pts.length - step);
67
+ return segs;
68
+ };
package/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./clip-poly.js";
2
+ export * from "./clip-with.js";
2
3
  export * from "./liang-barsky.js";
3
4
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./clip-poly.js";
2
+ export * from "./clip-with.js";
2
3
  export * from "./liang-barsky.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom-clip-line",
3
- "version": "2.2.3",
3
+ "version": "2.3.0",
4
4
  "description": "2D line clipping (Liang-Barsky)",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -34,13 +34,13 @@
34
34
  "test": "testament test"
35
35
  },
36
36
  "dependencies": {
37
- "@thi.ng/api": "^8.6.2",
38
- "@thi.ng/geom-isec": "^2.1.40",
39
- "@thi.ng/vectors": "^7.5.29"
37
+ "@thi.ng/api": "^8.6.3",
38
+ "@thi.ng/geom-isec": "^2.1.42",
39
+ "@thi.ng/vectors": "^7.5.31"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@microsoft/api-extractor": "^7.33.7",
43
- "@thi.ng/testament": "^0.3.8",
43
+ "@thi.ng/testament": "^0.3.9",
44
44
  "rimraf": "^3.0.2",
45
45
  "tools": "^0.0.1",
46
46
  "typedoc": "^0.23.22",
@@ -73,6 +73,9 @@
73
73
  "./clip-poly": {
74
74
  "default": "./clip-poly.js"
75
75
  },
76
+ "./clip-with": {
77
+ "default": "./clip-with.js"
78
+ },
76
79
  "./liang-barsky": {
77
80
  "default": "./liang-barsky.js"
78
81
  }
@@ -84,5 +87,5 @@
84
87
  ],
85
88
  "year": 2013
86
89
  },
87
- "gitHead": "bc6f7f5e2765bb96fe64db804eaf4b2443b47fc6\n"
90
+ "gitHead": "3f0b3e2a7c82aefc7e46fb4338369836b5e1b8cf\n"
88
91
  }