@thi.ng/geom-subdiv-curve 2.1.131 → 3.0.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 +37 -1
- package/README.md +57 -13
- package/api.d.ts +33 -33
- package/api.js +0 -58
- package/kernels.d.ts +58 -0
- package/kernels.js +73 -0
- package/package.json +10 -11
- package/subdivide.d.ts +14 -6
- package/subdivide.js +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
3
|
+
- **Last updated**: 2024-06-21T19:34:38Z
|
|
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,42 @@ 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
|
+
# [3.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-subdiv-curve@3.0.0) (2024-06-21)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- migrate types from [@thi.ng/geom-api](https://github.com/thi-ng/umbrella/tree/main/packages/geom-api) ([c7564f2](https://github.com/thi-ng/umbrella/commit/c7564f2))
|
|
17
|
+
- BREAKING CHANGE: migrate/internalize types from [@thi.ng/geom-api](https://github.com/thi-ng/umbrella/tree/main/packages/geom-api)
|
|
18
|
+
- add/migrate SubdivKernel
|
|
19
|
+
- update imports
|
|
20
|
+
- update deps
|
|
21
|
+
- update subdiv kernels ([cd69dd4](https://github.com/thi-ng/umbrella/commit/cd69dd4))
|
|
22
|
+
- BREAKING CHANGE: update SubdivKernel interface & impls
|
|
23
|
+
- update `SubdivKernel` fns to support both open/closed versions
|
|
24
|
+
- merge/rename open/closed kernels & remove obsolete
|
|
25
|
+
- SUBDIV_MID
|
|
26
|
+
- SUBDIV_THIRDS
|
|
27
|
+
- SUBDIV_CHAIKIN
|
|
28
|
+
- SUBDIV_CUBIC
|
|
29
|
+
- add SUBDIV_DLG kernel
|
|
30
|
+
- update subdivide() signature ([25576ca](https://github.com/thi-ng/umbrella/commit/25576ca))
|
|
31
|
+
- BREAKING CHANGE: update subdivide() signature
|
|
32
|
+
- only accept kernels as array
|
|
33
|
+
- add `closed` arg/flag
|
|
34
|
+
|
|
35
|
+
#### 🚀 Features
|
|
36
|
+
|
|
37
|
+
- add SUBDIV_DISPLACE higher-order kernel ([7655e50](https://github.com/thi-ng/umbrella/commit/7655e50))
|
|
38
|
+
- add support for passing multiple kernels to subdivide() ([03c5e54](https://github.com/thi-ng/umbrella/commit/03c5e54))
|
|
39
|
+
- update args to support multiple kernels as array
|
|
40
|
+
- update SUBDIV_DISPLACE ([a75f37c](https://github.com/thi-ng/umbrella/commit/a75f37c))
|
|
41
|
+
- update displace config to allow specifying normalized split positions
|
|
42
|
+
- add/update docs & example
|
|
43
|
+
|
|
44
|
+
#### ♻️ Refactoring
|
|
45
|
+
|
|
46
|
+
- update SUBDIV_DISPLACE, internal refactoring ([3e84ba8](https://github.com/thi-ng/umbrella/commit/3e84ba8))
|
|
47
|
+
|
|
12
48
|
### [2.1.86](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-subdiv-curve@2.1.86) (2023-11-09)
|
|
13
49
|
|
|
14
50
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://mastodon.thi.ng/@toxi)
|
|
8
8
|
|
|
9
9
|
> [!NOTE]
|
|
10
|
-
> This is one of
|
|
10
|
+
> This is one of 193 standalone projects, maintained as part
|
|
11
11
|
> of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo
|
|
12
12
|
> and anti-framework.
|
|
13
13
|
>
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
> GitHub](https://github.com/sponsors/postspectacular). Thank you! ❤️
|
|
16
16
|
|
|
17
17
|
- [About](#about)
|
|
18
|
+
- [Available subdivision schemes](#available-subdivision-schemes)
|
|
19
|
+
- [Chaikin subdivision](#chaikin-subdivision)
|
|
20
|
+
- [Cubic subdivision](#cubic-subdivision)
|
|
21
|
+
- [Dyn-Levin-Gregory subdivision](#dyn-levin-gregory-subdivision)
|
|
22
|
+
- [Displacement subdivision](#displacement-subdivision)
|
|
23
|
+
- [Split at midpoints](#split-at-midpoints)
|
|
24
|
+
- [Split at thirds](#split-at-thirds)
|
|
18
25
|
- [Status](#status)
|
|
19
26
|
- [Related packages](#related-packages)
|
|
20
27
|
- [Installation](#installation)
|
|
@@ -33,16 +40,55 @@ Based in principle on:
|
|
|
33
40
|
GPU](http://algorithmicbotany.org/papers/subgpu.sig2003.pdf)
|
|
34
41
|
- Clojure version [thi.ng/geom-clj](http://thi.ng/geom-clj).
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
### Available subdivision schemes
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
- Split @ thirds (open / closed)
|
|
40
|
-
- Chaikin (open / closed)
|
|
41
|
-
- Cubic (closed only)
|
|
45
|
+
The following schemes are available as presets and their effects illustrated.
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
#### Chaikin subdivision
|
|
48
|
+
|
|
49
|
+
[`SUBDIV_CHAIKIN`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_CHAIKIN.html) is supported for open & closed geometries.
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
#### Cubic subdivision
|
|
56
|
+
|
|
57
|
+
[`SUBDIV_CUBIC`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_CUBIC.html)
|
|
58
|
+
is only supported for closed geometries (at current).
|
|
59
|
+
|
|
60
|
+

|
|
61
|
+
|
|
62
|
+
#### Dyn-Levin-Gregory subdivision
|
|
63
|
+
|
|
64
|
+
[`SUBDIV_DLG`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_DLG.html)
|
|
65
|
+
is only supported for closed geometries (at current).
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
#### Displacement subdivision
|
|
70
|
+
|
|
71
|
+
[`SUBDIV_DISPLACE`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_DISPLACE.html) is a higher order, customizable subdivision and supported for open & closed geometries.
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
75
|
+

|
|
76
|
+
|
|
77
|
+
#### Split at midpoints
|
|
78
|
+
|
|
79
|
+
[`SUBDIV_MID`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_MID.html) is supported for open & closed geometries.
|
|
80
|
+
|
|
81
|
+

|
|
82
|
+
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
#### Split at thirds
|
|
86
|
+
|
|
87
|
+
[`SUBDIV_THIRDS`](https://docs.thi.ng/umbrella/geom-subdiv-curve/variables/SUBDIV_THIRDS.html) is supported for open & closed geometries.
|
|
88
|
+
|
|
89
|
+

|
|
90
|
+
|
|
91
|
+

|
|
46
92
|
|
|
47
93
|
## Status
|
|
48
94
|
|
|
@@ -80,12 +126,10 @@ For Node.js REPL:
|
|
|
80
126
|
const gsc = await import("@thi.ng/geom-subdiv-curve");
|
|
81
127
|
```
|
|
82
128
|
|
|
83
|
-
Package sizes (brotli'd, pre-treeshake): ESM:
|
|
129
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 801 bytes
|
|
84
130
|
|
|
85
131
|
## Dependencies
|
|
86
132
|
|
|
87
|
-
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
88
|
-
- [@thi.ng/geom-api](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-api)
|
|
89
133
|
- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
|
|
90
134
|
- [@thi.ng/vectors](https://github.com/thi-ng/umbrella/tree/develop/packages/vectors)
|
|
91
135
|
|
|
@@ -96,7 +140,7 @@ Package sizes (brotli'd, pre-treeshake): ESM: 661 bytes
|
|
|
96
140
|
```ts
|
|
97
141
|
import * as gsc from "@thi.ng/geom-subdiv-curve";
|
|
98
142
|
|
|
99
|
-
gsc.subdivide([[0,0], [100,0], [100,100], [0,100]], gsc.
|
|
143
|
+
gsc.subdivide([[0,0], [100,0], [100,100], [0,100]], [gsc.SUBDIV_CHAIKIN], true);
|
|
100
144
|
```
|
|
101
145
|
|
|
102
146
|
## Authors
|
package/api.d.ts
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
|
|
2
|
+
export interface SubdivKernel {
|
|
3
|
+
/**
|
|
4
|
+
* Subdivision function. Called with an array of {@link SubdivKernel.size}
|
|
5
|
+
* consecutive points of the original curve and can produce any number of
|
|
6
|
+
* result points. Additionally is passed the index `i` of the processed
|
|
7
|
+
* point and `nump`, the total number of point in the curve/polyline. The
|
|
8
|
+
* latter 2 args are useful to implement custom behaviors for the start /
|
|
9
|
+
* end points of the curve.
|
|
10
|
+
*
|
|
11
|
+
* @param pts
|
|
12
|
+
* @param i
|
|
13
|
+
* @param nump
|
|
14
|
+
* @param closed
|
|
15
|
+
*/
|
|
16
|
+
fn: (pts: ReadonlyVec[], i: number, nump: number, closed: boolean) => Vec[];
|
|
17
|
+
/**
|
|
18
|
+
* Optional function to pre-process the original curve points prior
|
|
19
|
+
* to each subdivision iteration and MUST yield an iterable of
|
|
20
|
+
* points (e.g. for closed curves / polygons to prepend the last
|
|
21
|
+
* point before the first). If omitted, the curve points are
|
|
22
|
+
* processed as is.
|
|
23
|
+
*
|
|
24
|
+
* @param pts
|
|
25
|
+
* @param closed
|
|
26
|
+
*/
|
|
27
|
+
pre?: (pts: ReadonlyVec[], closed: boolean) => Iterable<ReadonlyVec>;
|
|
28
|
+
/**
|
|
29
|
+
* Kernal size. The subdivision function `fn` always receives `size`
|
|
30
|
+
* number consecutive points.
|
|
31
|
+
*/
|
|
32
|
+
size: number;
|
|
33
|
+
}
|
|
34
34
|
//# sourceMappingURL=api.d.ts.map
|
package/api.js
CHANGED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { wrapSides } from "@thi.ng/transducers/wrap-sides";
|
|
2
|
-
import { addmN } from "@thi.ng/vectors/addmn";
|
|
3
|
-
import { mixN } from "@thi.ng/vectors/mixn";
|
|
4
|
-
import { kernel3 } from "./kernels.js";
|
|
5
|
-
const MIDP = ([a, b]) => [a, addmN([], a, b, 0.5)];
|
|
6
|
-
const THIRDS = ([a, b]) => [
|
|
7
|
-
a,
|
|
8
|
-
mixN([], a, b, 1 / 3),
|
|
9
|
-
mixN([], a, b, 2 / 3)
|
|
10
|
-
];
|
|
11
|
-
const wrap2 = (pts) => wrapSides(pts, 0, 1);
|
|
12
|
-
const wrap3 = (pts) => wrapSides(pts, 1, 1);
|
|
13
|
-
const subdivWith = (fn) => (pts, i, n) => i < n - 2 ? fn(pts) : [...fn(pts), pts[1]];
|
|
14
|
-
const SUBDIV_MID_OPEN = {
|
|
15
|
-
fn: subdivWith(MIDP),
|
|
16
|
-
size: 2
|
|
17
|
-
};
|
|
18
|
-
const SUBDIV_MID_CLOSED = {
|
|
19
|
-
fn: MIDP,
|
|
20
|
-
pre: wrap2,
|
|
21
|
-
size: 2
|
|
22
|
-
};
|
|
23
|
-
const SUBDIV_THIRDS_OPEN = {
|
|
24
|
-
fn: subdivWith(THIRDS),
|
|
25
|
-
size: 2
|
|
26
|
-
};
|
|
27
|
-
const SUBDIV_THIRDS_CLOSED = {
|
|
28
|
-
fn: THIRDS,
|
|
29
|
-
pre: wrap2,
|
|
30
|
-
size: 2
|
|
31
|
-
};
|
|
32
|
-
const CHAIKIN_FIRST = kernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]);
|
|
33
|
-
const CHAIKIN_MAIN = kernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]);
|
|
34
|
-
const CHAIKIN_LAST = kernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]);
|
|
35
|
-
const SUBDIV_CHAIKIN_OPEN = {
|
|
36
|
-
fn: (pts, i, n) => i == 0 ? [pts[0], ...CHAIKIN_FIRST(pts)] : i === n - 3 ? [...CHAIKIN_LAST(pts), pts[2]] : CHAIKIN_MAIN(pts),
|
|
37
|
-
size: 3
|
|
38
|
-
};
|
|
39
|
-
const SUBDIV_CHAIKIN_CLOSED = {
|
|
40
|
-
fn: CHAIKIN_MAIN,
|
|
41
|
-
pre: wrap3,
|
|
42
|
-
size: 3
|
|
43
|
-
};
|
|
44
|
-
const CUBIC_MAIN = kernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]);
|
|
45
|
-
const SUBDIV_CUBIC_CLOSED = {
|
|
46
|
-
fn: CUBIC_MAIN,
|
|
47
|
-
pre: wrap3,
|
|
48
|
-
size: 3
|
|
49
|
-
};
|
|
50
|
-
export {
|
|
51
|
-
SUBDIV_CHAIKIN_CLOSED,
|
|
52
|
-
SUBDIV_CHAIKIN_OPEN,
|
|
53
|
-
SUBDIV_CUBIC_CLOSED,
|
|
54
|
-
SUBDIV_MID_CLOSED,
|
|
55
|
-
SUBDIV_MID_OPEN,
|
|
56
|
-
SUBDIV_THIRDS_CLOSED,
|
|
57
|
-
SUBDIV_THIRDS_OPEN
|
|
58
|
-
};
|
package/kernels.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
2
|
+
import type { SubdivKernel } from "./api.js";
|
|
2
3
|
/**
|
|
3
4
|
* HOF subdiv kernel function for computing 2 split points from 2 source
|
|
4
5
|
* points, using weighted summation (thi.ng/vectors/addW2)
|
|
@@ -23,4 +24,61 @@ export declare const kernel3: ([ua, ub, uc]: number[], [va, vb, vc]: number[]) =
|
|
|
23
24
|
* @param v - split coeffs
|
|
24
25
|
*/
|
|
25
26
|
export declare const kernel5: ([ua, ub, uc, ud, ue]: number[], [va, vb, vc, vd, ve]: number[]) => ([a, b, c, d, e]: ReadonlyVec[]) => import("@thi.ng/vectors").Vec[];
|
|
27
|
+
/**
|
|
28
|
+
* Splits each curve / line segment into halves at midpoint.
|
|
29
|
+
*/
|
|
30
|
+
export declare const SUBDIV_MID: SubdivKernel;
|
|
31
|
+
/**
|
|
32
|
+
* Splits each curve / line segment into 3 parts at 1/3 and 2/3.
|
|
33
|
+
*/
|
|
34
|
+
export declare const SUBDIV_THIRDS: SubdivKernel;
|
|
35
|
+
/**
|
|
36
|
+
* Chaikin subdivision scheme for open curves.
|
|
37
|
+
*/
|
|
38
|
+
export declare const SUBDIV_CHAIKIN: SubdivKernel;
|
|
39
|
+
/**
|
|
40
|
+
* Cubic bezier subdivision scheme. Currently ONLY supported for closed curves.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SUBDIV_CUBIC: SubdivKernel;
|
|
43
|
+
/**
|
|
44
|
+
* Subdivision kernel for Dyn-Levin-Gregory subdivision. Currently ONLY
|
|
45
|
+
* supported for closed curves.
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* Reference:
|
|
49
|
+
* - https://web.archive.org/web/20060816003547/https://algorithmicbotany.org/papers/subgpu.sig2003.pdf
|
|
50
|
+
*/
|
|
51
|
+
export declare const SUBDIV_DLG: SubdivKernel;
|
|
52
|
+
/**
|
|
53
|
+
* Higher-order subdiv kernel. Takes an array of 2-tuples of `[t,x]` where `t`
|
|
54
|
+
* is the normalized split position (along each edge) and `x` is the normalized
|
|
55
|
+
* displacement amount (relative to edge length). The `closed` flag indicates if
|
|
56
|
+
* to be used for open/closed curves. Returns a {@link SubdivKernel} which
|
|
57
|
+
* results in `displace.length` points for each original edge and displaces each
|
|
58
|
+
* point by `displace[i][1] * edgeLength` units along the normal of the edge.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* The original edge end points are always remaining in place. The normalized
|
|
62
|
+
* split positions `t` must be in the open (0,1) interval.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts tangle:../export/subdiv-displace.ts
|
|
66
|
+
* import { subdivide, SUBDIV_DISPLACE } from "@thi.ng/geom-subdiv-curve";
|
|
67
|
+
*
|
|
68
|
+
* // define subdiv kernel w/ custom displacements
|
|
69
|
+
* const kernel = SUBDIV_DISPLACE([[0.25, 0.25], [0.75, -0.25]]);
|
|
70
|
+
*
|
|
71
|
+
* // subdivide polyline with the kernel
|
|
72
|
+
* console.log(
|
|
73
|
+
* subdivide([[0,0], [100, 100], [200, 0]], kernel)
|
|
74
|
+
* );
|
|
75
|
+
* // [
|
|
76
|
+
* // [ 0, 0 ], [ 50, 0 ], [ 50, 100 ], [ 100, 100 ],
|
|
77
|
+
* // [100, 50 ], [ 200, 50 ], [ 200, 0 ]
|
|
78
|
+
* // ]
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @param displace
|
|
82
|
+
*/
|
|
83
|
+
export declare const SUBDIV_DISPLACE: (displace: number[][]) => SubdivKernel;
|
|
26
84
|
//# sourceMappingURL=kernels.d.ts.map
|
package/kernels.js
CHANGED
|
@@ -1,11 +1,84 @@
|
|
|
1
|
+
import { wrapSides } from "@thi.ng/transducers/wrap-sides";
|
|
2
|
+
import { addmN } from "@thi.ng/vectors/addmn";
|
|
1
3
|
import { addW2, addW3, addW5 } from "@thi.ng/vectors/addw";
|
|
4
|
+
import { mag2 } from "@thi.ng/vectors/mag";
|
|
5
|
+
import { mixN } from "@thi.ng/vectors/mixn";
|
|
6
|
+
import { normalize2 } from "@thi.ng/vectors/normalize";
|
|
7
|
+
import { perpendicularCW } from "@thi.ng/vectors/perpendicular";
|
|
8
|
+
import { sub2 } from "@thi.ng/vectors/sub";
|
|
2
9
|
const kernel2 = ([ua, ub], [va, vb]) => ([a, b]) => [addW2([], a, b, ua, ub), addW2([], a, b, va, vb)];
|
|
3
10
|
const kernel3 = ([ua, ub, uc], [va, vb, vc]) => ([a, b, c]) => [addW3([], a, b, c, ua, ub, uc), addW3([], a, b, c, va, vb, vc)];
|
|
4
11
|
const kernel5 = ([ua, ub, uc, ud, ue], [va, vb, vc, vd, ve]) => ([a, b, c, d, e]) => [
|
|
5
12
|
addW5([], a, b, c, d, e, ua, ub, uc, ud, ue),
|
|
6
13
|
addW5([], a, b, c, d, e, va, vb, vc, vd, ve)
|
|
7
14
|
];
|
|
15
|
+
const __wrap2 = (pts, closed) => closed ? wrapSides(pts, 0, 1) : pts;
|
|
16
|
+
const __wrap3 = (pts, closed) => closed ? wrapSides(pts, 1, 1) : pts;
|
|
17
|
+
const SUBDIV_MID = {
|
|
18
|
+
fn: ([a, b], i, nump, closed) => {
|
|
19
|
+
const res = [a, addmN([], a, b, 0.5)];
|
|
20
|
+
if (!closed && i === nump - 2) res.push(b);
|
|
21
|
+
return res;
|
|
22
|
+
},
|
|
23
|
+
pre: __wrap2,
|
|
24
|
+
size: 2
|
|
25
|
+
};
|
|
26
|
+
const SUBDIV_THIRDS = {
|
|
27
|
+
fn: ([a, b], i, nump, closed) => {
|
|
28
|
+
const res = [a, mixN([], a, b, 1 / 3), mixN([], a, b, 2 / 3)];
|
|
29
|
+
if (!closed && i === nump - 2) res.push(b);
|
|
30
|
+
return res;
|
|
31
|
+
},
|
|
32
|
+
pre: __wrap2,
|
|
33
|
+
size: 2
|
|
34
|
+
};
|
|
35
|
+
const CHAIKIN_FIRST = kernel3([1 / 2, 1 / 2, 0], [0, 3 / 4, 1 / 4]);
|
|
36
|
+
const CHAIKIN_MAIN = kernel3([1 / 4, 3 / 4, 0], [0, 3 / 4, 1 / 4]);
|
|
37
|
+
const CHAIKIN_LAST = kernel3([1 / 4, 3 / 4, 0], [0, 1 / 2, 1 / 2]);
|
|
38
|
+
const SUBDIV_CHAIKIN = {
|
|
39
|
+
fn: (pts, i, n, closed) => closed ? CHAIKIN_MAIN(pts) : i == 0 ? [pts[0], ...CHAIKIN_FIRST(pts)] : i === n - 3 ? [...CHAIKIN_LAST(pts), pts[2]] : CHAIKIN_MAIN(pts),
|
|
40
|
+
pre: __wrap3,
|
|
41
|
+
size: 3
|
|
42
|
+
};
|
|
43
|
+
const CUBIC_MAIN = kernel3([1 / 8, 3 / 4, 1 / 8], [0, 1 / 2, 1 / 2]);
|
|
44
|
+
const SUBDIV_CUBIC = {
|
|
45
|
+
fn: (pts) => CUBIC_MAIN(pts),
|
|
46
|
+
pre: (pts) => wrapSides(pts, 1, 1),
|
|
47
|
+
size: 3
|
|
48
|
+
};
|
|
49
|
+
const DLG_MAIN = kernel5(
|
|
50
|
+
[0, 0, 1, 0, 0],
|
|
51
|
+
[0, -1 / 16, 9 / 16, 9 / 16, -1 / 16]
|
|
52
|
+
);
|
|
53
|
+
const SUBDIV_DLG = {
|
|
54
|
+
fn: (pts) => DLG_MAIN(pts),
|
|
55
|
+
pre: (pts) => wrapSides(pts, 2, 2),
|
|
56
|
+
size: 5
|
|
57
|
+
};
|
|
58
|
+
const SUBDIV_DISPLACE = (displace) => ({
|
|
59
|
+
fn: ([a, b], i, nump, closed) => {
|
|
60
|
+
const delta = sub2([], b, a);
|
|
61
|
+
const len = mag2(delta);
|
|
62
|
+
const normal = perpendicularCW(null, normalize2([], delta));
|
|
63
|
+
const res = [
|
|
64
|
+
a,
|
|
65
|
+
...displace.map(
|
|
66
|
+
([t, x]) => addW3([], a, delta, normal, 1, t, x * len)
|
|
67
|
+
)
|
|
68
|
+
];
|
|
69
|
+
if (!closed && i === nump - 2) res.push(b);
|
|
70
|
+
return res;
|
|
71
|
+
},
|
|
72
|
+
size: 2,
|
|
73
|
+
pre: __wrap2
|
|
74
|
+
});
|
|
8
75
|
export {
|
|
76
|
+
SUBDIV_CHAIKIN,
|
|
77
|
+
SUBDIV_CUBIC,
|
|
78
|
+
SUBDIV_DISPLACE,
|
|
79
|
+
SUBDIV_DLG,
|
|
80
|
+
SUBDIV_MID,
|
|
81
|
+
SUBDIV_THIRDS,
|
|
9
82
|
kernel2,
|
|
10
83
|
kernel3,
|
|
11
84
|
kernel5
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/geom-subdiv-curve",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Freely customizable, iterative nD subdivision curves for open / closed geometries",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/thi-ng/umbrella.git"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://
|
|
13
|
+
"homepage": "https://thi.ng/geom-subdiv-curve",
|
|
14
14
|
"funding": [
|
|
15
15
|
{
|
|
16
16
|
"type": "github",
|
|
@@ -33,19 +33,18 @@
|
|
|
33
33
|
"doc:readme": "bun ../../tools/src/module-stats.ts && bun ../../tools/src/readme.ts",
|
|
34
34
|
"pub": "yarn npm publish --access public",
|
|
35
35
|
"test": "bun test",
|
|
36
|
-
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
36
|
+
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts",
|
|
37
|
+
"tool:viz": "bun tools/visualize.ts"
|
|
37
38
|
},
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"@thi.ng/
|
|
40
|
-
"@thi.ng/
|
|
41
|
-
"@thi.ng/transducers": "^9.0.5",
|
|
42
|
-
"@thi.ng/vectors": "^7.10.31"
|
|
40
|
+
"@thi.ng/transducers": "^9.0.6",
|
|
41
|
+
"@thi.ng/vectors": "^7.11.0"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
45
|
-
"@microsoft/api-extractor": "^7.
|
|
46
|
-
"esbuild": "^0.21.
|
|
44
|
+
"@microsoft/api-extractor": "^7.47.0",
|
|
45
|
+
"esbuild": "^0.21.5",
|
|
47
46
|
"typedoc": "^0.25.13",
|
|
48
|
-
"typescript": "^5.
|
|
47
|
+
"typescript": "^5.5.2"
|
|
49
48
|
},
|
|
50
49
|
"keywords": [
|
|
51
50
|
"2d",
|
|
@@ -91,5 +90,5 @@
|
|
|
91
90
|
"geom-splines"
|
|
92
91
|
]
|
|
93
92
|
},
|
|
94
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "154c95cf9d6bab32174498ec3b5b5d87e42be7f9\n"
|
|
95
94
|
}
|
package/subdivide.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import type { SubdivKernel } from "@thi.ng/geom-api";
|
|
2
1
|
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
2
|
+
import type { SubdivKernel } from "./api.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Takes an array of `points` and an array of subdivision `kernels`. Iterativel
|
|
5
|
+
* applies kernels in given order (each iteration operating on the result of the
|
|
6
|
+
* previous iteration). The `closed` flag (default: false) indicates if the
|
|
7
|
+
* points define a closed or open geometry (i.e. polygon vs. polyline).
|
|
5
8
|
*
|
|
6
|
-
* @
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Reference:
|
|
11
|
+
* - https://web.archive.org/web/20060816003547/https://algorithmicbotany.org/papers/subgpu.sig2003.pdf
|
|
12
|
+
* - https://www.csl.mtu.edu/cs3621/common/Subdivision.pdf
|
|
13
|
+
*
|
|
14
|
+
* @param points - source points
|
|
15
|
+
* @param kernels - subdivision scheme(s)
|
|
16
|
+
* @param closed
|
|
9
17
|
*/
|
|
10
|
-
export declare
|
|
18
|
+
export declare function subdivide(points: ReadonlyVec[], kernels: SubdivKernel[], closed?: boolean): ReadonlyVec[];
|
|
11
19
|
//# sourceMappingURL=subdivide.d.ts.map
|
package/subdivide.js
CHANGED
|
@@ -3,20 +3,20 @@ import { mapcatIndexed } from "@thi.ng/transducers/mapcat-indexed";
|
|
|
3
3
|
import { partition } from "@thi.ng/transducers/partition";
|
|
4
4
|
import { push } from "@thi.ng/transducers/push";
|
|
5
5
|
import { transduce } from "@thi.ng/transducers/transduce";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const nump =
|
|
9
|
-
|
|
6
|
+
function subdivide(points, kernels, closed = false) {
|
|
7
|
+
for (let { fn, pre, size } of kernels) {
|
|
8
|
+
const nump = points.length;
|
|
9
|
+
points = transduce(
|
|
10
10
|
comp(
|
|
11
11
|
partition(size, 1),
|
|
12
|
-
mapcatIndexed((i,
|
|
12
|
+
mapcatIndexed((i, pts) => fn(pts, i, nump, closed))
|
|
13
13
|
),
|
|
14
14
|
push(),
|
|
15
|
-
pre ? pre(
|
|
15
|
+
pre ? pre(points, closed) : points
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
|
-
return
|
|
19
|
-
}
|
|
18
|
+
return points;
|
|
19
|
+
}
|
|
20
20
|
export {
|
|
21
21
|
subdivide
|
|
22
22
|
};
|