@thi.ng/geom 4.4.0 → 5.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-03-24T19:50:18Z
3
+ - **Last updated**: 2023-04-08T11:09:50Z
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,27 @@ 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
+ # [5.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@5.0.0) (2023-04-08)
13
+
14
+ #### 🛑 Breaking changes
15
+
16
+ - update asSVG() bleed handling ([cf3eafb](https://github.com/thi-ng/umbrella/commit/cf3eafb))
17
+ - BREAKING CHANGE: rename `bleed` attrib to `__bleed`
18
+ - for consistency, keep all control attribs prefixed as `__xxx`
19
+ - add asSvg() support for `__prec`
20
+ - update docs
21
+ - update splitArcLength() group handling ([6b97085](https://github.com/thi-ng/umbrella/commit/6b97085))
22
+ - BREAKING CHANGE: update splitArcLength() group handling & return type
23
+ - update group handling to form sub-groups of predictable length
24
+ (e.g. grouping shorter shapes and/or splitting longer shapes until desired arc length is reached)
25
+ - remove support for nested groups
26
+ - update docs, add example
27
+ - update all impls to return single group
28
+
29
+ #### 🚀 Features
30
+
31
+ - update inscribedSquare/Hex() args, add attribs ([317f630](https://github.com/thi-ng/umbrella/commit/317f630))
32
+
12
33
  ## [4.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@4.4.0) (2023-03-24)
13
34
 
14
35
  #### 🚀 Features
package/README.md CHANGED
@@ -122,7 +122,7 @@ directly and/or perform automatic resampling/conversion if needed).
122
122
  | [`scale()`](https://docs.thi.ng/umbrella/geom/functions/scale.html) | scale shape (uniformly/non-uniformly) |
123
123
  | [`scatter()`](https://docs.thi.ng/umbrella/geom/functions/scatter.html) | create random points inside a shape boundary |
124
124
  | [`simplify()`](https://docs.thi.ng/umbrella/geom/functions/simplify.html) | simplify shape/boundary (Douglas-Peucker) |
125
- | [`splitArcLength()`](https://docs.thi.ng/umbrella/geom/functions/splitArcLength.html) | split shapes based on max. arc length |
125
+ | [`splitArcLength()`](https://docs.thi.ng/umbrella/geom/functions/splitArcLength.html) | split shapes & groups based on max. arc length |
126
126
  | [`splitAt()`](https://docs.thi.ng/umbrella/geom/functions/splitAt.html) | split shape/boundary at parametric position |
127
127
  | [`splitNear()`](https://docs.thi.ng/umbrella/geom/functions/splitNear.html) | split shape/boundary near world position |
128
128
  | [`subdivCurve()`](https://docs.thi.ng/umbrella/geom/functions/subdivCurve.html) | recursively apply curve subdivision kernel |
@@ -199,7 +199,7 @@ For Node.js REPL:
199
199
  const geom = await import("@thi.ng/geom");
200
200
  ```
201
201
 
202
- Package sizes (brotli'd, pre-treeshake): ESM: 12.62 KB
202
+ Package sizes (brotli'd, pre-treeshake): ESM: 12.71 KB
203
203
 
204
204
  ## Dependencies
205
205
 
@@ -253,12 +253,14 @@ A selection:
253
253
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/kmeans-viz.jpg" width="240"/> | k-means clustering visualization | [Demo](https://demo.thi.ng/umbrella/kmeans-viz/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/kmeans-viz) |
254
254
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/poisson/poisson.jpg" width="240"/> | 2D Poisson-disc sampler with procedural gradient map | [Demo](https://demo.thi.ng/umbrella/poisson-circles/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/poisson-circles) |
255
255
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/poly-spline.png" width="240"/> | Polygon to cubic curve conversion & visualization | [Demo](https://demo.thi.ng/umbrella/poly-spline/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/poly-spline) |
256
+ | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rdom-canvas-basics.png" width="240"/> | Minimal rdom-canvas animation | [Demo](https://demo.thi.ng/umbrella/rdom-canvas-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rdom-canvas-basics) |
256
257
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rotating-voronoi.jpg" width="240"/> | Animated Voronoi diagram, cubic splines & SVG download | [Demo](https://demo.thi.ng/umbrella/rotating-voronoi/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rotating-voronoi) |
257
258
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/scenegraph.png" width="240"/> | 2D scenegraph & shape picking | [Demo](https://demo.thi.ng/umbrella/scenegraph/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/scenegraph) |
258
259
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/scenegraph-image.png" width="240"/> | 2D scenegraph & image map based geometry manipulation | [Demo](https://demo.thi.ng/umbrella/scenegraph-image/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/scenegraph-image) |
259
260
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/spline-tangent.png" width="240"/> | Compute cubic spline position & tangent using Dual Numbers | [Demo](https://demo.thi.ng/umbrella/spline-tangent/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/spline-tangent) |
260
261
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/svg-resample.png" width="240"/> | SVG path parsing & dynamic resampling | [Demo](https://demo.thi.ng/umbrella/svg-resample/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/svg-resample) |
261
262
  | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/text-canvas.png" width="240"/> | 3D wireframe textmode demo | [Demo](https://demo.thi.ng/umbrella/text-canvas/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/text-canvas) |
263
+ | <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/trace-bitmap.jpg" width="240"/> | Multi-layer vectorization & dithering of bitmap images | [Demo](https://demo.thi.ng/umbrella/trace-bitmap/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/trace-bitmap) |
262
264
 
263
265
  ## API
264
266
 
package/aabb.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Attribs } from "@thi.ng/geom-api";
2
- import { ReadonlyVec, Vec } from "@thi.ng/vectors/api";
2
+ import { type ReadonlyVec, type Vec } from "@thi.ng/vectors/api";
3
3
  import { AABB } from "./api/aabb.js";
4
4
  import type { Sphere } from "./api/sphere.js";
5
5
  export declare function aabb(pos: Vec, size: number | Vec, attribs?: Attribs): AABB;
package/api/aabb.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { IToHiccup } from "@thi.ng/api";
2
2
  import type { AABBLike, Attribs } from "@thi.ng/geom-api";
3
- import { Vec } from "@thi.ng/vectors/api";
3
+ import { type Vec } from "@thi.ng/vectors/api";
4
4
  export declare class AABB implements AABBLike, IToHiccup {
5
5
  pos: Vec;
6
6
  attribs?: Attribs | undefined;
@@ -11,6 +11,6 @@ export declare class AABB implements AABBLike, IToHiccup {
11
11
  withAttribs(attribs: Attribs): AABB;
12
12
  max(): Vec;
13
13
  offset(offset: number): this;
14
- toHiccup(): (string | Attribs | undefined)[];
14
+ toHiccup(): (string | Vec | Attribs | undefined)[];
15
15
  }
16
16
  //# sourceMappingURL=aabb.d.ts.map
package/api/arc.d.ts CHANGED
@@ -16,7 +16,7 @@ export declare class Arc implements IHiccupShape, IHiccupPathSegment {
16
16
  equiv(o: any): boolean;
17
17
  pointAt(t: number, out?: Vec): Vec;
18
18
  pointAtTheta(theta: number, out?: Vec): Vec;
19
- toHiccup(): (string | Attribs | undefined)[];
19
+ toHiccup(): (string | Attribs | (string | number | boolean | Vec)[][] | undefined)[];
20
20
  toHiccupPathSegments(): (string | number | boolean | Vec)[][];
21
21
  }
22
22
  //# sourceMappingURL=arc.d.ts.map
package/api/circle.d.ts CHANGED
@@ -8,6 +8,6 @@ export declare class Circle implements IHiccupShape {
8
8
  get type(): string;
9
9
  copy(): Circle;
10
10
  withAttribs(attribs: Attribs): Circle;
11
- toHiccup(): (string | number | Attribs | undefined)[];
11
+ toHiccup(): (string | number | Vec | Attribs | undefined)[];
12
12
  }
13
13
  //# sourceMappingURL=circle.d.ts.map
package/api/cubic.d.ts CHANGED
@@ -4,7 +4,7 @@ export declare class Cubic extends APC implements IHiccupPathSegment {
4
4
  get type(): string;
5
5
  copy(): Cubic;
6
6
  withAttribs(attribs: Attribs): Cubic;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | Attribs | (string | import("@thi.ng/vectors").Vec)[][] | undefined)[];
8
8
  toHiccupPathSegments(): (string | import("@thi.ng/vectors").Vec)[][];
9
9
  }
10
10
  //# sourceMappingURL=cubic.d.ts.map
package/api/ellipse.d.ts CHANGED
@@ -8,6 +8,6 @@ export declare class Ellipse implements IHiccupShape {
8
8
  get type(): string;
9
9
  copy(): Ellipse;
10
10
  withAttribs(attribs: Attribs): Ellipse;
11
- toHiccup(): (string | Attribs | undefined)[];
11
+ toHiccup(): (string | Vec | Attribs | undefined)[];
12
12
  }
13
13
  //# sourceMappingURL=ellipse.d.ts.map
package/api/line.d.ts CHANGED
@@ -4,7 +4,7 @@ export declare class Line extends APC implements IHiccupShape, IHiccupPathSegmen
4
4
  get type(): string;
5
5
  copy(): Line;
6
6
  withAttribs(attribs: Attribs): Line;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec | Attribs | undefined)[];
8
8
  toHiccupPathSegments(): ((string | number)[] | (string | import("@thi.ng/vectors").Vec)[])[];
9
9
  }
10
10
  //# sourceMappingURL=line.d.ts.map
package/api/path.d.ts CHANGED
@@ -10,6 +10,6 @@ export declare class Path implements IHiccupShape {
10
10
  withAttribs(attribs: Attribs): Path;
11
11
  equiv(o: any): boolean;
12
12
  add(s: PathSegment): void;
13
- toHiccup(): (string | Attribs)[];
13
+ toHiccup(): (string | any[] | Attribs)[];
14
14
  }
15
15
  //# sourceMappingURL=path.d.ts.map
package/api/plane.d.ts CHANGED
@@ -8,6 +8,6 @@ export declare class Plane implements IHiccupShape {
8
8
  get type(): string;
9
9
  copy(): Plane;
10
10
  withAttribs(attribs: Attribs): Plane;
11
- toHiccup(): (string | number | Attribs | undefined)[];
11
+ toHiccup(): (string | number | Vec | Attribs | undefined)[];
12
12
  }
13
13
  //# sourceMappingURL=plane.d.ts.map
package/api/points.d.ts CHANGED
@@ -4,12 +4,12 @@ export declare class Points extends APC implements IHiccupShape {
4
4
  get type(): string;
5
5
  copy(): Points;
6
6
  withAttribs(attribs: Attribs): Points;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
8
8
  }
9
9
  export declare class Points3 extends APC implements IHiccupShape {
10
10
  get type(): string;
11
11
  copy(): Points3;
12
12
  withAttribs(attribs: Attribs): Points3;
13
- toHiccup(): (string | Attribs | undefined)[];
13
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
14
14
  }
15
15
  //# sourceMappingURL=points.d.ts.map
package/api/polygon.d.ts CHANGED
@@ -4,6 +4,6 @@ export declare class Polygon extends APC implements IHiccupShape {
4
4
  get type(): string;
5
5
  copy(): Polygon;
6
6
  withAttribs(attribs: Attribs): Polygon;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
8
8
  }
9
9
  //# sourceMappingURL=polygon.d.ts.map
package/api/quad.d.ts CHANGED
@@ -4,6 +4,6 @@ export declare class Quad extends APC implements IHiccupShape {
4
4
  get type(): string;
5
5
  copy(): Quad;
6
6
  withAttribs(attribs: Attribs): Quad;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
8
8
  }
9
9
  //# sourceMappingURL=quad.d.ts.map
package/api/quad3.d.ts CHANGED
@@ -4,6 +4,6 @@ export declare class Quad3 extends APC implements IHiccupShape {
4
4
  get type(): string;
5
5
  copy(): Quad3;
6
6
  withAttribs(attribs: Attribs): Quad3;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
8
8
  }
9
9
  //# sourceMappingURL=quad3.d.ts.map
@@ -4,7 +4,7 @@ export declare class Quadratic extends APC implements IHiccupShape, IHiccupPathS
4
4
  get type(): string;
5
5
  copy(): Quadratic;
6
6
  withAttribs(attribs: Attribs): Quadratic;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | Attribs | (string | import("@thi.ng/vectors").Vec)[][] | undefined)[];
8
8
  toHiccupPathSegments(): (string | import("@thi.ng/vectors").Vec)[][];
9
9
  }
10
10
  //# sourceMappingURL=quadratic.d.ts.map
package/api/ray.d.ts CHANGED
@@ -8,6 +8,6 @@ export declare class Ray implements IHiccupShape {
8
8
  get type(): string;
9
9
  copy(): Ray;
10
10
  withAttribs(attribs: Attribs): Ray;
11
- toHiccup(): (string | Attribs | undefined)[];
11
+ toHiccup(): (string | Vec | Attribs | undefined)[];
12
12
  }
13
13
  //# sourceMappingURL=ray.d.ts.map
package/api/rect.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { AABBLike, Attribs, IHiccupShape } from "@thi.ng/geom-api";
2
- import { Vec } from "@thi.ng/vectors/api";
2
+ import { type Vec } from "@thi.ng/vectors/api";
3
3
  export declare class Rect implements AABBLike, IHiccupShape {
4
4
  pos: Vec;
5
5
  attribs?: Attribs | undefined;
@@ -10,6 +10,6 @@ export declare class Rect implements AABBLike, IHiccupShape {
10
10
  withAttribs(attribs: Attribs): Rect;
11
11
  max(): Vec;
12
12
  offset(offset: number): this;
13
- toHiccup(): (string | number | Attribs | undefined)[];
13
+ toHiccup(): (string | number | Vec | Attribs | undefined)[];
14
14
  }
15
15
  //# sourceMappingURL=rect.d.ts.map
package/api/sphere.d.ts CHANGED
@@ -8,6 +8,6 @@ export declare class Sphere implements IHiccupShape {
8
8
  get type(): string;
9
9
  copy(): Sphere;
10
10
  withAttribs(attribs: Attribs): Sphere;
11
- toHiccup(): (string | number | Attribs | undefined)[];
11
+ toHiccup(): (string | number | Vec | Attribs | undefined)[];
12
12
  }
13
13
  //# sourceMappingURL=sphere.d.ts.map
package/api/triangle.d.ts CHANGED
@@ -4,6 +4,6 @@ export declare class Triangle extends APC implements IHiccupShape {
4
4
  get type(): string;
5
5
  copy(): Triangle;
6
6
  withAttribs(attribs: Attribs): Triangle;
7
- toHiccup(): (string | Attribs | undefined)[];
7
+ toHiccup(): (string | import("@thi.ng/vectors").Vec[] | Attribs | undefined)[];
8
8
  }
9
9
  //# sourceMappingURL=triangle.d.ts.map
package/as-svg.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import type { Attribs, IShape } from "@thi.ng/geom-api";
2
+ /**
3
+ * Can be overridden via {@link setSvgDefaultAttribs}.
4
+ */
5
+ export declare let DEFAULT_ATTRIBS: Attribs;
2
6
  /**
3
7
  * Sets the SVG root element attribs used by default by {@link svgDoc}.
4
8
  *
@@ -12,15 +16,28 @@ export declare const setSvgDefaultAttribs: (attribs: Attribs) => void;
12
16
  */
13
17
  export declare const asSvg: (...args: any[]) => string;
14
18
  /**
15
- * Creates a hiccup SVG doc element for given {@link IShape}s and attribs
16
- * (merged with default attribs). If the attribs do not include a `viewBox`, it
17
- * will be computed automatically. Furthermore (and only for the case a viewbox
18
- * needs to be computed), a `bleed` attrib can be provided to include a
19
- * bleed/margin for the viewbox.
19
+ * Creates a hiccup SVG doc element container for given {@link IShape}s and
20
+ * attribs (merged with {@link DEFAULT_ATTRIBS}). If the attribs do not include
21
+ * a `viewBox`, it will be computed automatically. Furthermore (and only for the
22
+ * case a viewbox needs to be computed), a `__bleed` attrib can be provided to
23
+ * include a bleed/margin for the viewbox (in world space units).
20
24
  *
21
25
  * @remarks
22
26
  * Use {@link asSvg} to serialize the resulting doc to an SVG string.
23
27
  *
28
+ * The actual serialization is performed via the
29
+ * [thi.ng/hiccup](https://thi.ng/hiccup) and
30
+ * [thi.ng/hiccup-svg](https://thi.ng/hiccup-svg) packages. Floating point
31
+ * precision for various point coordinates can be controlled via the `__prec`
32
+ * attribute (number of fractional digits), either for the entire doc or on a
33
+ * per-shape basis. If omitted, the currently configured precision will be used
34
+ * (default: 3).
35
+ *
36
+ * Also see
37
+ * [`convertTree()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/convertTree.html)
38
+ * and
39
+ * [`setPrecision()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/setPrecision.html).
40
+ *
24
41
  * @param attribs
25
42
  * @param xs
26
43
  */
package/as-svg.js CHANGED
@@ -8,7 +8,7 @@ import { __collBounds } from "./internal/bounds.js";
8
8
  /**
9
9
  * Can be overridden via {@link setSvgDefaultAttribs}.
10
10
  */
11
- let DEFAULT_ATTRIBS = { fill: "none", stroke: "#000" };
11
+ export let DEFAULT_ATTRIBS = { fill: "none", stroke: "#000" };
12
12
  /**
13
13
  * Sets the SVG root element attribs used by default by {@link svgDoc}.
14
14
  *
@@ -24,15 +24,28 @@ export const setSvgDefaultAttribs = (attribs) => {
24
24
  */
25
25
  export const asSvg = (...args) => args.map((x) => serialize(convertTree(x))).join("");
26
26
  /**
27
- * Creates a hiccup SVG doc element for given {@link IShape}s and attribs
28
- * (merged with default attribs). If the attribs do not include a `viewBox`, it
29
- * will be computed automatically. Furthermore (and only for the case a viewbox
30
- * needs to be computed), a `bleed` attrib can be provided to include a
31
- * bleed/margin for the viewbox.
27
+ * Creates a hiccup SVG doc element container for given {@link IShape}s and
28
+ * attribs (merged with {@link DEFAULT_ATTRIBS}). If the attribs do not include
29
+ * a `viewBox`, it will be computed automatically. Furthermore (and only for the
30
+ * case a viewbox needs to be computed), a `__bleed` attrib can be provided to
31
+ * include a bleed/margin for the viewbox (in world space units).
32
32
  *
33
33
  * @remarks
34
34
  * Use {@link asSvg} to serialize the resulting doc to an SVG string.
35
35
  *
36
+ * The actual serialization is performed via the
37
+ * [thi.ng/hiccup](https://thi.ng/hiccup) and
38
+ * [thi.ng/hiccup-svg](https://thi.ng/hiccup-svg) packages. Floating point
39
+ * precision for various point coordinates can be controlled via the `__prec`
40
+ * attribute (number of fractional digits), either for the entire doc or on a
41
+ * per-shape basis. If omitted, the currently configured precision will be used
42
+ * (default: 3).
43
+ *
44
+ * Also see
45
+ * [`convertTree()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/convertTree.html)
46
+ * and
47
+ * [`setPrecision()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/setPrecision.html).
48
+ *
36
49
  * @param attribs
37
50
  * @param xs
38
51
  */
@@ -43,7 +56,7 @@ export const svgDoc = (attribs, ...xs) => {
43
56
  const cbounds = __collBounds(xs, bounds);
44
57
  if (cbounds) {
45
58
  const [[x, y], [w, h]] = cbounds;
46
- const bleed = attribs.bleed || 0;
59
+ const bleed = attribs.__bleed || 0;
47
60
  const bleed2 = 2 * bleed;
48
61
  const width = ff(w + bleed2);
49
62
  const height = ff(h + bleed2);
@@ -51,7 +64,7 @@ export const svgDoc = (attribs, ...xs) => {
51
64
  width,
52
65
  height,
53
66
  viewBox: `${ff(x - bleed)} ${ff(y - bleed)} ${width} ${height}`,
54
- ...withoutKeysObj(attribs, ["bleed"]),
67
+ ...withoutKeysObj(attribs, ["__bleed"]),
55
68
  };
56
69
  }
57
70
  }
package/bpatch.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Attribs } from "@thi.ng/geom-api";
2
- import { Vec } from "@thi.ng/vectors";
2
+ import type { Vec } from "@thi.ng/vectors";
3
3
  import { BPatch } from "./api/bpatch.js";
4
4
  export declare const bpatch: (pts: Vec[], attribs?: Attribs) => BPatch;
5
5
  export declare const bpatchFromQuad: (pts: Vec[], attribs?: Attribs) => BPatch;
package/bpatch.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { assert } from "@thi.ng/errors/assert";
2
- import { mixBilinear } from "@thi.ng/vectors";
2
+ import { mixBilinear } from "@thi.ng/vectors/mix-bilinear";
3
3
  import { BPatch } from "./api/bpatch.js";
4
4
  export const bpatch = (pts, attribs) => new BPatch(pts, attribs);
5
5
  export const bpatchFromQuad = (pts, attribs) => {
package/center.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { MultiFn1O } from "@thi.ng/defmulti";
2
2
  import type { IShape } from "@thi.ng/geom-api";
3
- import { ReadonlyVec } from "@thi.ng/vectors/api";
3
+ import { type ReadonlyVec } from "@thi.ng/vectors/api";
4
4
  /**
5
5
  * Returns copy of given shape centered around optionally provided point `p`
6
6
  * (default: worldspace origin).
@@ -1,5 +1,5 @@
1
1
  import type { Attribs } from "@thi.ng/geom-api";
2
- import { SamplingOpts } from "@thi.ng/geom-api/sample";
2
+ import { type SamplingOpts } from "@thi.ng/geom-api/sample";
3
3
  /** @internal */
4
4
  export declare const __circleOpts: (opts: number | Partial<SamplingOpts>, r: number) => [number, number, boolean];
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom",
3
- "version": "4.4.0",
3
+ "version": "5.0.0",
4
4
  "description": "Functional, polymorphic API for 2D geometry types & SVG generation",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -35,41 +35,41 @@
35
35
  "tool:bpatch": "tools:node-esm tools/bpatch.ts"
36
36
  },
37
37
  "dependencies": {
38
- "@thi.ng/api": "^8.7.4",
39
- "@thi.ng/arrays": "^2.5.8",
40
- "@thi.ng/associative": "^6.2.32",
41
- "@thi.ng/checks": "^3.3.10",
42
- "@thi.ng/defmulti": "^2.1.33",
43
- "@thi.ng/equiv": "^2.1.20",
44
- "@thi.ng/errors": "^2.2.13",
45
- "@thi.ng/geom-api": "^3.4.11",
46
- "@thi.ng/geom-arc": "^2.1.54",
47
- "@thi.ng/geom-clip-line": "^2.3.11",
48
- "@thi.ng/geom-clip-poly": "^2.1.53",
49
- "@thi.ng/geom-closest-point": "^2.1.49",
50
- "@thi.ng/geom-hull": "^2.1.49",
51
- "@thi.ng/geom-isec": "^2.1.53",
52
- "@thi.ng/geom-poly-utils": "^2.3.37",
53
- "@thi.ng/geom-resample": "^2.2.11",
54
- "@thi.ng/geom-splines": "^2.2.28",
55
- "@thi.ng/geom-subdiv-curve": "^2.1.53",
56
- "@thi.ng/geom-tessellate": "^2.1.53",
57
- "@thi.ng/hiccup": "^4.2.37",
58
- "@thi.ng/hiccup-svg": "^4.3.39",
59
- "@thi.ng/math": "^5.4.5",
60
- "@thi.ng/matrices": "^2.1.50",
61
- "@thi.ng/random": "^3.3.27",
62
- "@thi.ng/strings": "^3.4.2",
63
- "@thi.ng/transducers": "^8.4.0",
64
- "@thi.ng/vectors": "^7.6.9"
38
+ "@thi.ng/api": "^8.7.6",
39
+ "@thi.ng/arrays": "^2.5.10",
40
+ "@thi.ng/associative": "^6.2.34",
41
+ "@thi.ng/checks": "^3.3.12",
42
+ "@thi.ng/defmulti": "^2.1.35",
43
+ "@thi.ng/equiv": "^2.1.22",
44
+ "@thi.ng/errors": "^2.2.15",
45
+ "@thi.ng/geom-api": "^3.4.13",
46
+ "@thi.ng/geom-arc": "^2.1.56",
47
+ "@thi.ng/geom-clip-line": "^2.3.13",
48
+ "@thi.ng/geom-clip-poly": "^2.1.55",
49
+ "@thi.ng/geom-closest-point": "^2.1.51",
50
+ "@thi.ng/geom-hull": "^2.1.51",
51
+ "@thi.ng/geom-isec": "^2.1.55",
52
+ "@thi.ng/geom-poly-utils": "^2.3.39",
53
+ "@thi.ng/geom-resample": "^2.2.13",
54
+ "@thi.ng/geom-splines": "^2.2.30",
55
+ "@thi.ng/geom-subdiv-curve": "^2.1.55",
56
+ "@thi.ng/geom-tessellate": "^2.1.55",
57
+ "@thi.ng/hiccup": "^4.2.39",
58
+ "@thi.ng/hiccup-svg": "^5.0.0",
59
+ "@thi.ng/math": "^5.4.7",
60
+ "@thi.ng/matrices": "^2.1.52",
61
+ "@thi.ng/random": "^3.3.29",
62
+ "@thi.ng/strings": "^3.4.4",
63
+ "@thi.ng/transducers": "^8.4.2",
64
+ "@thi.ng/vectors": "^7.6.11"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@microsoft/api-extractor": "^7.34.4",
68
- "@thi.ng/testament": "^0.3.13",
69
- "rimraf": "^4.4.0",
68
+ "@thi.ng/testament": "^0.3.15",
69
+ "rimraf": "^4.4.1",
70
70
  "tools": "^0.0.1",
71
- "typedoc": "^0.23.26",
72
- "typescript": "^4.9.5"
71
+ "typedoc": "^0.23.28",
72
+ "typescript": "^5.0.4"
73
73
  },
74
74
  "keywords": [
75
75
  "2d",
@@ -398,5 +398,5 @@
398
398
  ],
399
399
  "year": 2013
400
400
  },
401
- "gitHead": "51a3361eb4b4e906ff6dfc114049f1ea9cd97d0e\n"
401
+ "gitHead": "abcedd9e4e06a4b631f363610eec572f79b571c1\n"
402
402
  }
package/quad.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Attribs } from "@thi.ng/geom-api";
2
- import { ReadonlyVec, Vec } from "@thi.ng/vectors/api";
2
+ import { type ReadonlyVec, type Vec } from "@thi.ng/vectors/api";
3
3
  import type { Plane } from "./api/plane.js";
4
4
  import { Quad } from "./api/quad.js";
5
5
  import { Quad3 } from "./api/quad3.js";
package/rect.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Attribs } from "@thi.ng/geom-api";
2
- import { ReadonlyVec, Vec } from "@thi.ng/vectors/api";
2
+ import { type ReadonlyVec, type Vec } from "@thi.ng/vectors/api";
3
3
  import type { Circle } from "./api/circle.js";
4
4
  import type { Polygon } from "./api/polygon.js";
5
5
  import { Rect } from "./api/rect.js";
@@ -23,15 +23,16 @@ export declare const intersectionRect: (a: Rect, b: Rect) => Rect | undefined;
23
23
  * given as centroid & radius.
24
24
  *
25
25
  * @param circle - target circle
26
+ * @param attribs -
26
27
  */
27
- export declare function inscribedSquare(circle: Circle): Rect;
28
- export declare function inscribedSquare(pos: ReadonlyVec, r: number): Rect;
28
+ export declare function inscribedSquare(circle: Circle, attribs?: Attribs): Rect;
29
+ export declare function inscribedSquare(pos: ReadonlyVec, r: number, attribs?: Attribs): Rect;
29
30
  /**
30
31
  * Returns square inscribed in given (unrotated) hexagon. The hexagon
31
32
  * can be given as {@link Polygon} or centroid and edge length.
32
33
  *
33
34
  * @param hex - target hexagon
34
35
  */
35
- export declare function inscribedSquareHex(hex: Polygon): Rect;
36
- export declare function inscribedSquareHex(pos: ReadonlyVec, len: number): Rect;
36
+ export declare function inscribedSquareHex(hex: Polygon, attribs?: Attribs): Rect;
37
+ export declare function inscribedSquareHex(pos: ReadonlyVec, len: number, attribs?: Attribs): Rect;
37
38
  //# sourceMappingURL=rect.d.ts.map
package/rect.js CHANGED
@@ -9,7 +9,7 @@ import { min2 } from "@thi.ng/vectors/min";
9
9
  import { sub2 } from "@thi.ng/vectors/sub";
10
10
  import { subN2 } from "@thi.ng/vectors/subn";
11
11
  import { Rect } from "./api/rect.js";
12
- import { __argsVV, __asVec } from "./internal/args.js";
12
+ import { __argAttribs, __argsVV, __asVec } from "./internal/args.js";
13
13
  export function rect(...args) {
14
14
  return new Rect(...__argsVV(args));
15
15
  }
@@ -35,6 +35,7 @@ export const intersectionRect = (a, b) => {
35
35
  };
36
36
  export function inscribedSquare(...args) {
37
37
  let pos, r;
38
+ const attribs = __argAttribs(args);
38
39
  if (args.length === 1) {
39
40
  const c = args[0];
40
41
  pos = c.pos;
@@ -44,10 +45,11 @@ export function inscribedSquare(...args) {
44
45
  [pos, r] = args;
45
46
  }
46
47
  r *= SQRT2_2;
47
- return rect(subN2([], pos, r), r * 2);
48
+ return rect(subN2([], pos, r), r * 2, attribs);
48
49
  }
49
50
  export function inscribedSquareHex(...args) {
50
51
  let pos, l;
52
+ const attribs = __argAttribs(args);
51
53
  if (args.length === 1) {
52
54
  const pts = args[0].points;
53
55
  pos = centroid(pts);
@@ -57,5 +59,5 @@ export function inscribedSquareHex(...args) {
57
59
  [pos, l] = args;
58
60
  }
59
61
  l *= 3 - SQRT3;
60
- return rect(subN2([], pos, l / 2), l);
62
+ return rect(subN2([], pos, l / 2), l, attribs);
61
63
  }
@@ -1,8 +1,9 @@
1
1
  import type { MultiFn2 } from "@thi.ng/defmulti";
2
2
  import type { IShape } from "@thi.ng/geom-api";
3
+ import { Group } from "./api/group.js";
3
4
  /**
4
5
  * Splits given shape into {@link Polyline} segments of given (max) arc length.
5
- * Returns array of new shapes/polylines.
6
+ * Returns a {@link Group} of shapes/polylines.
6
7
  *
7
8
  * @remarks
8
9
  * If the shape has a `__samples` attribute, it will be removed in the result to
@@ -16,13 +17,52 @@ import type { IShape } from "@thi.ng/geom-api";
16
17
  * Other shape types will be attempted to be auto-converted via
17
18
  * {@link asPolyline} first.
18
19
  *
19
- * Groups will be recursively processed (i.e. by calling {@link splitArcLength}
20
- * for each child). Any nested groups will be retained, but each group might
21
- * have a greater resulting number of children (depending on number of splits
22
- * performed).
20
+ * Nested groups are NOT supported. Groups are processing their child shapes and
21
+ * forming new child groups of given max. arc lengths and potentially splitting
22
+ * shapes if they don't fit within the current subgroup...
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * // circle (to be sampled as octagon)
27
+ * const a = circle(100, { stroke: "red", __samples: 8 });
28
+ *
29
+ * // inner square of circle
30
+ * const b = inscribedSquare(a, { stroke: "blue" });
31
+ *
32
+ * // process as group, split/partition into subgroups of arclength max. 200
33
+ * splitArcLength(group({}, [a, b]), 200);
34
+ * ```
35
+ *
36
+ * Result serialized to SVG:
37
+ *
38
+ * ```svg
39
+ * <g>
40
+ * <g>
41
+ * <polyline fill="none" points="100,0 70.7,70.7 0.0,100 -43.4,82.0" stroke="red"/>
42
+ * </g>
43
+ * <g>
44
+ * <polyline fill="none" points="-43.4,82.0 -70.7,70.7 -100,0.0 -70.7,-70.7 -54.7,-77.3" stroke="red"/>
45
+ * </g>
46
+ * <g>
47
+ * <polyline fill="none" points="-54.7,-77.3 -0.0,-100 70.7,-70.7 95.3,-11.4" stroke="red"/>
48
+ * </g>
49
+ * <g>
50
+ * <!-- last segment of circle -->
51
+ * <polyline fill="none" points="95.3,-11.4 100,0" stroke="red"/>
52
+ * <!-- first segment of rect -->
53
+ * <polyline fill="none" points="-70.7,-70.7 70.7,-70.7 70.7,-24.4" stroke="blue"/>
54
+ * </g>
55
+ * <g>
56
+ * <polyline fill="none" points="70.7,-24.4 70.7,70.7 -34.2,70.7" stroke="blue"/>
57
+ * </g>
58
+ * <g>
59
+ * <polyline fill="none" points="-34.2,70.7 -70.7,70.7 -70.7,-70.7" stroke="blue"/>
60
+ * </g>
61
+ * </g>
62
+ * ```
23
63
  *
24
64
  * @param shape
25
65
  * @param dist
26
66
  */
27
- export declare const splitArcLength: MultiFn2<IShape, number, IShape[]>;
67
+ export declare const splitArcLength: MultiFn2<IShape, number, Group>;
28
68
  //# sourceMappingURL=split-arclength.d.ts.map
@@ -1,6 +1,5 @@
1
1
  import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
2
2
  import { Sampler } from "@thi.ng/geom-resample/sampler";
3
- import { mapcat } from "@thi.ng/transducers/mapcat";
4
3
  import { Group } from "./api/group.js";
5
4
  import { Polyline } from "./api/polyline.js";
6
5
  import { asPolyline } from "./as-polyline.js";
@@ -9,7 +8,7 @@ import { __dispatch } from "./internal/dispatch.js";
9
8
  import { __pointArraysAsShapes } from "./internal/points-as-shape.js";
10
9
  /**
11
10
  * Splits given shape into {@link Polyline} segments of given (max) arc length.
12
- * Returns array of new shapes/polylines.
11
+ * Returns a {@link Group} of shapes/polylines.
13
12
  *
14
13
  * @remarks
15
14
  * If the shape has a `__samples` attribute, it will be removed in the result to
@@ -23,21 +22,83 @@ import { __pointArraysAsShapes } from "./internal/points-as-shape.js";
23
22
  * Other shape types will be attempted to be auto-converted via
24
23
  * {@link asPolyline} first.
25
24
  *
26
- * Groups will be recursively processed (i.e. by calling {@link splitArcLength}
27
- * for each child). Any nested groups will be retained, but each group might
28
- * have a greater resulting number of children (depending on number of splits
29
- * performed).
25
+ * Nested groups are NOT supported. Groups are processing their child shapes and
26
+ * forming new child groups of given max. arc lengths and potentially splitting
27
+ * shapes if they don't fit within the current subgroup...
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * // circle (to be sampled as octagon)
32
+ * const a = circle(100, { stroke: "red", __samples: 8 });
33
+ *
34
+ * // inner square of circle
35
+ * const b = inscribedSquare(a, { stroke: "blue" });
36
+ *
37
+ * // process as group, split/partition into subgroups of arclength max. 200
38
+ * splitArcLength(group({}, [a, b]), 200);
39
+ * ```
40
+ *
41
+ * Result serialized to SVG:
42
+ *
43
+ * ```svg
44
+ * <g>
45
+ * <g>
46
+ * <polyline fill="none" points="100,0 70.7,70.7 0.0,100 -43.4,82.0" stroke="red"/>
47
+ * </g>
48
+ * <g>
49
+ * <polyline fill="none" points="-43.4,82.0 -70.7,70.7 -100,0.0 -70.7,-70.7 -54.7,-77.3" stroke="red"/>
50
+ * </g>
51
+ * <g>
52
+ * <polyline fill="none" points="-54.7,-77.3 -0.0,-100 70.7,-70.7 95.3,-11.4" stroke="red"/>
53
+ * </g>
54
+ * <g>
55
+ * <!-- last segment of circle -->
56
+ * <polyline fill="none" points="95.3,-11.4 100,0" stroke="red"/>
57
+ * <!-- first segment of rect -->
58
+ * <polyline fill="none" points="-70.7,-70.7 70.7,-70.7 70.7,-24.4" stroke="blue"/>
59
+ * </g>
60
+ * <g>
61
+ * <polyline fill="none" points="70.7,-24.4 70.7,70.7 -34.2,70.7" stroke="blue"/>
62
+ * </g>
63
+ * <g>
64
+ * <polyline fill="none" points="-34.2,70.7 -70.7,70.7 -70.7,-70.7" stroke="blue"/>
65
+ * </g>
66
+ * </g>
67
+ * ```
30
68
  *
31
69
  * @param shape
32
70
  * @param dist
33
71
  */
34
72
  export const splitArcLength = defmulti(__dispatch, {}, {
35
73
  [DEFAULT]: ($, d) => splitArcLength(asPolyline($), d),
36
- group: ($, d) => [
37
- new Group(__attribs($), [
38
- ...mapcat((c) => splitArcLength(c, d), $.children),
39
- ]),
40
- ],
74
+ group: ($, d) => {
75
+ const groups = [];
76
+ let curr = [];
77
+ let currLen = 0;
78
+ const queue = $.children.slice().reverse();
79
+ while (queue.length) {
80
+ const child = queue.pop();
81
+ const polyline = asPolyline(child);
82
+ const sampler = new Sampler(polyline.points);
83
+ const len = sampler.totalLength();
84
+ if (currLen + len <= d) {
85
+ curr.push(polyline);
86
+ currLen += len;
87
+ }
88
+ else {
89
+ const remainingLen = d - currLen;
90
+ const [fill, next] = sampler.splitAt(remainingLen / len);
91
+ curr.push(new Polyline(fill, __attribs(child)));
92
+ groups.push(new Group({}, curr));
93
+ curr = [];
94
+ currLen = 0;
95
+ queue.push(new Polyline(next, __attribs(child)));
96
+ }
97
+ }
98
+ if (curr.length)
99
+ groups.push(new Group({}, curr));
100
+ return new Group(__attribs($), groups);
101
+ },
41
102
  polyline: ($, d) => {
42
103
  const chunks = [];
43
104
  let pts = $.points;
@@ -56,6 +117,6 @@ export const splitArcLength = defmulti(__dispatch, {}, {
56
117
  break;
57
118
  }
58
119
  }
59
- return __pointArraysAsShapes(Polyline, chunks, __attribs($));
120
+ return new Group(__attribs($), __pointArraysAsShapes(Polyline, chunks));
60
121
  },
61
122
  });
package/vertices.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { MultiFn1O } from "@thi.ng/defmulti";
2
2
  import type { IShape } from "@thi.ng/geom-api";
3
- import { SamplingOpts } from "@thi.ng/geom-api/sample";
3
+ import { type SamplingOpts } from "@thi.ng/geom-api/sample";
4
4
  import type { Vec } from "@thi.ng/vectors";
5
5
  /**
6
6
  * Extracts/samples vertices from given shape's boundary and returns them as