Skip to content

Commit

Permalink
feat(geom): add tessellation post-processing helpers
Browse files Browse the repository at this point in the history
- add graphFromTessellation()
- add edgesFromTessellation()
- add edgePointsFromTessellation()
- update deps (adjacency)
- update pkg exports/meta
  • Loading branch information
postspectacular committed Jun 8, 2024
1 parent 607dd27 commit 7687975
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 18 deletions.
16 changes: 16 additions & 0 deletions packages/geom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
},
"dependencies": {
"@thi.ng/adjacency": "^2.5.51",
"@thi.ng/api": "^8.11.2",
"@thi.ng/arrays": "^2.9.6",
"@thi.ng/associative": "^6.3.60",
Expand Down Expand Up @@ -73,6 +74,7 @@
},
"keywords": [
"2d",
"3d",
"analysis",
"arc",
"area",
Expand All @@ -83,14 +85,25 @@
"clipping",
"conversion",
"datastructure",
"edges",
"ellipse",
"geometry",
"graph",
"graphics",
"group",
"intersection",
"parser",
"path",
"polygon",
"polyline",
"polymorphic",
"sample",
"scatter",
"shape",
"spline",
"svg",
"triangulation",
"tessellation",
"typescript"
],
"publishConfig": {
Expand Down Expand Up @@ -301,6 +314,9 @@
"./flip": {
"default": "./flip.js"
},
"./from-tessellation": {
"default": "./from-tessellation.js"
},
"./group": {
"default": "./group.js"
},
Expand Down
86 changes: 86 additions & 0 deletions packages/geom/src/from-tessellation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { Edge } from "@thi.ng/adjacency";
import { defAdjBitMatrix } from "@thi.ng/adjacency/binary";
import type { GroupAttribs, Tessellation } from "@thi.ng/geom-api";
import { indexedPoints } from "@thi.ng/geom-tessellate/tessellate";
import { map } from "@thi.ng/transducers/map";
import { mapcat } from "@thi.ng/transducers/mapcat";
import { partition } from "@thi.ng/transducers/partition";
import { wrapSides } from "@thi.ng/transducers/wrap-sides";
import { Group } from "./api/group.js";
import { Polygon } from "./api/polygon.js";

/**
* Creates a group of polygons from the given tessellation. If `attribs` are
* given, they will be used as the group's attribs.
*
* @param tess
* @param attribs
*/
export const groupFromTessellation = (
tess: Tessellation,
attribs?: GroupAttribs
) =>
new Group(
attribs,
tess.indices.map((ids) => new Polygon(indexedPoints(tess.points, ids)))
);

/**
* Create a directed or undirected graph from the given tessellation. The graph
* is stored as
* [`AdjacencyBitMatrix`](https://docs.thi.ng/umbrella/adjacency/classes/AdjacencyBitMatrix.html)
* and can be edited, queried, and analyzed further.
*
* @remarks
* Also see {@link edgesFromTessellation}, {@link edgePointsFromTessellation}.
*
* @param tessel
*/
export const graphFromTessellation = (
{ points, indices }: Tessellation,
directed = false
) =>
defAdjBitMatrix(
points.length,
<Iterable<Edge>>(
mapcat((ids) => partition(2, 1, wrapSides(ids, 0, 1)), indices)
),
!directed
);

/**
* Returns an iterable of unique edges in the given tessellation, where each
* edge is a 2-tuple of point indices `[a,b]`, each referring to points in the
* tessellation's `points` array.
*
* @remarks
*
* @example
* ``ts
* import * as g from "@thi.ng/geom";
*
* // tessellate rect into a triangle fan
* const tess = g.tessellate(g.rect(100), [g.TESSELLATE_TRI_FAN]);
*
* // extract unique edges (ignoring direction)
* console.log([...g.uniqueEdgesFromTessellation(tess)]);
* // [[ 3, 4 ], [ 2, 3 ], [ 2, 4 ], [ 1, 2 ],
* // [ 1, 4 ], [ 0, 1 ], [ 0, 3 ], [ 0, 4 ]]
* ```
*
* @param tess
*/
export const edgesFromTessellation = (tess: Tessellation) =>
graphFromTessellation(tess, false).edges();

/**
* Similar to {@link edgesFromTessellation}, but returns edges as pairs of
* points (instead of point IDs).
*
* @param tess
*/
export const edgePointsFromTessellation = (tess: Tessellation) =>
map(
(e) => indexedPoints(tess.points, e),
graphFromTessellation(tess, false).edges()
);
1 change: 1 addition & 0 deletions packages/geom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export * from "./convolve.js";
export * from "./edges.js";
export * from "./fit-into-bounds.js";
export * from "./flip.js";
export * from "./from-tessellation.js";
export * from "./intersects.js";
export * from "./map-point.js";
export * from "./offset.js";
Expand Down
18 changes: 1 addition & 17 deletions packages/geom/src/tessellate.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import type { Maybe } from "@thi.ng/api";
import { ensureArray } from "@thi.ng/arrays/ensure-array";
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
import type {
GroupAttribs,
IShape,
Tessellation,
Tessellator,
} from "@thi.ng/geom-api";
import type { IShape, Tessellation, Tessellator } from "@thi.ng/geom-api";
import { earCut } from "@thi.ng/geom-tessellate/earcut";
import {
earCutComplex,
Expand All @@ -18,15 +13,13 @@ import { quadFan } from "@thi.ng/geom-tessellate/quad-fan";
import { rimTris } from "@thi.ng/geom-tessellate/rim-tris";
import {
tessellate as _tessellate,
indexedPoints,
tessellateQueue,
} from "@thi.ng/geom-tessellate/tessellate";
import { triFan } from "@thi.ng/geom-tessellate/tri-fan";
import { triFanSplit } from "@thi.ng/geom-tessellate/tri-fan-split";
import { range } from "@thi.ng/transducers/range";
import type { ComplexPolygon } from "./api/complex-polygon.js";
import { Group } from "./api/group.js";
import { Polygon } from "./api/polygon.js";
import { __dispatch } from "./internal/dispatch.js";
import { vertices } from "./vertices.js";

Expand Down Expand Up @@ -104,15 +97,6 @@ export const tessellate = defmulti<IShape, Iterable<Tessellator>, Tessellation>(
}
);

export const groupFromTessellation = (
tess: Tessellation,
attribs?: GroupAttribs
) =>
new Group(
attribs,
tess.indices.map((ids) => new Polygon(indexedPoints(tess.points, ids)))
);

/**
* Alias for thi.ng/geom-tessellate
* [`earCut`](https://docs.thi.ng/umbrella/geom-tessellate/functions/earCut.html)
Expand Down
3 changes: 2 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3669,7 +3669,7 @@ __metadata:
languageName: unknown
linkType: soft

"@thi.ng/adjacency@workspace:^, @thi.ng/adjacency@workspace:packages/adjacency":
"@thi.ng/adjacency@npm:^2.5.51, @thi.ng/adjacency@workspace:^, @thi.ng/adjacency@workspace:packages/adjacency":
version: 0.0.0-use.local
resolution: "@thi.ng/adjacency@workspace:packages/adjacency"
dependencies:
Expand Down Expand Up @@ -4869,6 +4869,7 @@ __metadata:
resolution: "@thi.ng/geom@workspace:packages/geom"
dependencies:
"@microsoft/api-extractor": "npm:^7.45.0"
"@thi.ng/adjacency": "npm:^2.5.51"
"@thi.ng/api": "npm:^8.11.2"
"@thi.ng/arrays": "npm:^2.9.6"
"@thi.ng/associative": "npm:^6.3.60"
Expand Down

0 comments on commit 7687975

Please sign in to comment.