@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 +25 -1
- package/README.md +105 -47
- package/aabb.d.ts +1 -1
- package/aabb.js +1 -1
- package/api/aabb.d.ts +3 -1
- package/api/aabb.js +3 -0
- package/apply-transforms.js +3 -2
- package/offset.js +4 -4
- package/package.json +33 -30
- package/polygon.d.ts +45 -0
- package/polygon.js +46 -1
- package/rect.d.ts +2 -2
- package/rect.js +2 -2
- package/vertices.d.ts +19 -0
- package/vertices.js +41 -5
- package/with-attribs.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-
|
|
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
|
-
|
|
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
|
|
40
|
-
|
|
41
|
-
| [`
|
|
42
|
-
| [`
|
|
43
|
-
| [`
|
|
44
|
-
| [`
|
|
45
|
-
| [`
|
|
46
|
-
| [`
|
|
47
|
-
| [`
|
|
48
|
-
| [`
|
|
49
|
-
| [`
|
|
50
|
-
| [`
|
|
51
|
-
| [`
|
|
52
|
-
| [`
|
|
53
|
-
| [`
|
|
54
|
-
| [`
|
|
55
|
-
| [`
|
|
56
|
-
| [`
|
|
57
|
-
| [`
|
|
58
|
-
| [`
|
|
59
|
-
| [`
|
|
60
|
-
| [`
|
|
61
|
-
| [`
|
|
62
|
-
| [`
|
|
63
|
-
| [`
|
|
64
|
-
| [`
|
|
65
|
-
| [`
|
|
66
|
-
| [`
|
|
67
|
-
| [`
|
|
68
|
-
| [`
|
|
69
|
-
| [`
|
|
70
|
-
| [`
|
|
71
|
-
| [`
|
|
72
|
-
| [`
|
|
73
|
-
| [`
|
|
74
|
-
| [`
|
|
75
|
-
| [`
|
|
76
|
-
| [`
|
|
77
|
-
| [`
|
|
78
|
-
| [`
|
|
79
|
-
| [`
|
|
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 (
|
|
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
|
|
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
|
|
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
package/apply-transforms.js
CHANGED
|
@@ -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,
|
|
16
|
+
return transform($.withAttribs(withoutKeysObj(attribs, TX_ATTRIBS)), tx);
|
|
16
17
|
if (!(t || r || s))
|
|
17
18
|
return $;
|
|
18
|
-
$ = $.withAttribs(withoutKeysObj(attribs,
|
|
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 {
|
|
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 {
|
|
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) =>
|
|
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) =>
|
|
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
|
+
"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.
|
|
39
|
-
"@thi.ng/arrays": "^2.4.
|
|
40
|
-
"@thi.ng/associative": "^6.2.
|
|
41
|
-
"@thi.ng/checks": "^3.3.
|
|
42
|
-
"@thi.ng/defmulti": "^2.1.
|
|
43
|
-
"@thi.ng/equiv": "^2.1.
|
|
44
|
-
"@thi.ng/errors": "^2.2.
|
|
45
|
-
"@thi.ng/geom-api": "^3.3.
|
|
46
|
-
"@thi.ng/geom-arc": "^2.1.
|
|
47
|
-
"@thi.ng/geom-clip-line": "^2.
|
|
48
|
-
"@thi.ng/geom-clip-poly": "^2.1.
|
|
49
|
-
"@thi.ng/geom-closest-point": "^2.1.
|
|
50
|
-
"@thi.ng/geom-hull": "^2.1.
|
|
51
|
-
"@thi.ng/geom-isec": "^2.1.
|
|
52
|
-
"@thi.ng/geom-poly-utils": "^2.3.
|
|
53
|
-
"@thi.ng/geom-resample": "^2.1.
|
|
54
|
-
"@thi.ng/geom-splines": "^2.2.
|
|
55
|
-
"@thi.ng/geom-subdiv-curve": "^2.1.
|
|
56
|
-
"@thi.ng/geom-tessellate": "^2.1.
|
|
57
|
-
"@thi.ng/hiccup": "^4.2.
|
|
58
|
-
"@thi.ng/hiccup-svg": "^4.3.
|
|
59
|
-
"@thi.ng/math": "^5.3.
|
|
60
|
-
"@thi.ng/matrices": "^2.1.
|
|
61
|
-
"@thi.ng/random": "^3.3.
|
|
62
|
-
"@thi.ng/strings": "^3.3.
|
|
63
|
-
"@thi.ng/transducers": "^8.3.
|
|
64
|
-
"@thi.ng/vectors": "^7.5.
|
|
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.
|
|
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": "
|
|
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
|
-
|
|
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
|
|
12
|
-
export declare const
|
|
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
|
|
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
|
|
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) =>
|
|
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
|