@thi.ng/geom 3.4.22 → 4.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**: 2022-11-23T22:46:54Z
3
+ - **Last updated**: 2022-12-10T14:04: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,30 @@ 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
+ # [4.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@4.0.0) (2022-12-10)
13
+
14
+ #### 🛑 Breaking changes
15
+
16
+ - unify function naming ([980f625](https://github.com/thi-ng/umbrella/commit/980f625))
17
+ - BREAKING CHANGE: rename rect & aabb ctor fns
18
+ - rename rectFromCentroid => rectWithCentroid
19
+ - rename rectFromCentroidWithMargin => rectWithCentroidAndMargin
20
+ - same for aabb versions
21
+
22
+ #### 🚀 Features
23
+
24
+ - add AABB.toHiccup() impl ([2c419cc](https://github.com/thi-ng/umbrella/commit/2c419cc))
25
+ - add startWithCentroid(), add docs ([6b4df6a](https://github.com/thi-ng/umbrella/commit/6b4df6a))
26
+ - update vertices(), config via attribs ([b5a53ba](https://github.com/thi-ng/umbrella/commit/b5a53ba))
27
+ - add support for per-shape config overrides via `__samples` attrib object
28
+ - add docs
29
+
30
+ #### 🩹 Bug fixes
31
+
32
+ - correct withAttribs() return type ([867c302](https://github.com/thi-ng/umbrella/commit/867c302))
33
+ - update applyTransforms() ([b6262c2](https://github.com/thi-ng/umbrella/commit/b6262c2))
34
+ - always remove all spatial transform attribs
35
+
12
36
  ### [3.4.6](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@3.4.6) (2022-08-06)
13
37
 
14
38
  #### ⏱ Performance improvements
package/README.md CHANGED
@@ -12,6 +12,10 @@ This project is part of the
12
12
  For the Clojure version, please visit: [thi.ng/geom-clj](https://thi.ng/geom-clj)
13
13
 
14
14
  - [About](#about)
15
+ - [Shape types](#shape-types)
16
+ - [Hiccup support](#hiccup-support)
17
+ - [SVG support](#svg-support)
18
+ - [Polymorphic operations](#polymorphic-operations)
15
19
  - [Support packages](#support-packages)
16
20
  - [Status](#status)
17
21
  - [Installation](#installation)
@@ -29,54 +33,107 @@ This project is a partially ported from the [Clojure version of the same
29
33
  name](http://thi.ng/geom-clj). All polymorphic operations built on
30
34
  [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti).
31
35
 
32
- <!--
33
- [**Up-to-date feature matrix spreadsheet**](https://docs.google.com/spreadsheets/d/1GxJm-zOQaGECui2MJUmy3gQPTF-T6BJ6vhNlUnPsmDs/edit?usp=sharing)
34
- -->
36
+ ### Shape types
37
+
38
+ The following shape primitives are provided. For many there're multiple ways to
39
+ create them, please check linked sources and/or docs.
40
+
41
+ | Shape/Form | Description | Hiccup support |
42
+ |-------------------------------------------------------------------------------------------------------|------------------------------|-----------------|
43
+ | [AABB](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/aabb.ts) | 3D Axis-aligned bounding box | ✅<sup>(2)</sup> |
44
+ | [Arc](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/arc.ts) | 2D elliptic arc | ✅ |
45
+ | [Circle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/circle.ts) | 2D circle | ✅ |
46
+ | [Cubic](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/cubic.ts) | nD cubic bezier | ✅<sup>(1)</sup> |
47
+ | [Ellipse](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/ellipse.ts) | 2D ellipse | ✅ |
48
+ | [Group](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/group.ts) | group of 2D shapes | ✅ |
49
+ | [Line](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/line.ts) | 2D line segment | ✅ |
50
+ | [Path](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/path-builder.ts) | 2D path | ✅ |
51
+ | [Path (from SVG)](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/path-from-svg.ts) | 2D path from SVG `<path>` | ✅ |
52
+ | [Plane](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/plane.ts) | 3D plane | ✅<sup>(2)</sup> |
53
+ | [Point cloud](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/points.ts) | nD point cloud | ✅<sup>(1)</sup> |
54
+ | [Polygon](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/polygon.ts) | 2D simple polygon (no holes) | ✅ |
55
+ | [Polyline](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/polyline.ts) | 2D polyline | ✅ |
56
+ | [Quad](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/quad.ts) | 2D/3D quad (4-gon) | ✅<sup>(1)</sup> |
57
+ | [Quadratic](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/quadratic.ts) | nD quadratic bezier | ✅<sup>(1)</sup> |
58
+ | [Ray](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/ray.ts) | nD ray | ✅<sup>(1)</sup> |
59
+ | [Rectangle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/ray.ts) | 2D rectangle | ✅ |
60
+ | [Sphere](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/sphere.ts) | 3D sphere | ✅<sup>(2)</sup> |
61
+ | [Text](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/text.ts) | Basic stub for text labels | ✅<sup>(3)</sup> |
62
+ | [Triangle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/triangle.ts) | 2D triangle | ✅ |
63
+
64
+ - <sup>(1)</sup> valid hiccup format, currently only useable/supported if 2D geometry
65
+ - <sup>(2)</sup> valid hiccup format, currently unused/unsupported elsewhere
66
+ - <sup>(3)</sup> merely treated as a point in space (e.g. used for placing text labels), no geometry of text itself
67
+
68
+ ### Hiccup support
69
+
70
+ With very few exceptions these all are implementing the [`IToHiccup`
71
+ interface](https://docs.thi.ng/umbrella/api/interfaces/IToHiccup.html) and so
72
+ can be easily converted (via
73
+ [hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)) to a
74
+ variety of other formats. By design, for better flexibility and performance
75
+ reasons, the hiccup flavor used by this package is **not** compatible with that
76
+ used by
77
+ [thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-svg),
78
+ though the latter provides a
79
+ [`convertTree()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/convertTree.html)
80
+ function for that purpose. This is only needed for some cases of dynamic
81
+ in-browser SVG DOM creation...
82
+
83
+ ### SVG support
84
+
85
+ SVG conversion is included via the
86
+ [`asSvg()`](https://docs.thi.ng/umbrella/geom/functions/asSvg.html) and
87
+ [`svgDoc()`](https://docs.thi.ng/umbrella/geom/functions/svgDoc.html) functions.
88
+
89
+ ### Polymorphic operations
35
90
 
36
91
  The following operations are provided (many also applicable to shape groups
37
- directly and/or perform automatic resampling/conversion if needed):
38
-
39
- | Operation | Description |
40
- |-------------------------------------------------------------------------------------------|--------------------------------------------------------------|
41
- | [`arcLength()`](https://docs.thi.ng/umbrella/geom/modules.html#arcLength) | compute arc length / perimeter of shape boundary |
42
- | [`area()`](https://docs.thi.ng/umbrella/geom/modules.html#area) | signed/unsigned surface area |
43
- | [`asCubic()`](https://docs.thi.ng/umbrella/geom/modules.html#asCubic) | convert shape boundary to cubic bezier segments |
44
- | [`asPath()`](https://docs.thi.ng/umbrella/geom/modules.html#asPath) | convert shape to path |
45
- | [`asPolygon()`](https://docs.thi.ng/umbrella/geom/modules.html#asPolygon) | convert shape to polygon |
46
- | [`asPolyline()`](https://docs.thi.ng/umbrella/geom/modules.html#asPolyline) | convert shape to polyline |
47
- | [`asSvg()`](https://docs.thi.ng/umbrella/geom/modules.html#asSvg) | serialize shape/group/hierarchy to SVG |
48
- | [`bounds()`](https://docs.thi.ng/umbrella/geom/modules.html#bounds) | compute bounding box |
49
- | [`center()`](https://docs.thi.ng/umbrella/geom/modules.html#center) | center shape around origin or point |
50
- | [`centroid()`](https://docs.thi.ng/umbrella/geom/modules.html#centroid) | compute shape centroid |
51
- | [`classifyPoint()`](https://docs.thi.ng/umbrella/geom/modules.html#classifyPoint) | classify point in relation to shape boundary (in/out) |
52
- | [`clipConvex()`](https://docs.thi.ng/umbrella/geom/modules.html#clipConvex) | clip shape against convex boundary |
53
- | [`closestPoint()`](https://docs.thi.ng/umbrella/geom/modules.html#closestPoint) | compute closest point on shape boundary |
54
- | [`convexHull()`](https://docs.thi.ng/umbrella/geom/modules.html#convexHull) | compute convex hull (2d only) |
55
- | [`edges()`](https://docs.thi.ng/umbrella/geom/modules.html#edges) | extract edges |
56
- | [`fitIntoBounds()`](https://docs.thi.ng/umbrella/geom/modules.html#fitIntoBounds) | rescale/reposition shapes into a destination boundary |
57
- | [`flip()`](https://docs.thi.ng/umbrella/geom/modules.html#flip) | reverse order (vertices or direction) |
58
- | [`intersects()`](https://docs.thi.ng/umbrella/geom/modules.html#intersects) | pairwise shape intersection (various types) |
59
- | [`mapPoint()`](https://docs.thi.ng/umbrella/geom/modules.html#mapPoint) | transform world space point into local shape space |
60
- | [`offset()`](https://docs.thi.ng/umbrella/geom/modules.html#offset) | shape/path offsetting |
61
- | [`pointAt()`](https://docs.thi.ng/umbrella/geom/modules.html#pointAt) | compute point on shape boundary at parametric position |
62
- | [`pointInside()`](https://docs.thi.ng/umbrella/geom/modules.html#pointInside) | check if point is inside shape |
63
- | [`resample()`](https://docs.thi.ng/umbrella/geom/modules.html#resample) | resample/convert shape |
64
- | [`rotate()`](https://docs.thi.ng/umbrella/geom/modules.html#rotate) | rotate shape |
65
- | [`scale()`](https://docs.thi.ng/umbrella/geom/modules.html#scale) | scale shape (uniformly/non-uniformly) |
66
- | [`scatter()`](https://docs.thi.ng/umbrella/geom/modules.html#scatter) | create random points inside a shape boundary |
67
- | [`simplify()`](https://docs.thi.ng/umbrella/geom/modules.html#simplify) | simplify shape/boundary (Douglas-Peucker) |
68
- | [`splitAt()`](https://docs.thi.ng/umbrella/geom/modules.html#splitAt) | split shape/boundary at parametric position |
69
- | [`splitNear()`](https://docs.thi.ng/umbrella/geom/modules.html#splitNear) | split shape/boundary near world position |
70
- | [`subdivCurve()`](https://docs.thi.ng/umbrella/geom/modules.html#subdivCurve) | recursively apply curve subdivision kernel |
71
- | [`tangentAt()`](https://docs.thi.ng/umbrella/geom/modules.html#tangentAt) | compute tangent at parametric position |
72
- | [`tessellate()`](https://docs.thi.ng/umbrella/geom/modules.html#tessellate) | (recursively) tessellate shape |
73
- | [`transformVertices()`](https://docs.thi.ng/umbrella/geom/modules.html#transformVertices) | apply custom function to each vertex |
74
- | [`transform()`](https://docs.thi.ng/umbrella/geom/modules.html#transform) | apply transformation matrix |
75
- | [`translate()`](https://docs.thi.ng/umbrella/geom/modules.html#translate) | translate shape |
76
- | [`union()`](https://docs.thi.ng/umbrella/geom/modules.html#union) | compute shape union |
77
- | [`vertices()`](https://docs.thi.ng/umbrella/geom/modules.html#vertices) | extract/sample vertices from shape boundary |
78
- | [`volume()`](https://docs.thi.ng/umbrella/geom/modules.html#volume) | compute shape volume (3D only) |
79
- | [`warpPoints()`](https://docs.thi.ng/umbrella/geom/modules.html#warpPoints) | transfer points between the local spaces defined by 2 shapes |
92
+ directly and/or perform automatic resampling/conversion if needed).
93
+
94
+ | Operation | Description |
95
+ |---------------------------------------------------------------------------------------------|--------------------------------------------------------------|
96
+ | [`applyTransforms()`](https://docs.thi.ng/umbrella/geom/functions/applyTransforms.html) | applies any spatial transformation attributes |
97
+ | [`arcLength()`](https://docs.thi.ng/umbrella/geom/functions/arcLength.html) | compute arc length / perimeter of shape boundary |
98
+ | [`area()`](https://docs.thi.ng/umbrella/geom/functions/area.html) | signed/unsigned surface area |
99
+ | [`asCubic()`](https://docs.thi.ng/umbrella/geom/functions/asCubic.html) | convert shape boundary to cubic bezier segments |
100
+ | [`asPath()`](https://docs.thi.ng/umbrella/geom/functions/asPath.html) | convert shape to path |
101
+ | [`asPolygon()`](https://docs.thi.ng/umbrella/geom/functions/asPolygon.html) | convert shape to polygon |
102
+ | [`asPolyline()`](https://docs.thi.ng/umbrella/geom/functions/asPolyline.html) | convert shape to polyline |
103
+ | [`asSvg()`](https://docs.thi.ng/umbrella/geom/functions/asSvg.html) | serialize shape/group/hierarchy to SVG |
104
+ | [`bounds()`](https://docs.thi.ng/umbrella/geom/functions/bounds.html) | compute bounding box |
105
+ | [`center()`](https://docs.thi.ng/umbrella/geom/functions/center.html) | center shape around origin or point |
106
+ | [`centroid()`](https://docs.thi.ng/umbrella/geom/functions/centroid.html) | compute shape centroid |
107
+ | [`classifyPoint()`](https://docs.thi.ng/umbrella/geom/functions/classifyPoint.html) | classify point in relation to shape boundary (in/out) |
108
+ | [`clipConvex()`](https://docs.thi.ng/umbrella/geom/functions/clipConvex.html) | clip shape against convex boundary |
109
+ | [`closestPoint()`](https://docs.thi.ng/umbrella/geom/functions/closestPoint.html) | compute closest point on shape boundary |
110
+ | [`convexHull()`](https://docs.thi.ng/umbrella/geom/functions/convexHull.html) | compute convex hull (2d only) |
111
+ | [`edges()`](https://docs.thi.ng/umbrella/geom/functions/edges.html) | extract edges |
112
+ | [`fitIntoBounds()`](https://docs.thi.ng/umbrella/geom/functions/fitIntoBounds.html) | rescale/reposition shapes into a destination boundary |
113
+ | [`flip()`](https://docs.thi.ng/umbrella/geom/functions/flip.html) | reverse order (vertices or direction) |
114
+ | [`intersects()`](https://docs.thi.ng/umbrella/geom/functions/intersects.html) | pairwise shape intersection (various types) |
115
+ | [`mapPoint()`](https://docs.thi.ng/umbrella/geom/functions/mapPoint.html) | transform world space point into local shape space |
116
+ | [`offset()`](https://docs.thi.ng/umbrella/geom/functions/offset.html) | shape/path offsetting |
117
+ | [`pointAt()`](https://docs.thi.ng/umbrella/geom/functions/pointAt.html) | compute point on shape boundary at parametric position |
118
+ | [`pointInside()`](https://docs.thi.ng/umbrella/geom/functions/pointInside.html) | check if point is inside shape |
119
+ | [`resample()`](https://docs.thi.ng/umbrella/geom/functions/resample.html) | resample/convert shape |
120
+ | [`rotate()`](https://docs.thi.ng/umbrella/geom/functions/rotate.html) | rotate shape |
121
+ | [`scale()`](https://docs.thi.ng/umbrella/geom/functions/scale.html) | scale shape (uniformly/non-uniformly) |
122
+ | [`scatter()`](https://docs.thi.ng/umbrella/geom/functions/scatter.html) | create random points inside a shape boundary |
123
+ | [`simplify()`](https://docs.thi.ng/umbrella/geom/functions/simplify.html) | simplify shape/boundary (Douglas-Peucker) |
124
+ | [`splitAt()`](https://docs.thi.ng/umbrella/geom/functions/splitAt.html) | split shape/boundary at parametric position |
125
+ | [`splitNear()`](https://docs.thi.ng/umbrella/geom/functions/splitNear.html) | split shape/boundary near world position |
126
+ | [`subdivCurve()`](https://docs.thi.ng/umbrella/geom/functions/subdivCurve.html) | recursively apply curve subdivision kernel |
127
+ | [`tangentAt()`](https://docs.thi.ng/umbrella/geom/functions/tangentAt.html) | compute tangent at parametric position |
128
+ | [`tessellate()`](https://docs.thi.ng/umbrella/geom/functions/tessellate.html) | (recursively) tessellate shape |
129
+ | [`transformVertices()`](https://docs.thi.ng/umbrella/geom/functions/transformVertices.html) | apply custom function to each vertex |
130
+ | [`transform()`](https://docs.thi.ng/umbrella/geom/functions/transform.html) | apply transformation matrix |
131
+ | [`translate()`](https://docs.thi.ng/umbrella/geom/functions/translate.html) | translate shape |
132
+ | [`union()`](https://docs.thi.ng/umbrella/geom/functions/union.html) | compute shape union |
133
+ | [`vertices()`](https://docs.thi.ng/umbrella/geom/functions/vertices.html) | extract/sample vertices from shape boundary |
134
+ | [`volume()`](https://docs.thi.ng/umbrella/geom/functions/volume.html) | compute shape volume (3D only) |
135
+ | [`warpPoints()`](https://docs.thi.ng/umbrella/geom/functions/warpPoints.html) | transfer points between the local spaces defined by 2 shapes |
136
+ | [`withAttribs()`](https://docs.thi.ng/umbrella/geom/functions/withAttribs.html) | shallow copy of given shape with new `attribs` assigned |
80
137
 
81
138
  This package acts as a higher-level frontend for most of the following related
82
139
  packages (which are more low-level, lightweight and usable by themselves too):
@@ -86,6 +143,7 @@ packages (which are more low-level, lightweight and usable by themselves too):
86
143
  - [@thi.ng/geom-accel](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-accel) - n-D spatial indexing data structures with a shared ES6 Map/Set-like API
87
144
  - [@thi.ng/geom-api](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-api) - Shared type & interface declarations for [@thi.ng/geom](https://github.com/thi-ng/umbrella/tree/develop/packages/geom) packages
88
145
  - [@thi.ng/geom-arc](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-arc) - 2D circular / elliptic arc operations
146
+ - [@thi.ng/geom-axidraw](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-axidraw) - Conversion and preparation of thi.ng/geom shapes & shape groups to AxiDraw pen plotter draw commands
89
147
  - [@thi.ng/geom-clip-line](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-clip-line) - 2D line clipping (Liang-Barsky)
90
148
  - [@thi.ng/geom-clip-poly](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-clip-poly) - 2D polygon clipping / offsetting (Sutherland-Hodgeman, Grainer-Hormann)
91
149
  - [@thi.ng/geom-closest-point](https://github.com/thi-ng/umbrella/tree/develop/packages/geom-closest-point) - 2D / 3D closest point / proximity helpers
@@ -131,7 +189,7 @@ node --experimental-repl-await
131
189
  > const geom = await import("@thi.ng/geom");
132
190
  ```
133
191
 
134
- Package sizes (gzipped, pre-treeshake): ESM: 13.50 KB
192
+ Package sizes (brotli'd, pre-treeshake): ESM: 11.98 KB
135
193
 
136
194
  ## Dependencies
137
195
 
package/aabb.d.ts CHANGED
@@ -8,7 +8,7 @@ export declare function aabb(attribs?: Attribs): AABB;
8
8
  export declare const aabbFromMinMax: (min: Vec, max: Vec, attribs?: Attribs) => AABB;
9
9
  export declare const aabbFromMinMaxWithMargin: (min: Vec, max: Vec, margin: number, attribs?: Attribs) => AABB;
10
10
  export declare const aabbFromCentroid: (centroid: Vec, size: Vec, attribs?: Attribs) => AABB;
11
- export declare const aabbFromCentroidWithMargin: (centroid: Vec, size: Vec, margin: number, attribs?: Attribs) => AABB;
11
+ export declare const aabbWithCentroidAndMargin: (centroid: Vec, size: Vec, margin: number, attribs?: Attribs) => AABB;
12
12
  /**
13
13
  * Returns the intersection AABB of given inputs or `undefined` if they
14
14
  * are non-overlapping.
package/aabb.js CHANGED
@@ -14,7 +14,7 @@ export function aabb(...args) {
14
14
  export const aabbFromMinMax = (min, max, attribs) => new AABB(min, sub3([], max, min), attribs);
15
15
  export const aabbFromMinMaxWithMargin = (min, max, margin, attribs) => aabbFromMinMax(min, max, attribs).offset(margin);
16
16
  export const aabbFromCentroid = (centroid, size, attribs) => new AABB(maddN3([], size, -0.5, centroid), size, attribs);
17
- export const aabbFromCentroidWithMargin = (centroid, size, margin, attribs) => aabbFromCentroid(centroid, size, attribs).offset(margin);
17
+ export const aabbWithCentroidAndMargin = (centroid, size, margin, attribs) => aabbFromCentroid(centroid, size, attribs).offset(margin);
18
18
  /**
19
19
  * Returns the intersection AABB of given inputs or `undefined` if they
20
20
  * are non-overlapping.
package/api/aabb.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import type { IToHiccup } from "@thi.ng/api";
1
2
  import type { AABBLike, Attribs } from "@thi.ng/geom-api";
2
3
  import { Vec } from "@thi.ng/vectors/api";
3
- export declare class AABB implements AABBLike {
4
+ export declare class AABB implements AABBLike, IToHiccup {
4
5
  pos: Vec;
5
6
  attribs?: Attribs | undefined;
6
7
  size: Vec;
@@ -10,5 +11,6 @@ export declare class AABB implements AABBLike {
10
11
  withAttribs(attribs: Attribs): AABB;
11
12
  max(): Vec;
12
13
  offset(offset: number): this;
14
+ toHiccup(): (string | Attribs | undefined)[];
13
15
  }
14
16
  //# sourceMappingURL=aabb.d.ts.map
package/api/aabb.js CHANGED
@@ -29,4 +29,7 @@ export class AABB {
29
29
  max3(null, addN3(null, this.size, offset * 2), ZERO3);
30
30
  return this;
31
31
  }
32
+ toHiccup() {
33
+ return ["aabb", this.attribs, this.pos, this.size];
34
+ }
32
35
  }
@@ -5,6 +5,7 @@ import { rotate } from "./rotate.js";
5
5
  import { scale } from "./scale.js";
6
6
  import { transform } from "./transform.js";
7
7
  import { translate } from "./translate.js";
8
+ const TX_ATTRIBS = ["transform", "translate", "rotate", "scale"];
8
9
  /** @internal */
9
10
  const __apply = ($) => {
10
11
  let attribs = $.attribs;
@@ -12,10 +13,10 @@ const __apply = ($) => {
12
13
  return $;
13
14
  const { transform: tx, translate: t, rotate: r, scale: s } = attribs;
14
15
  if (tx)
15
- return transform($.withAttribs(withoutKeysObj(attribs, ["transform"])), tx);
16
+ return transform($.withAttribs(withoutKeysObj(attribs, TX_ATTRIBS)), tx);
16
17
  if (!(t || r || s))
17
18
  return $;
18
- $ = $.withAttribs(withoutKeysObj(attribs, ["translate", "rotate", "scale"]));
19
+ $ = $.withAttribs(withoutKeysObj(attribs, TX_ATTRIBS));
19
20
  if (r)
20
21
  $ = rotate($, r);
21
22
  if (s)
package/offset.js CHANGED
@@ -3,13 +3,13 @@ import { add2 } from "@thi.ng/vectors/add";
3
3
  import { normalCW } from "@thi.ng/vectors/normal";
4
4
  import { set2 } from "@thi.ng/vectors/set";
5
5
  import { sub2 } from "@thi.ng/vectors/sub";
6
- import { aabbFromCentroidWithMargin } from "./aabb.js";
6
+ import { aabbWithCentroidAndMargin } from "./aabb.js";
7
7
  import { Circle } from "./api/circle.js";
8
8
  import { Quad } from "./api/quad.js";
9
9
  import { centroid } from "./centroid.js";
10
10
  import { __copyAttribs } from "./internal/copy.js";
11
11
  import { __dispatch } from "./internal/dispatch.js";
12
- import { rectFromCentroidWithMargin } from "./rect.js";
12
+ import { rectWithCentroidAndMargin } from "./rect.js";
13
13
  /**
14
14
  * Computes an offset shape (as in "path offsetting") of given shape and offset
15
15
  * distance `dist`.
@@ -28,7 +28,7 @@ import { rectFromCentroidWithMargin } from "./rect.js";
28
28
  * @param dist
29
29
  */
30
30
  export const offset = defmulti(__dispatch, {}, {
31
- aabb: ($, n) => aabbFromCentroidWithMargin(centroid($), $.size, n, __copyAttribs($)),
31
+ aabb: ($, n) => aabbWithCentroidAndMargin(centroid($), $.size, n, __copyAttribs($)),
32
32
  circle: ($, n) => new Circle(set2([], $.pos), Math.max($.r + n, 0)),
33
33
  line: ({ points: [a, b], attribs }, n) => {
34
34
  const norm = normalCW([], a, b, n);
@@ -39,5 +39,5 @@ export const offset = defmulti(__dispatch, {}, {
39
39
  sub2([], a, norm),
40
40
  ], { ...attribs });
41
41
  },
42
- rect: ($, n) => rectFromCentroidWithMargin(centroid($), $.size, n, __copyAttribs($)),
42
+ rect: ($, n) => rectWithCentroidAndMargin(centroid($), $.size, n, __copyAttribs($)),
43
43
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom",
3
- "version": "3.4.22",
3
+ "version": "4.0.0",
4
4
  "description": "Functional, polymorphic API for 2D geometry types & SVG generation",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -35,37 +35,37 @@
35
35
  "tool:bpatch": "tools:node-esm tools/bpatch.ts"
36
36
  },
37
37
  "dependencies": {
38
- "@thi.ng/api": "^8.5.0",
39
- "@thi.ng/arrays": "^2.4.3",
40
- "@thi.ng/associative": "^6.2.17",
41
- "@thi.ng/checks": "^3.3.3",
42
- "@thi.ng/defmulti": "^2.1.22",
43
- "@thi.ng/equiv": "^2.1.13",
44
- "@thi.ng/errors": "^2.2.4",
45
- "@thi.ng/geom-api": "^3.3.19",
46
- "@thi.ng/geom-arc": "^2.1.36",
47
- "@thi.ng/geom-clip-line": "^2.1.36",
48
- "@thi.ng/geom-clip-poly": "^2.1.36",
49
- "@thi.ng/geom-closest-point": "^2.1.33",
50
- "@thi.ng/geom-hull": "^2.1.33",
51
- "@thi.ng/geom-isec": "^2.1.36",
52
- "@thi.ng/geom-poly-utils": "^2.3.20",
53
- "@thi.ng/geom-resample": "^2.1.36",
54
- "@thi.ng/geom-splines": "^2.2.10",
55
- "@thi.ng/geom-subdiv-curve": "^2.1.36",
56
- "@thi.ng/geom-tessellate": "^2.1.36",
57
- "@thi.ng/hiccup": "^4.2.24",
58
- "@thi.ng/hiccup-svg": "^4.3.22",
59
- "@thi.ng/math": "^5.3.14",
60
- "@thi.ng/matrices": "^2.1.34",
61
- "@thi.ng/random": "^3.3.16",
62
- "@thi.ng/strings": "^3.3.18",
63
- "@thi.ng/transducers": "^8.3.24",
64
- "@thi.ng/vectors": "^7.5.25"
38
+ "@thi.ng/api": "^8.5.1",
39
+ "@thi.ng/arrays": "^2.4.4",
40
+ "@thi.ng/associative": "^6.2.18",
41
+ "@thi.ng/checks": "^3.3.4",
42
+ "@thi.ng/defmulti": "^2.1.23",
43
+ "@thi.ng/equiv": "^2.1.14",
44
+ "@thi.ng/errors": "^2.2.5",
45
+ "@thi.ng/geom-api": "^3.3.20",
46
+ "@thi.ng/geom-arc": "^2.1.38",
47
+ "@thi.ng/geom-clip-line": "^2.2.0",
48
+ "@thi.ng/geom-clip-poly": "^2.1.37",
49
+ "@thi.ng/geom-closest-point": "^2.1.34",
50
+ "@thi.ng/geom-hull": "^2.1.34",
51
+ "@thi.ng/geom-isec": "^2.1.37",
52
+ "@thi.ng/geom-poly-utils": "^2.3.21",
53
+ "@thi.ng/geom-resample": "^2.1.38",
54
+ "@thi.ng/geom-splines": "^2.2.12",
55
+ "@thi.ng/geom-subdiv-curve": "^2.1.37",
56
+ "@thi.ng/geom-tessellate": "^2.1.37",
57
+ "@thi.ng/hiccup": "^4.2.25",
58
+ "@thi.ng/hiccup-svg": "^4.3.23",
59
+ "@thi.ng/math": "^5.3.15",
60
+ "@thi.ng/matrices": "^2.1.35",
61
+ "@thi.ng/random": "^3.3.17",
62
+ "@thi.ng/strings": "^3.3.19",
63
+ "@thi.ng/transducers": "^8.3.25",
64
+ "@thi.ng/vectors": "^7.5.26"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@microsoft/api-extractor": "^7.33.5",
68
- "@thi.ng/testament": "^0.3.5",
68
+ "@thi.ng/testament": "^0.3.6",
69
69
  "rimraf": "^3.0.2",
70
70
  "tools": "^0.0.1",
71
71
  "typedoc": "^0.23.20",
@@ -250,6 +250,9 @@
250
250
  "./group": {
251
251
  "default": "./group.js"
252
252
  },
253
+ "./internal/bounds": {
254
+ "default": "./internal/bounds.js"
255
+ },
253
256
  "./internal/copy": {
254
257
  "default": "./internal/copy.js"
255
258
  },
@@ -380,5 +383,5 @@
380
383
  "thi.ng": {
381
384
  "year": 2013
382
385
  },
383
- "gitHead": "75ec32ff7f1b7b5e72e7a04ace24732cd5d6c774\n"
386
+ "gitHead": "5178ea1d7f4b2de86cf5101bdd73f6567518c0bd\n"
384
387
  }
package/polygon.d.ts CHANGED
@@ -2,5 +2,50 @@ import type { Attribs } from "@thi.ng/geom-api";
2
2
  import type { Vec } from "@thi.ng/vectors";
3
3
  import { Polygon } from "./api/polygon.js";
4
4
  export declare const polygon: (pts?: Vec[], attribs?: Attribs) => Polygon;
5
+ /**
6
+ * Syntax sugar for {@link starWithCentroid}, using [0,0] as center.
7
+ *
8
+ * @param r
9
+ * @param n
10
+ * @param profile
11
+ * @param attribs
12
+ * @returns
13
+ */
5
14
  export declare const star: (r: number, n: number, profile: number[], attribs?: Attribs) => Polygon;
15
+ /**
16
+ * Creates a new "star"-shaped polygon around `pos` with radius `r` and `n`
17
+ * repetitions of `profile`. The latter is an array of radius scale values to
18
+ * define the overall shape. The resulting polygon will have `n *
19
+ * profile.length` vertices. To create an actual star-like shape, the profile
20
+ * needs to contain at least 2 values, e.g. `[1, 0.5]`, meaning every other
21
+ * vertex will be inset to 50% of the base radius.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * starWithCentroid([100,200], 50, 5, [1, 0.5])
26
+ * // Polygon {
27
+ * // points: [
28
+ * // [150.000, 200.000],
29
+ * // [120.225, 214.695],
30
+ * // [115.451, 247.553],
31
+ * // [92.275, 223.776],
32
+ * // [59.549, 229.389],
33
+ * // [75.000, 200.000],
34
+ * // [59.549, 170.611],
35
+ * // [92.275, 176.224],
36
+ * // [115.451, 152.447],
37
+ * // [120.225, 185.305]
38
+ * // ],
39
+ * // attribs: undefined
40
+ * // }
41
+ * ```
42
+ *
43
+ * @param pos
44
+ * @param r
45
+ * @param n
46
+ * @param profile
47
+ * @param attribs
48
+ * @returns
49
+ */
50
+ export declare const starWithCentroid: (pos: Vec, r: number, n: number, profile: number[], attribs?: Attribs) => Polygon;
6
51
  //# sourceMappingURL=polygon.d.ts.map
package/polygon.js CHANGED
@@ -8,4 +8,49 @@ import { zip } from "@thi.ng/transducers/zip";
8
8
  import { cartesian2 } from "@thi.ng/vectors/cartesian";
9
9
  import { Polygon } from "./api/polygon.js";
10
10
  export const polygon = (pts, attribs) => new Polygon(pts, attribs);
11
- export const star = (r, n, profile, attribs) => new Polygon(transduce(map(([i, p]) => cartesian2(null, [r * p, i * TAU])), push(), zip(normRange(n * profile.length, false), cycle(profile))), attribs);
11
+ /**
12
+ * Syntax sugar for {@link starWithCentroid}, using [0,0] as center.
13
+ *
14
+ * @param r
15
+ * @param n
16
+ * @param profile
17
+ * @param attribs
18
+ * @returns
19
+ */
20
+ export const star = (r, n, profile, attribs) => starWithCentroid([0, 0], r, n, profile, attribs);
21
+ /**
22
+ * Creates a new "star"-shaped polygon around `pos` with radius `r` and `n`
23
+ * repetitions of `profile`. The latter is an array of radius scale values to
24
+ * define the overall shape. The resulting polygon will have `n *
25
+ * profile.length` vertices. To create an actual star-like shape, the profile
26
+ * needs to contain at least 2 values, e.g. `[1, 0.5]`, meaning every other
27
+ * vertex will be inset to 50% of the base radius.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * starWithCentroid([100,200], 50, 5, [1, 0.5])
32
+ * // Polygon {
33
+ * // points: [
34
+ * // [150.000, 200.000],
35
+ * // [120.225, 214.695],
36
+ * // [115.451, 247.553],
37
+ * // [92.275, 223.776],
38
+ * // [59.549, 229.389],
39
+ * // [75.000, 200.000],
40
+ * // [59.549, 170.611],
41
+ * // [92.275, 176.224],
42
+ * // [115.451, 152.447],
43
+ * // [120.225, 185.305]
44
+ * // ],
45
+ * // attribs: undefined
46
+ * // }
47
+ * ```
48
+ *
49
+ * @param pos
50
+ * @param r
51
+ * @param n
52
+ * @param profile
53
+ * @param attribs
54
+ * @returns
55
+ */
56
+ export const starWithCentroid = (pos, r, n, profile, attribs) => new Polygon(transduce(map(([i, p]) => cartesian2(null, [r * p, i * TAU], pos)), push(), zip(normRange(n * profile.length, false), cycle(profile))), attribs);
package/rect.d.ts CHANGED
@@ -8,8 +8,8 @@ export declare function rect(size: number | Vec, attribs?: Attribs): Rect;
8
8
  export declare function rect(attribs?: Attribs): Rect;
9
9
  export declare const rectFromMinMax: (min: Vec, max: Vec, attribs?: Attribs) => Rect;
10
10
  export declare const rectFromMinMaxWithMargin: (min: Vec, max: Vec, margin: number, attribs?: Attribs) => Rect;
11
- export declare const rectFromCentroid: (centroid: Vec, size: number | Vec, attribs?: Attribs) => Rect;
12
- export declare const rectFromCentroidWithMargin: (centroid: Vec, size: number | Vec, margin: number, attribs?: Attribs) => Rect;
11
+ export declare const rectWithCentroid: (centroid: Vec, size: number | Vec, attribs?: Attribs) => Rect;
12
+ export declare const rectWithCentroidAndMargin: (centroid: Vec, size: number | Vec, margin: number, attribs?: Attribs) => Rect;
13
13
  /**
14
14
  * Returns the intersection rect of given inputs or `undefined` if they
15
15
  * are non-overlapping.
package/rect.js CHANGED
@@ -15,11 +15,11 @@ export function rect(...args) {
15
15
  }
16
16
  export const rectFromMinMax = (min, max, attribs) => new Rect(min, sub2([], max, min), attribs);
17
17
  export const rectFromMinMaxWithMargin = (min, max, margin, attribs) => rectFromMinMax(min, max, attribs).offset(margin);
18
- export const rectFromCentroid = (centroid, size, attribs) => {
18
+ export const rectWithCentroid = (centroid, size, attribs) => {
19
19
  size = __asVec(size);
20
20
  return new Rect(maddN2([], size, -0.5, centroid), size, attribs);
21
21
  };
22
- export const rectFromCentroidWithMargin = (centroid, size, margin, attribs) => rectFromCentroid(centroid, size, attribs).offset(margin);
22
+ export const rectWithCentroidAndMargin = (centroid, size, margin, attribs) => rectWithCentroid(centroid, size, attribs).offset(margin);
23
23
  /**
24
24
  * Returns the intersection rect of given inputs or `undefined` if they
25
25
  * are non-overlapping.
package/vertices.d.ts CHANGED
@@ -7,6 +7,25 @@ import type { Vec } from "@thi.ng/vectors";
7
7
  * array. Some shapes also support {@link @thi.ng/geom-api#SamplingOpts}.
8
8
  *
9
9
  * @remarks
10
+ * The given sampling options (if any) can also be overridden per shape using
11
+ * the special `__samples` attribute. If specified, these will be merged with
12
+ * the options.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // using default
17
+ * vertices(circle(100))
18
+ *
19
+ * // specify resolution only
20
+ * vertices(circle(100), 6)
21
+ *
22
+ * // specify more advanced options
23
+ * vertices(circle(100), { dist: 10 })
24
+ *
25
+ * // using shape attribs
26
+ * vertices(circle(100, { __samples: { dist: 10 } }))
27
+ * ```
28
+ *
10
29
  * Currently implemented for:
11
30
  *
12
31
  * - {@link AABB}
package/vertices.js CHANGED
@@ -19,6 +19,25 @@ import { __dispatch } from "./internal/dispatch.js";
19
19
  * array. Some shapes also support {@link @thi.ng/geom-api#SamplingOpts}.
20
20
  *
21
21
  * @remarks
22
+ * The given sampling options (if any) can also be overridden per shape using
23
+ * the special `__samples` attribute. If specified, these will be merged with
24
+ * the options.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // using default
29
+ * vertices(circle(100))
30
+ *
31
+ * // specify resolution only
32
+ * vertices(circle(100), 6)
33
+ *
34
+ * // specify more advanced options
35
+ * vertices(circle(100), { dist: 10 })
36
+ *
37
+ * // using shape attribs
38
+ * vertices(circle(100, { __samples: { dist: 10 } }))
39
+ * ```
40
+ *
22
41
  * Currently implemented for:
23
42
  *
24
43
  * - {@link AABB}
@@ -69,8 +88,9 @@ export const vertices = defmulti(__dispatch, {
69
88
  [qx, qy, pz], // h
70
89
  ];
71
90
  },
72
- arc: ($, opts) => _arcVertices($.pos, $.r, $.axis, $.start, $.end, opts),
91
+ arc: ($, opts) => _arcVertices($.pos, $.r, $.axis, $.start, $.end, __sampleAttribs(opts, $.attribs)),
73
92
  circle: ($, opts = DEFAULT_SAMPLES) => {
93
+ opts = __sampleAttribs(opts, $.attribs);
74
94
  const pos = $.pos;
75
95
  const r = $.r;
76
96
  let [num, last] = __circleOpts(opts, r);
@@ -82,8 +102,9 @@ export const vertices = defmulti(__dispatch, {
82
102
  }
83
103
  return buf;
84
104
  },
85
- cubic: ($, opts) => sampleCubic($.points, opts),
105
+ cubic: ($, opts) => sampleCubic($.points, __sampleAttribs(opts, $.attribs)),
86
106
  ellipse: ($, opts = DEFAULT_SAMPLES) => {
107
+ opts = __sampleAttribs(opts, $.attribs);
87
108
  const buf = [];
88
109
  const pos = $.pos;
89
110
  const r = $.r;
@@ -97,6 +118,7 @@ export const vertices = defmulti(__dispatch, {
97
118
  },
98
119
  group: ({ children }) => children.reduce((acc, $) => acc.concat(vertices($)), []),
99
120
  path: ($, opts) => {
121
+ opts = __sampleAttribs(opts, $.attribs);
100
122
  const _opts = isNumber(opts) ? { num: opts } : opts;
101
123
  let verts = [];
102
124
  for (let segs = $.segments, n = segs.length - 1, i = 0; i <= n; i++) {
@@ -111,10 +133,11 @@ export const vertices = defmulti(__dispatch, {
111
133
  return verts;
112
134
  },
113
135
  points: ($) => $.points,
114
- poly: ($, opts) => resample($.points, opts, true),
115
- polyline: ($, opts) => resample($.points, opts),
116
- quadratic: ($, opts) => sampleQuadratic($.points, opts),
136
+ poly: ($, opts) => resample($.points, __sampleAttribs(opts, $.attribs), true),
137
+ polyline: ($, opts) => resample($.points, __sampleAttribs(opts, $.attribs)),
138
+ quadratic: ($, opts) => sampleQuadratic($.points, __sampleAttribs(opts, $.attribs)),
117
139
  rect: ($, opts) => {
140
+ opts = __sampleAttribs(opts, $.attribs);
118
141
  const p = $.pos;
119
142
  const q = add2([], p, $.size);
120
143
  const verts = [set2([], p), [q[0], p[1]], q, [p[0], q[1]]];
@@ -140,3 +163,16 @@ const __circleOpts = (opts, r) => isNumber(opts)
140
163
  : opts.num || DEFAULT_SAMPLES,
141
164
  opts.last === true,
142
165
  ];
166
+ const __sampleAttribs = (opts, attribs) => {
167
+ if (attribs) {
168
+ const val = attribs.__samples;
169
+ return isNumber(opts)
170
+ ? isNumber(val)
171
+ ? val
172
+ : { num: opts, ...val }
173
+ : isNumber(val)
174
+ ? { ...opts, num: val }
175
+ : { ...opts, ...val };
176
+ }
177
+ return opts;
178
+ };
package/with-attribs.d.ts CHANGED
@@ -8,5 +8,5 @@ import type { Attribs, IShape } from "@thi.ng/geom-api";
8
8
  * @param attribs
9
9
  * @param replace
10
10
  */
11
- export declare const withAttribs: <T extends IShape<IShape<any>>>(shape: T, attribs: Attribs, replace?: boolean) => IShape<any>;
11
+ export declare const withAttribs: <T extends IShape<IShape<any>>>(shape: T, attribs: Attribs, replace?: boolean) => T;
12
12
  //# sourceMappingURL=with-attribs.d.ts.map