-
-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(geom-clip-line): add clipPolylineWith()
- Loading branch information
1 parent
daa7c32
commit 372db85
Showing
3 changed files
with
79 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import type { Predicate2 } from "@thi.ng/api"; | ||
import type { ReadonlyVec } from "@thi.ng/vectors"; | ||
|
||
/** | ||
* Segments given polyline based on given predicate and `step` size. Returns | ||
* array of segmented vertex chunks. | ||
* | ||
* @remarks | ||
* Vertices are processed pairwise using given `step` size (default: 1). As long | ||
* as the predicate is true, vertices are collected into the current chunk. If | ||
* the predicate returns false, the current chunk is terminated and depending on | ||
* `keepLast`, the current vertex (i.e. for which the predicate failed) is still | ||
* added or not. If `keepLast` is false and the current chunk only included one | ||
* other vertex, that entire chunk will be discarded. | ||
* | ||
* @example | ||
* ```ts | ||
* const pts = [[0, 0], [1, 0], [1, 1], [2, 1], [3, 1], [4, 0], [5, 0]]; | ||
* | ||
* // isolate horizontal chunks | ||
* clipPolylineWith((a, b) => a[1] == b[1], pts) | ||
* // [ | ||
* // [[0, 0], [1, 0]], | ||
* // [[1, 1], [2, 1], [3, 1]], | ||
* // [[4, 0], [5, 0]] | ||
* // ] | ||
* | ||
* // isolate sloped chunks | ||
* clipPolylineWith((a, b) => a[1] != b[1], pts) | ||
* // [ | ||
* // [[1, 0], [1, 1]], | ||
* // [[3, 1], [4, 0]] | ||
* // ] | ||
* ``` | ||
* | ||
* @param pred | ||
* @param pts | ||
* @param step | ||
* @param keepLast | ||
*/ | ||
export const clipPolylineWith = ( | ||
pred: Predicate2<ReadonlyVec>, | ||
pts: ReadonlyVec[], | ||
step = 1, | ||
keepLast = true | ||
) => { | ||
const segs: ReadonlyVec[][] = []; | ||
let last = -1; | ||
|
||
const $terminate = (i: number) => { | ||
if (last !== -1) { | ||
if (keepLast) { | ||
segs[segs.length - 1].push(pts[i]); | ||
} else if (segs[segs.length - 1].length < 2) { | ||
segs.pop(); | ||
} | ||
} | ||
last = -1; | ||
}; | ||
|
||
for (let i = 0, n = pts.length - step; i < n; i++) { | ||
if (pred(pts[i], pts[i + step])) { | ||
if (last === -1) { | ||
segs.push([pts[i]]); | ||
last = i; | ||
} else { | ||
segs[segs.length - 1].push(pts[i]); | ||
} | ||
} else { | ||
$terminate(i); | ||
} | ||
} | ||
$terminate(pts.length - step); | ||
return segs; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from "./clip-poly.js"; | ||
export * from "./clip-with.js"; | ||
export * from "./liang-barsky.js"; |