@thi.ng/geom-tessellate 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom-tessellate",
3
- "version": "2.1.131",
3
+ "version": "3.0.0",
4
4
  "description": "2D/3D convex polygon tessellators",
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://github.com/thi-ng/umbrella/tree/develop/packages/geom-tessellate#readme",
13
+ "homepage": "https://thi.ng/geom-tessellate",
14
14
  "funding": [
15
15
  {
16
16
  "type": "github",
@@ -33,21 +33,25 @@
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/checks": "^3.6.3",
40
- "@thi.ng/geom-api": "^4.0.9",
41
- "@thi.ng/geom-isec": "^3.0.9",
42
- "@thi.ng/geom-poly-utils": "^2.3.114",
43
- "@thi.ng/transducers": "^9.0.4",
44
- "@thi.ng/vectors": "^7.10.30"
40
+ "@thi.ng/api": "^8.11.3",
41
+ "@thi.ng/checks": "^3.6.5",
42
+ "@thi.ng/geom-accel": "^4.0.0",
43
+ "@thi.ng/geom-isec": "^4.0.0",
44
+ "@thi.ng/geom-poly-utils": "^3.0.0",
45
+ "@thi.ng/math": "^5.11.0",
46
+ "@thi.ng/morton": "^3.1.87",
47
+ "@thi.ng/transducers": "^9.0.6",
48
+ "@thi.ng/vectors": "^7.11.0"
45
49
  },
46
50
  "devDependencies": {
47
- "@microsoft/api-extractor": "^7.43.0",
48
- "esbuild": "^0.20.2",
49
- "typedoc": "^0.25.12",
50
- "typescript": "^5.4.3"
51
+ "@microsoft/api-extractor": "^7.47.0",
52
+ "esbuild": "^0.21.5",
53
+ "typedoc": "^0.25.13",
54
+ "typescript": "^5.5.2"
51
55
  },
52
56
  "keywords": [
53
57
  "2d",
@@ -74,6 +78,12 @@
74
78
  ".": {
75
79
  "default": "./index.js"
76
80
  },
81
+ "./api": {
82
+ "default": "./api.js"
83
+ },
84
+ "./earcut-complex": {
85
+ "default": "./earcut-complex.js"
86
+ },
77
87
  "./earcut": {
78
88
  "default": "./earcut.js"
79
89
  },
@@ -92,6 +102,15 @@
92
102
  "./tessellate": {
93
103
  "default": "./tessellate.js"
94
104
  },
105
+ "./tessellation": {
106
+ "default": "./tessellation.js"
107
+ },
108
+ "./tri-fan-boundary": {
109
+ "default": "./tri-fan-boundary.js"
110
+ },
111
+ "./tri-fan-split": {
112
+ "default": "./tri-fan-split.js"
113
+ },
95
114
  "./tri-fan": {
96
115
  "default": "./tri-fan.js"
97
116
  }
@@ -100,5 +119,5 @@
100
119
  "parent": "@thi.ng/geom",
101
120
  "year": 2013
102
121
  },
103
- "gitHead": "aed3421c21044c005fbcb7cc37965ccf85a870d2\n"
122
+ "gitHead": "154c95cf9d6bab32174498ec3b5b5d87e42be7f9\n"
104
123
  }
package/quad-fan.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import type { Tessellator } from "@thi.ng/geom-api";
1
+ import type { Tessellator } from "./api.js";
2
2
  export declare const quadFan: Tessellator;
3
3
  //# sourceMappingURL=quad-fan.d.ts.map
package/quad-fan.js CHANGED
@@ -1,21 +1,17 @@
1
1
  import { centroid } from "@thi.ng/geom-poly-utils/centroid";
2
- import { comp } from "@thi.ng/transducers/comp";
3
- import { map } from "@thi.ng/transducers/map";
4
- import { partition } from "@thi.ng/transducers/partition";
5
- import { push } from "@thi.ng/transducers/push";
6
- import { transduce } from "@thi.ng/transducers/transduce";
7
- import { wrapSides } from "@thi.ng/transducers/wrap-sides";
8
- import { mixN } from "@thi.ng/vectors/mixn";
9
- const quadFan = (points) => {
10
- const p = centroid(points);
11
- return transduce(
12
- comp(
13
- partition(3, 1),
14
- map(([a, b, c]) => [mixN([], a, b, 0.5), b, mixN([], b, c, 0.5), p])
15
- ),
16
- push(),
17
- wrapSides(points)
18
- );
2
+ import { addmN } from "@thi.ng/vectors";
3
+ const quadFan = (tess, faces, pids) => {
4
+ const points = tess.pointsForIDs(pids);
5
+ const c = tess.addPoint(centroid(points));
6
+ const n = pids.length - 1;
7
+ let m0 = tess.addPoint(addmN([], points[n], points[0], 0.5));
8
+ let mprev = m0;
9
+ for (let i = 0; i <= n; i++) {
10
+ const m = i < n ? tess.addPoint(addmN([], points[i], points[i + 1], 0.5)) : m0;
11
+ faces.push([c, mprev, pids[i], m]);
12
+ mprev = m;
13
+ }
14
+ return faces;
19
15
  };
20
16
  export {
21
17
  quadFan
package/rim-tris.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import type { Tessellator } from "@thi.ng/geom-api";
1
+ import type { Tessellator } from "./api.js";
2
2
  export declare const rimTris: Tessellator;
3
3
  //# sourceMappingURL=rim-tris.d.ts.map
package/rim-tris.js CHANGED
@@ -1,29 +1,24 @@
1
- import { comp } from "@thi.ng/transducers/comp";
2
- import { map } from "@thi.ng/transducers/map";
3
- import { partition } from "@thi.ng/transducers/partition";
4
- import { push } from "@thi.ng/transducers/push";
5
- import { transduce } from "@thi.ng/transducers/transduce";
6
- import { wrapSides } from "@thi.ng/transducers/wrap-sides";
7
- import { zip } from "@thi.ng/transducers/zip";
8
- import { mixN } from "@thi.ng/vectors/mixn";
9
- const rimTris = (points) => {
10
- const edgeCentroids = transduce(
11
- comp(
12
- partition(2, 1),
13
- map((e) => mixN([], e[0], e[1], 0.5))
14
- ),
15
- push(),
16
- wrapSides(points, 0, 1)
17
- );
18
- return transduce(
19
- comp(
20
- partition(2, 1),
21
- map((t) => [t[0][0], t[1][1], t[1][0]])
22
- ),
23
- push(),
24
- [edgeCentroids],
25
- wrapSides([...zip(edgeCentroids, points)], 1, 0)
26
- );
1
+ import { addmN } from "@thi.ng/vectors/addmn";
2
+ const rimTris = (tess, faces, pids) => {
3
+ const points = tess.pointsForIDs(pids);
4
+ const n = pids.length - 1;
5
+ const mids = [
6
+ tess.addPoint(addmN([], points[n], points[0], 0.5))
7
+ ];
8
+ let mprev = mids[0];
9
+ for (let i = 0; i <= n; i++) {
10
+ let m;
11
+ if (i < n) {
12
+ m = tess.addPoint(addmN([], points[i], points[i + 1], 0.5));
13
+ mids.push(m);
14
+ } else {
15
+ m = mids[0];
16
+ }
17
+ faces.push([mprev, pids[i], m]);
18
+ mprev = m;
19
+ }
20
+ faces.push(mids);
21
+ return faces;
27
22
  };
28
23
  export {
29
24
  rimTris
package/tessellate.d.ts CHANGED
@@ -1,5 +1,8 @@
1
- import type { Tessellator } from "@thi.ng/geom-api";
2
- import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
3
- export declare function tessellate(points: ReadonlyVec[], tessFn: Tessellator, iter?: number): Vec[][];
4
- export declare function tessellate(points: ReadonlyVec[], tessFns: Iterable<Tessellator>): Vec[][];
1
+ import type { ReadonlyVec } from "@thi.ng/vectors";
2
+ import type { ITessellation, Tessellator } from "./api.js";
3
+ export declare function tessellate(points: ReadonlyVec[], tessellators: Tessellator, iter?: number): ITessellation;
4
+ export declare function tessellate(points: ReadonlyVec[], tessellators: Iterable<Tessellator>): ITessellation;
5
+ export declare function tessellateWith(tessel: ITessellation, points: ReadonlyVec[], tessellators: Tessellator, iter?: number): ITessellation;
6
+ export declare function tessellateWith(tessel: ITessellation, points: ReadonlyVec[], tessellators: Iterable<Tessellator>): ITessellation;
7
+ export declare const tessellateFaces: (tessel: ITessellation, faces: number[][], tessellators: Iterable<Tessellator>) => ITessellation;
5
8
  //# sourceMappingURL=tessellate.d.ts.map
package/tessellate.js CHANGED
@@ -1,23 +1,30 @@
1
1
  import { isFunction } from "@thi.ng/checks/is-function";
2
- import { last } from "@thi.ng/transducers/last";
3
- import { mapcat } from "@thi.ng/transducers/mapcat";
4
- import { push } from "@thi.ng/transducers/push";
5
- import { reducer } from "@thi.ng/transducers/reduce";
6
2
  import { repeat } from "@thi.ng/transducers/repeat";
7
- import { scan } from "@thi.ng/transducers/scan";
8
- import { transduce } from "@thi.ng/transducers/transduce";
9
- function tessellate(...args) {
10
- return transduce(
11
- scan(
12
- reducer(
13
- () => [args[0]],
14
- (acc, fn) => transduce(mapcat(fn), push(), acc)
15
- )
16
- ),
17
- last(),
18
- isFunction(args[1]) ? repeat(args[1], args[2] || 1) : args[1]
3
+ import { BasicTessellation } from "./tessellation.js";
4
+ function tessellate(points, ...args) {
5
+ return tessellateWith(
6
+ new BasicTessellation(),
7
+ points,
8
+ ...args
19
9
  );
20
10
  }
11
+ function tessellateWith(tessel, points, ...args) {
12
+ const fns = isFunction(args[0]) ? repeat(args[0], args[1] ?? 1) : args[0];
13
+ return tessellateFaces(tessel, [tessel.addPoints(points)], fns);
14
+ }
15
+ const tessellateFaces = (tessel, faces, tessellators) => {
16
+ for (let fn of tessellators) {
17
+ let newFaces = [];
18
+ for (let face of faces) {
19
+ fn(tessel, newFaces, face);
20
+ }
21
+ faces = newFaces;
22
+ }
23
+ tessel.addFaces(faces);
24
+ return tessel;
25
+ };
21
26
  export {
22
- tessellate
27
+ tessellate,
28
+ tessellateFaces,
29
+ tessellateWith
23
30
  };
@@ -0,0 +1,26 @@
1
+ import { KdTreeMap } from "@thi.ng/geom-accel/kd-tree-map";
2
+ import type { ReadonlyVec } from "@thi.ng/vectors";
3
+ import type { ITessellation } from "./api.js";
4
+ export declare abstract class ATessellation implements ITessellation {
5
+ points: ReadonlyVec[];
6
+ faces: number[][];
7
+ constructor(points?: ReadonlyVec[], faces?: number[][]);
8
+ abstract empty(): ITessellation;
9
+ abstract addPoint(p: ReadonlyVec): number;
10
+ addPoints(points: ReadonlyVec[]): number[];
11
+ addFaces(faces: number[][]): this;
12
+ pointsForIDs(indices: number[]): ReadonlyVec[];
13
+ pointsForFaces(faces?: number[][]): ReadonlyVec[][];
14
+ }
15
+ export declare class BasicTessellation extends ATessellation {
16
+ empty(): BasicTessellation;
17
+ addPoint(p: ReadonlyVec): number;
18
+ }
19
+ export declare class MeshTessellation extends ATessellation {
20
+ eps: number;
21
+ tree: KdTreeMap<ReadonlyVec, number>;
22
+ constructor(dim: 2 | 3, points?: ReadonlyVec[], faces?: number[][], eps?: number);
23
+ empty(): MeshTessellation;
24
+ addPoint(p: ReadonlyVec): number;
25
+ }
26
+ //# sourceMappingURL=tessellation.d.ts.map
@@ -0,0 +1,59 @@
1
+ import { KdTreeMap } from "@thi.ng/geom-accel/kd-tree-map";
2
+ import { distSq2, distSq3 } from "@thi.ng/vectors/distsq";
3
+ class ATessellation {
4
+ constructor(points = [], faces = []) {
5
+ this.points = points;
6
+ this.faces = faces;
7
+ }
8
+ addPoints(points) {
9
+ return points.map((p) => this.addPoint(p));
10
+ }
11
+ addFaces(faces) {
12
+ this.faces.push(...faces);
13
+ return this;
14
+ }
15
+ pointsForIDs(indices) {
16
+ return indices.map((i) => this.points[i]);
17
+ }
18
+ pointsForFaces(faces = this.faces) {
19
+ return faces.map((ids) => this.pointsForIDs(ids));
20
+ }
21
+ }
22
+ class BasicTessellation extends ATessellation {
23
+ empty() {
24
+ return new BasicTessellation();
25
+ }
26
+ addPoint(p) {
27
+ return this.points.push(p) - 1;
28
+ }
29
+ }
30
+ class MeshTessellation extends ATessellation {
31
+ constructor(dim, points = [], faces = [], eps = 1e-6) {
32
+ super(points, faces);
33
+ this.eps = eps;
34
+ this.tree = new KdTreeMap(
35
+ dim,
36
+ void 0,
37
+ dim === 2 ? distSq2 : distSq3
38
+ );
39
+ this.addPoints(points);
40
+ }
41
+ tree;
42
+ empty() {
43
+ return new MeshTessellation(this.tree.dim);
44
+ }
45
+ addPoint(p) {
46
+ const tree = this.tree;
47
+ let id = tree.get(p, this.eps);
48
+ if (id !== void 0) return id;
49
+ id = tree.size;
50
+ tree.set(p, id, this.eps);
51
+ this.points.push(p);
52
+ return id;
53
+ }
54
+ }
55
+ export {
56
+ ATessellation,
57
+ BasicTessellation,
58
+ MeshTessellation
59
+ };
@@ -0,0 +1,3 @@
1
+ import type { Tessellator } from "./api.js";
2
+ export declare const triFanBoundary: Tessellator;
3
+ //# sourceMappingURL=tri-fan-boundary.d.ts.map
@@ -0,0 +1,11 @@
1
+ const triFanBoundary = (_, faces, pids) => {
2
+ const c = pids[0];
3
+ const n = pids.length - 1;
4
+ for (let i = 1; i < n; i++) {
5
+ faces.push([c, pids[i], pids[i + 1]]);
6
+ }
7
+ return faces;
8
+ };
9
+ export {
10
+ triFanBoundary
11
+ };
@@ -0,0 +1,9 @@
1
+ import type { Tessellator } from "./api.js";
2
+ /**
3
+ * Combined tessellator of {@link triFan}, followed by {@link rimTris}, but in a
4
+ * single pass.
5
+ *
6
+ * @param points
7
+ */
8
+ export declare const triFanSplit: Tessellator;
9
+ //# sourceMappingURL=tri-fan-split.d.ts.map
@@ -0,0 +1,26 @@
1
+ import { centroid } from "@thi.ng/geom-poly-utils/centroid";
2
+ import { addmN } from "@thi.ng/vectors/addmn";
3
+ const triFanSplit = (tess, faces, pids) => {
4
+ const points = tess.pointsForIDs(pids);
5
+ const c = centroid(points);
6
+ const cid = tess.addPoint(c);
7
+ const n = pids.length - 1;
8
+ for (let i = 0; i <= n; i++) {
9
+ const j = i < n ? i + 1 : 0;
10
+ const a = points[i];
11
+ const b = points[j];
12
+ const mab = tess.addPoint(addmN([], a, b, 0.5));
13
+ const mac = tess.addPoint(addmN([], a, c, 0.5));
14
+ const mbc = tess.addPoint(addmN([], b, c, 0.5));
15
+ faces.push(
16
+ [pids[i], mab, mac],
17
+ [mab, pids[j], mbc],
18
+ [mac, mab, mbc],
19
+ [mac, mbc, cid]
20
+ );
21
+ }
22
+ return faces;
23
+ };
24
+ export {
25
+ triFanSplit
26
+ };
package/tri-fan.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import type { Tessellator } from "@thi.ng/geom-api";
1
+ import type { Tessellator } from "./api.js";
2
2
  export declare const triFan: Tessellator;
3
3
  //# sourceMappingURL=tri-fan.d.ts.map
package/tri-fan.js CHANGED
@@ -1,20 +1,11 @@
1
1
  import { centroid } from "@thi.ng/geom-poly-utils/centroid";
2
- import { comp } from "@thi.ng/transducers/comp";
3
- import { map } from "@thi.ng/transducers/map";
4
- import { partition } from "@thi.ng/transducers/partition";
5
- import { push } from "@thi.ng/transducers/push";
6
- import { transduce } from "@thi.ng/transducers/transduce";
7
- import { wrapSides } from "@thi.ng/transducers/wrap-sides";
8
- const triFan = (points) => {
9
- const c = centroid(points);
10
- return transduce(
11
- comp(
12
- partition(2, 1),
13
- map(([a, b]) => [a, b, c])
14
- ),
15
- push(),
16
- wrapSides(points, 0, 1)
17
- );
2
+ const triFan = (tess, faces, pids) => {
3
+ const c = tess.addPoint(centroid(tess.pointsForIDs(pids)));
4
+ const n = pids.length - 1;
5
+ for (let i = 0; i <= n; i++) {
6
+ faces.push([c, pids[i], pids[i < n ? i + 1 : 0]]);
7
+ }
8
+ return faces;
18
9
  };
19
10
  export {
20
11
  triFan