@thi.ng/geom-sdf 0.3.32 → 0.4.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**: 2024-04-23T07:02:18Z
3
+ - **Last updated**: 2024-05-08T18:24:32Z
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,20 @@ 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
+ ## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-sdf@0.4.0) (2024-05-08)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add rdom-klist example project, update readmes ([cd458ac](https://github.com/thi-ng/umbrella/commit/cd458ac))
17
+ - add rdom-klist example project, update readmes ([531437f](https://github.com/thi-ng/umbrella/commit/531437f))
18
+ - support path & complexpoly sub-shapes in asSDF() ([e924dc2](https://github.com/thi-ng/umbrella/commit/e924dc2))
19
+
20
+ #### ♻️ Refactoring
21
+
22
+ - update internal polyline handling ([f758425](https://github.com/thi-ng/umbrella/commit/f758425))
23
+ - add/update asSDF() impls for ComplexPoly & Path ([3337a0e](https://github.com/thi-ng/umbrella/commit/3337a0e))
24
+ - update docs
25
+
12
26
  ## [0.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-sdf@0.3.0) (2024-01-23)
13
27
 
14
28
  #### 🚀 Features
package/README.md CHANGED
@@ -16,6 +16,7 @@
16
16
 
17
17
  - [About](#about)
18
18
  - [SDF creation](#sdf-creation)
19
+ - [Supported thi.ng/geom shape types](#supported-thinggeom-shape-types)
19
20
  - [SDF combinators](#sdf-combinators)
20
21
  - [SDF discretization, sampling & domain modifiers](#sdf-discretization-sampling--domain-modifiers)
21
22
  - [Status](#status)
@@ -60,6 +61,25 @@ import { asSDF } from "@thi.ng/geom-sdf";
60
61
  const f = asSDF(group({}, [circle([-50, 0], 100), circle([50, 0], 100)]));
61
62
  ```
62
63
 
64
+ ### Supported thi.ng/geom shape types
65
+
66
+ ([shape type descriptions](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/README.md#shape-types))
67
+
68
+ - circle
69
+ - complexPoly (polygon w/ holes)
70
+ - cubic
71
+ - ellipse
72
+ - group (of supported shapes)
73
+ - line
74
+ - path (w/ holes and/or sub-paths, multiple curves)
75
+ - points
76
+ - polygon
77
+ - polyline
78
+ - quad
79
+ - quadratic
80
+ - rect
81
+ - triangle
82
+
63
83
  ### SDF combinators
64
84
 
65
85
  The following table illustrates various options how SDFs can be combined. When
@@ -147,7 +167,7 @@ For Node.js REPL:
147
167
  const sdf = await import("@thi.ng/geom-sdf");
148
168
  ```
149
169
 
150
- Package sizes (brotli'd, pre-treeshake): ESM: 3.65 KB
170
+ Package sizes (brotli'd, pre-treeshake): ESM: 3.76 KB
151
171
 
152
172
  ## Dependencies
153
173
 
@@ -166,13 +186,14 @@ Package sizes (brotli'd, pre-treeshake): ESM: 3.65 KB
166
186
 
167
187
  ## Usage examples
168
188
 
169
- One project in this repo's
189
+ Several projects in this repo's
170
190
  [/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
171
- directory is using this package:
191
+ directory are using this package:
172
192
 
173
193
  | Screenshot | Description | Live demo | Source |
174
194
  |:---------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------|:----------------------------------------------------|:---------------------------------------------------------------------------------|
175
195
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-sdf-logo.jpg" width="240"/> | (Re)Constructing the thi.ng logo using a 2D signed-distance field | [Demo](https://demo.thi.ng/umbrella/geom-sdf-logo/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-sdf-logo) |
196
+ | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-sdf-path.png" width="240"/> | SVG path to SDF, applying deformation and converting back to SVG | [Demo](https://demo.thi.ng/umbrella/geom-sdf-path/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-sdf-path) |
176
197
 
177
198
  ## API
178
199
 
package/as-sdf.d.ts CHANGED
@@ -13,10 +13,11 @@ import type { SDFn } from "./api.js";
13
13
  *
14
14
  * - circle
15
15
  * - cubic (auto-converted to polyline)
16
+ * - complexpoly (boundary only, holes ignored)
16
17
  * - ellipse
17
18
  * - group
18
19
  * - line
19
- * - path (auto-converted to polygon/polyline)
20
+ * - path (auto-converted to polyline or complex polygon)
20
21
  * - points
21
22
  * - polygon
22
23
  * - polyline
package/as-sdf.js CHANGED
@@ -1,10 +1,13 @@
1
1
  import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
2
2
  import { assert } from "@thi.ng/errors/assert";
3
3
  import { unsupported } from "@thi.ng/errors/unsupported";
4
+ import { Path } from "@thi.ng/geom/api/path";
5
+ import { Polygon } from "@thi.ng/geom/api/polygon";
4
6
  import { asPolygon } from "@thi.ng/geom/as-polygon";
5
7
  import { asPolyline } from "@thi.ng/geom/as-polyline";
6
- import { simplify } from "@thi.ng/geom/simplify";
7
8
  import { __dispatch } from "@thi.ng/geom/internal/dispatch";
9
+ import { simplify } from "@thi.ng/geom/simplify";
10
+ import { withAttribs } from "@thi.ng/geom/with-attribs";
8
11
  import { add2 } from "@thi.ng/vectors/add";
9
12
  import { mulN2 } from "@thi.ng/vectors/muln";
10
13
  import {
@@ -25,9 +28,9 @@ import {
25
28
  union
26
29
  } from "./ops.js";
27
30
  import {
31
+ DEFAULT_ATTRIBS,
28
32
  box2,
29
33
  circle2,
30
- DEFAULT_ATTRIBS,
31
34
  ellipse2,
32
35
  line2,
33
36
  points2,
@@ -45,9 +48,14 @@ const asSDF = defmulti(
45
48
  {
46
49
  [DEFAULT]: ($) => unsupported(`shape type: ${$.type}`),
47
50
  circle: ($) => circle2($.pos, $.r, __sdfAttribs($.attribs)),
51
+ complexpoly: ($) => diff(
52
+ [$.boundary, ...$.children].map(
53
+ (poly) => asSDF(withAttribs(poly, $.attribs))
54
+ )
55
+ ),
48
56
  cubic: ($) => asSDF(
49
57
  simplify(
50
- asPolyline($, (__sdfAttribs($.attribs) || {}).samples),
58
+ asPolyline($, (__sdfAttribs($.attribs) || {}).samples)[0],
51
59
  0
52
60
  )
53
61
  ),
@@ -96,9 +104,21 @@ const asSDF = defmulti(
96
104
  line: ({ points: [a, b], attribs }) => line2(a, b, __sdfAttribs(attribs)),
97
105
  path: ($) => {
98
106
  const n = (__sdfAttribs($.attribs) || {}).samples;
99
- return asSDF(
100
- simplify($.closed ? asPolygon($, n) : asPolyline($, n), 0)
107
+ const path = new Path($.segments, [], $.attribs);
108
+ const boundary = asSDF(
109
+ simplify(
110
+ $.closed ? asPolygon(path, n)[0] : asPolyline(path, n)[0],
111
+ 0
112
+ )
101
113
  );
114
+ if (!$.subPaths.length) return boundary;
115
+ const fields = [
116
+ boundary,
117
+ ...$.subPaths.map(
118
+ (segments) => asSDF(new Path(segments, [], $.attribs))
119
+ )
120
+ ];
121
+ return $.closed ? diff(fields) : union(fields);
102
122
  },
103
123
  points: ($) => points2($.points, __sdfAttribs($.attribs)),
104
124
  poly: ($) => polygon2($.points, __sdfAttribs($.attribs)),
package/bounds.js CHANGED
@@ -7,8 +7,7 @@ function withBoundingCircle(sdf, ...args) {
7
7
  let [[cx, cy], r] = args.length === 1 ? boundingCircle(args[0]) : args;
8
8
  r *= r;
9
9
  return (p, minD = Infinity) => {
10
- if (minD === Infinity)
11
- return sdf(p, minD);
10
+ if (minD === Infinity) return sdf(p, minD);
12
11
  const dx = p[0] - cx;
13
12
  const dy = p[1] - cy;
14
13
  return dx * dx + dy * dy - r < minD * minD ? sdf(p, minD) : minD;
@@ -20,8 +19,7 @@ function withBoundingRect(sdf, ...args) {
20
19
  const hSize = submN2([], max, min, 0.5);
21
20
  const t = [0, 0];
22
21
  return (p, minD = Infinity) => {
23
- if (minD === Infinity)
24
- return sdf(p, minD);
22
+ if (minD === Infinity) return sdf(p, minD);
25
23
  return distBox2(sub2(t, p, centroid), hSize) < minD ? sdf(p, minD) : minD;
26
24
  };
27
25
  }
package/dist.js CHANGED
@@ -39,8 +39,7 @@ const distPolygon2 = (p, pts) => {
39
39
  const w = sub2(t2, p, pi);
40
40
  d = min(d, distSq2(w, mulN2(t3, e, clamp01(dot2(w, e) / magSq2(e)))));
41
41
  const c = [py >= pi[1], py < pj[1], e[0] * w[1] > e[1] * w[0]];
42
- if (every3(c) || !some3(c))
43
- s *= -1;
42
+ if (every3(c) || !some3(c)) s *= -1;
44
43
  }
45
44
  return s * sqrt(d);
46
45
  };
package/ops.js CHANGED
@@ -22,18 +22,13 @@ const withSDFModifiers = (fn, mods) => {
22
22
  min: $min2,
23
23
  max: $max2
24
24
  } = { ...DEFAULT_MODS, ...mods };
25
- if ($abs2)
26
- fn = abs(fn);
27
- if (isFunction($offset) || $offset > 0)
28
- fn = offset(fn, $offset);
29
- if ($flip)
30
- fn = flip(fn);
25
+ if ($abs2) fn = abs(fn);
26
+ if (isFunction($offset) || $offset > 0) fn = offset(fn, $offset);
27
+ if ($flip) fn = flip(fn);
31
28
  if ($min2 >= -Infinity) {
32
- if ($max2 < Infinity)
33
- return clamp(fn, $min2, $max2);
29
+ if ($max2 < Infinity) return clamp(fn, $min2, $max2);
34
30
  fn = max(fn, $min2);
35
- } else if ($max2 < Infinity)
36
- fn = min(fn, $max2);
31
+ } else if ($max2 < Infinity) fn = min(fn, $max2);
37
32
  return fn;
38
33
  };
39
34
  const abs = (sdf) => (p, minD) => $abs(sdf(p, minD));
@@ -47,12 +42,10 @@ const defOp = (op) => (children) => {
47
42
  const n = children.length;
48
43
  return (p, minD = Infinity) => {
49
44
  let res = children[0](p, minD);
50
- if (res < minD)
51
- minD = res;
45
+ if (res < minD) minD = res;
52
46
  for (let i = 1; i < n; i++) {
53
47
  const d = children[i](p, minD);
54
- if (d < minD)
55
- minD = d;
48
+ if (d < minD) minD = d;
56
49
  res = op(res, d);
57
50
  }
58
51
  return res;
@@ -68,12 +61,10 @@ const defParamOp = (op) => (k, children) => {
68
61
  return (p, minD = Infinity) => {
69
62
  const $k = kfield(p);
70
63
  let res = children[0](p, minD);
71
- if (res < minD)
72
- minD = res;
64
+ if (res < minD) minD = res;
73
65
  for (let i = 1; i < n; i++) {
74
66
  const d = children[i](p, minD);
75
- if (d < minD)
76
- minD = d;
67
+ if (d < minD) minD = d;
77
68
  res = op(res, d, $k);
78
69
  }
79
70
  return res;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom-sdf",
3
- "version": "0.3.32",
3
+ "version": "0.4.0",
4
4
  "description": "2D Signed Distance Field creation from @thi.ng/geom shapes, conversions, sampling, combinators",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -36,24 +36,24 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.11.1",
40
- "@thi.ng/checks": "^3.6.3",
41
- "@thi.ng/defmulti": "^3.0.38",
42
- "@thi.ng/errors": "^2.5.6",
43
- "@thi.ng/geom": "^6.1.8",
44
- "@thi.ng/geom-api": "^4.0.8",
45
- "@thi.ng/geom-isoline": "^2.1.125",
46
- "@thi.ng/geom-poly-utils": "^2.3.113",
47
- "@thi.ng/geom-resample": "^2.3.51",
48
- "@thi.ng/math": "^5.10.12",
49
- "@thi.ng/transducers": "^9.0.3",
50
- "@thi.ng/vectors": "^7.10.29"
39
+ "@thi.ng/api": "^8.11.2",
40
+ "@thi.ng/checks": "^3.6.4",
41
+ "@thi.ng/defmulti": "^3.0.39",
42
+ "@thi.ng/errors": "^2.5.7",
43
+ "@thi.ng/geom": "^7.0.0",
44
+ "@thi.ng/geom-api": "^4.0.10",
45
+ "@thi.ng/geom-isoline": "^2.1.127",
46
+ "@thi.ng/geom-poly-utils": "^2.4.0",
47
+ "@thi.ng/geom-resample": "^2.3.53",
48
+ "@thi.ng/math": "^5.10.13",
49
+ "@thi.ng/transducers": "^9.0.5",
50
+ "@thi.ng/vectors": "^7.10.31"
51
51
  },
52
52
  "devDependencies": {
53
- "@microsoft/api-extractor": "^7.43.0",
54
- "esbuild": "^0.20.2",
55
- "typedoc": "^0.25.12",
56
- "typescript": "^5.4.3"
53
+ "@microsoft/api-extractor": "^7.43.2",
54
+ "esbuild": "^0.21.1",
55
+ "typedoc": "^0.25.13",
56
+ "typescript": "^5.4.5"
57
57
  },
58
58
  "keywords": [
59
59
  "2d",
@@ -128,5 +128,5 @@
128
128
  "status": "alpha",
129
129
  "year": 2022
130
130
  },
131
- "gitHead": "5dd66c18a3862a3af69a5b2f49563f7cbdd960c2\n"
131
+ "gitHead": "df34b4a9e650cc7323575356de207d78933bdcf3\n"
132
132
  }