@thi.ng/geom 6.1.8 → 7.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 +108 -1
- package/README.md +33 -28
- package/api/arc.js +1 -1
- package/api/complex-polygon.d.ts +14 -0
- package/api/complex-polygon.js +44 -0
- package/api/path.d.ts +11 -3
- package/api/path.js +45 -29
- package/apply-transforms.js +5 -10
- package/arc-length.d.ts +1 -0
- package/arc-length.js +12 -0
- package/area.d.ts +1 -0
- package/area.js +4 -1
- package/as-cubic.d.ts +2 -0
- package/as-cubic.js +10 -2
- package/as-path.d.ts +19 -3
- package/as-path.js +54 -1
- package/as-polygon.d.ts +7 -5
- package/as-polygon.js +14 -1
- package/as-polyline.d.ts +6 -4
- package/as-polyline.js +19 -5
- package/bounds.js +14 -7
- package/centroid.d.ts +3 -2
- package/centroid.js +10 -1
- package/classify-point.d.ts +5 -2
- package/clip-convex.d.ts +22 -3
- package/clip-convex.js +39 -12
- package/closest-point.d.ts +2 -0
- package/closest-point.js +34 -0
- package/complex-polygon-from-path.d.ts +14 -0
- package/complex-polygon-from-path.js +9 -0
- package/complex-polygon.d.ts +23 -0
- package/complex-polygon.js +6 -0
- package/convex-hull.d.ts +1 -0
- package/convex-hull.js +2 -0
- package/edges.d.ts +2 -0
- package/edges.js +7 -3
- package/fit-into-bounds.js +5 -10
- package/flip.d.ts +1 -0
- package/flip.js +5 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/internal/bounds.js +3 -6
- package/internal/copy.d.ts +3 -1
- package/internal/copy.js +9 -3
- package/internal/transform.d.ts +20 -7
- package/internal/transform.js +10 -0
- package/intersects.js +3 -6
- package/package.json +48 -33
- package/path-builder.d.ts +21 -1
- package/path-builder.js +31 -14
- package/path-from-svg.d.ts +13 -1
- package/path-from-svg.js +10 -14
- package/path.d.ts +59 -2
- package/path.js +44 -19
- package/point-inside.d.ts +12 -9
- package/point-inside.js +3 -0
- package/proximity.d.ts +11 -0
- package/proximity.js +9 -0
- package/resample.d.ts +1 -0
- package/resample.js +7 -1
- package/rotate.d.ts +1 -0
- package/rotate.js +13 -10
- package/scale-with-center.d.ts +20 -0
- package/scale-with-center.js +7 -0
- package/scale.d.ts +1 -0
- package/scale.js +12 -9
- package/scatter.js +1 -2
- package/simplify.d.ts +4 -3
- package/simplify.js +39 -27
- package/split-arclength.d.ts +1 -1
- package/split-arclength.js +4 -6
- package/subdiv-curve.d.ts +5 -1
- package/subdiv-curve.js +10 -8
- package/transform-vertices.d.ts +1 -0
- package/transform-vertices.js +19 -19
- package/transform.d.ts +1 -0
- package/transform.js +17 -16
- package/translate.d.ts +1 -0
- package/translate.js +17 -12
- package/vertices.d.ts +18 -17
- package/vertices.js +22 -11
- package/with-attribs.d.ts +1 -1
- package/with-attribs.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2024-
|
|
3
|
+
- **Last updated**: 2024-05-08T18:24:31Z
|
|
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,113 @@ 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
|
+
# [7.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@7.0.0) (2024-05-08)
|
|
13
|
+
|
|
14
|
+
#### 🛑 Breaking changes
|
|
15
|
+
|
|
16
|
+
- update Path to support sub-paths (holes), update impls ([#464](https://github.com/thi-ng/umbrella/issues/464)) ([9329d27](https://github.com/thi-ng/umbrella/commit/9329d27))
|
|
17
|
+
- BREAKING CHANGE: update path related ctors & functions
|
|
18
|
+
- add `subPaths` argument for Path ctor/factory fn
|
|
19
|
+
- rename `Path.add()` => `Path.addSegments()`
|
|
20
|
+
- add `Path.addSubPaths()`
|
|
21
|
+
- update `Path.toHiccup()` to include sub-paths
|
|
22
|
+
- update `pathFromSvg()` to always return a single path only
|
|
23
|
+
- sub-paths are included in main path now
|
|
24
|
+
- update impls for following ops to also process sub-paths:
|
|
25
|
+
- bounds()
|
|
26
|
+
- rotate()
|
|
27
|
+
- scale()
|
|
28
|
+
- simplify()
|
|
29
|
+
- translate()
|
|
30
|
+
- transform()
|
|
31
|
+
- transformVertices()
|
|
32
|
+
- update asPolyline(), add support for multiple boundaries ([#464](https://github.com/thi-ng/umbrella/issues/464)) ([0616b96](https://github.com/thi-ng/umbrella/commit/0616b96))
|
|
33
|
+
- BREAKING CHANGE: update asPolygon() to return array of polylines
|
|
34
|
+
- add/update impls for complexpoly & path to produce multiple results
|
|
35
|
+
- update other internal callsites
|
|
36
|
+
- update tests
|
|
37
|
+
- update `Path` closing logic ([ce3a922](https://github.com/thi-ng/umbrella/commit/ce3a922))
|
|
38
|
+
- BREAKING CHANGE: update `Path` closing logic, `Path.closed` now a readonly property
|
|
39
|
+
- add `Path.closed()` getter
|
|
40
|
+
- add `Path.close()` to add a `Z`-type segment, check if not closed already
|
|
41
|
+
- update `Path.addSegments()` to check each segment, throw error if path already closed
|
|
42
|
+
- refactor `PathBuilder.closePath()`
|
|
43
|
+
- add asPolygon() support for complexpoly & path ([e3c9f20](https://github.com/thi-ng/umbrella/commit/e3c9f20))
|
|
44
|
+
- BREAKING CHANGE: update asPolygon() to return array of polygons (rather than single only)
|
|
45
|
+
- add support for complexpoly & path (incl. sub-shapes, holes)
|
|
46
|
+
- refactor internal call sites
|
|
47
|
+
- update asPath(), add AsPathOpts ([ef0ebdf](https://github.com/thi-ng/umbrella/commit/ef0ebdf))
|
|
48
|
+
- BREAKING CHANGE: update asPath() args, add AsPathOpts as 2nd arg
|
|
49
|
+
- add option for using only linear path segments (no cubics)
|
|
50
|
+
- update impls for complexpoly & other polygon types
|
|
51
|
+
- update Path & PathBuilder.close() ([b2134c2](https://github.com/thi-ng/umbrella/commit/b2134c2))
|
|
52
|
+
- BREAKING CHANGE: rename `PathBuilder.closePath()` => `PathBuilder.close()`
|
|
53
|
+
- update `Path.close()` to return path itself
|
|
54
|
+
- rewrite roundedRect() to allow individual corner radii ([a4817aa](https://github.com/thi-ng/umbrella/commit/a4817aa))
|
|
55
|
+
- BREAKING CHANGE: update roundedRect() radius handling to allow individual corner radii
|
|
56
|
+
- update docs
|
|
57
|
+
- add tests
|
|
58
|
+
|
|
59
|
+
#### 🚀 Features
|
|
60
|
+
|
|
61
|
+
- initial import ComplexPolygon & impls ([#464](https://github.com/thi-ng/umbrella/issues/464)) ([ded007c](https://github.com/thi-ng/umbrella/commit/ded007c))
|
|
62
|
+
- add complexPolygon() factory fn
|
|
63
|
+
- add bounds() & centroid() impls
|
|
64
|
+
- add ops for complex polygons ([#464](https://github.com/thi-ng/umbrella/issues/464)) ([35ce854](https://github.com/thi-ng/umbrella/commit/35ce854))
|
|
65
|
+
- add implementations for:
|
|
66
|
+
- arcLength()
|
|
67
|
+
- area()
|
|
68
|
+
- asPath()
|
|
69
|
+
- closestPoint()
|
|
70
|
+
- convexHull()
|
|
71
|
+
- edges()
|
|
72
|
+
- flip()
|
|
73
|
+
- pointInside()
|
|
74
|
+
- resample()
|
|
75
|
+
- rotate()
|
|
76
|
+
- scale()
|
|
77
|
+
- simplify()
|
|
78
|
+
- subdivCurve()
|
|
79
|
+
- transform()
|
|
80
|
+
- transformVertices()
|
|
81
|
+
- translate()
|
|
82
|
+
- vertices()
|
|
83
|
+
- add tests
|
|
84
|
+
- add proximity() ([5d5951c](https://github.com/thi-ng/umbrella/commit/5d5951c))
|
|
85
|
+
- update `vertices()` impl for `Path`, incl. sub-path vertices ([824067f](https://github.com/thi-ng/umbrella/commit/824067f))
|
|
86
|
+
- update simplify() default threshold ([bdba298](https://github.com/thi-ng/umbrella/commit/bdba298))
|
|
87
|
+
- add arcLength() for Path, refactor complexpoly impl ([d133bbe](https://github.com/thi-ng/umbrella/commit/d133bbe))
|
|
88
|
+
- add/update asCubic() impls for complex poly & path ([7f9e927](https://github.com/thi-ng/umbrella/commit/7f9e927))
|
|
89
|
+
- update pathFromCubics() to auto-create sub-paths if needed ([1170e45](https://github.com/thi-ng/umbrella/commit/1170e45))
|
|
90
|
+
- add closestPoint() impl for Path ([f0cf2f1](https://github.com/thi-ng/umbrella/commit/f0cf2f1))
|
|
91
|
+
- add pointInside() impl for Polyline ([d10bf43](https://github.com/thi-ng/umbrella/commit/d10bf43))
|
|
92
|
+
- add centroid() & convexHull() impl for Path ([76aa229](https://github.com/thi-ng/umbrella/commit/76aa229))
|
|
93
|
+
- add complexPolygonFromPath() ([cd526f1](https://github.com/thi-ng/umbrella/commit/cd526f1))
|
|
94
|
+
- update PathBuilder.close(), fix attrib handling ([e68d0bc](https://github.com/thi-ng/umbrella/commit/e68d0bc))
|
|
95
|
+
- only insert closing line segment if needed
|
|
96
|
+
- copy attribs for each new path
|
|
97
|
+
- add docs
|
|
98
|
+
- add opt attribs for `pathFromSvg()` ([2da31f6](https://github.com/thi-ng/umbrella/commit/2da31f6))
|
|
99
|
+
- update docs
|
|
100
|
+
- add/update tests
|
|
101
|
+
- add scaleWithCenter() ([e328494](https://github.com/thi-ng/umbrella/commit/e328494))
|
|
102
|
+
- add complexpoly & path support for `clipConvex()` ([7665dc1](https://github.com/thi-ng/umbrella/commit/7665dc1))
|
|
103
|
+
|
|
104
|
+
#### 🩹 Bug fixes
|
|
105
|
+
|
|
106
|
+
- update vertices() ([2afc05e](https://github.com/thi-ng/umbrella/commit/2afc05e))
|
|
107
|
+
- update impl for points, poly, polyline to return shallow copy of point array if no opts given
|
|
108
|
+
|
|
109
|
+
#### ♻️ Refactoring
|
|
110
|
+
|
|
111
|
+
- update withAttribs(), make new attribs optional ([688e1bf](https://github.com/thi-ng/umbrella/commit/688e1bf))
|
|
112
|
+
- update geom examples (recent API changes) ([f0f5ea7](https://github.com/thi-ng/umbrella/commit/f0f5ea7))
|
|
113
|
+
- update area() impl for Path ([0960817](https://github.com/thi-ng/umbrella/commit/0960817))
|
|
114
|
+
- update/simplify asPath() impls ([cbc71bb](https://github.com/thi-ng/umbrella/commit/cbc71bb))
|
|
115
|
+
- update centroid() for complexpoly ([58ac296](https://github.com/thi-ng/umbrella/commit/58ac296))
|
|
116
|
+
- re-use migrated fn from [@thi.ng/geom-poly-utils](https://github.com/thi-ng/umbrella/tree/main/packages/geom-poly-utils)
|
|
117
|
+
- update path segment transformations ([88b2c40](https://github.com/thi-ng/umbrella/commit/88b2c40))
|
|
118
|
+
|
|
12
119
|
### [6.1.7](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom@6.1.7) (2024-04-20)
|
|
13
120
|
|
|
14
121
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -44,28 +44,29 @@ name](http://thi.ng/geom-clj). All polymorphic operations built on
|
|
|
44
44
|
The following shape primitives are provided. For many there're multiple ways to
|
|
45
45
|
create them, please check linked sources and/or docs.
|
|
46
46
|
|
|
47
|
-
| Shape/Form
|
|
48
|
-
|
|
49
|
-
| [AABB](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/aabb.ts)
|
|
50
|
-
| [Arc](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/arc.ts)
|
|
51
|
-
| [Circle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/circle.ts)
|
|
52
|
-
| [
|
|
53
|
-
| [
|
|
54
|
-
| [
|
|
55
|
-
| [
|
|
56
|
-
| [
|
|
57
|
-
| [Path
|
|
58
|
-
| [
|
|
59
|
-
| [
|
|
60
|
-
| [
|
|
61
|
-
| [
|
|
62
|
-
| [
|
|
63
|
-
| [
|
|
64
|
-
| [
|
|
65
|
-
| [
|
|
66
|
-
| [
|
|
67
|
-
| [
|
|
68
|
-
| [
|
|
47
|
+
| Shape/Form | Description | Hiccup support |
|
|
48
|
+
|--------------------------------------------------------------------------------------------------------|---------------------------------------|-----------------|
|
|
49
|
+
| [AABB](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/aabb.ts) | 3D Axis-aligned bounding box | ✅<sup>(2)</sup> |
|
|
50
|
+
| [Arc](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/arc.ts) | 2D elliptic arc | ✅ |
|
|
51
|
+
| [Circle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/circle.ts) | 2D circle | ✅ |
|
|
52
|
+
| [ComplexPolygon](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/complex-polygon.ts) | 2D polygon w/ holes | ✅ |
|
|
53
|
+
| [Cubic](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/cubic.ts) | nD cubic bezier | ✅<sup>(1)</sup> |
|
|
54
|
+
| [Ellipse](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/ellipse.ts) | 2D ellipse | ✅ |
|
|
55
|
+
| [Group](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/group.ts) | group of 2D shapes | ✅ |
|
|
56
|
+
| [Line](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/line.ts) | 2D line segment | ✅ |
|
|
57
|
+
| [Path](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/path-builder.ts) | 2D path (w/ optional holes/sub-paths) | ✅ |
|
|
58
|
+
| [Path (from SVG)](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/path-from-svg.ts) | 2D path from SVG | ✅ |
|
|
59
|
+
| [Plane](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/plane.ts) | 3D plane | ✅<sup>(2)</sup> |
|
|
60
|
+
| [Point cloud](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/points.ts) | nD point cloud | ✅<sup>(1)</sup> |
|
|
61
|
+
| [Polygon](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/polygon.ts) | 2D simple polygon (no holes) | ✅ |
|
|
62
|
+
| [Polyline](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/polyline.ts) | 2D polyline | ✅ |
|
|
63
|
+
| [Quad](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/quad.ts) | 2D/3D quad (4-gon) | ✅<sup>(1)</sup> |
|
|
64
|
+
| [Quadratic](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/quadratic.ts) | nD quadratic bezier | ✅<sup>(1)</sup> |
|
|
65
|
+
| [Ray](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/ray.ts) | nD ray | ✅<sup>(1)</sup> |
|
|
66
|
+
| [Rectangle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/rect.ts) | 2D rectangle | ✅ |
|
|
67
|
+
| [Sphere](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/sphere.ts) | 3D sphere | ✅<sup>(2)</sup> |
|
|
68
|
+
| [Text](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/text.ts) | Basic stub for text labels | ✅<sup>(3)</sup> |
|
|
69
|
+
| [Triangle](https://github.com/thi-ng/umbrella/blob/develop/packages/geom/src/triangle.ts) | 2D triangle | ✅ |
|
|
69
70
|
|
|
70
71
|
- <sup>(1)</sup> valid hiccup format, currently only useable/supported if 2D geometry
|
|
71
72
|
- <sup>(2)</sup> valid hiccup format, currently unused/unsupported elsewhere
|
|
@@ -77,9 +78,10 @@ With very few exceptions these all are implementing the [`IToHiccup`
|
|
|
77
78
|
interface](https://docs.thi.ng/umbrella/api/interfaces/IToHiccup.html) and so
|
|
78
79
|
can be easily converted (via
|
|
79
80
|
[hiccup](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup)) to a
|
|
80
|
-
variety of other formats
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
variety of other formats, incl. [conversion to SVG](#svg-support).
|
|
82
|
+
|
|
83
|
+
By design, for better flexibility and performance reasons, the hiccup flavor
|
|
84
|
+
used by this package is **not** compatible with that used by
|
|
83
85
|
[thi.ng/hiccup-svg](https://github.com/thi-ng/umbrella/tree/develop/packages/hiccup-svg),
|
|
84
86
|
though the latter provides a
|
|
85
87
|
[`convertTree()`](https://docs.thi.ng/umbrella/hiccup-svg/functions/convertTree.html)
|
|
@@ -104,8 +106,8 @@ directly and/or perform automatic resampling/conversion if needed).
|
|
|
104
106
|
| [`area()`](https://docs.thi.ng/umbrella/geom/functions/area.html) | signed/unsigned surface area |
|
|
105
107
|
| [`asCubic()`](https://docs.thi.ng/umbrella/geom/functions/asCubic.html) | convert shape boundary to cubic bezier segments |
|
|
106
108
|
| [`asPath()`](https://docs.thi.ng/umbrella/geom/functions/asPath.html) | convert shape to path |
|
|
107
|
-
| [`asPolygon()`](https://docs.thi.ng/umbrella/geom/functions/asPolygon.html) | convert shape to polygon
|
|
108
|
-
| [`asPolyline()`](https://docs.thi.ng/umbrella/geom/functions/asPolyline.html) | convert shape to polyline
|
|
109
|
+
| [`asPolygon()`](https://docs.thi.ng/umbrella/geom/functions/asPolygon.html) | convert shape to polygon(s) |
|
|
110
|
+
| [`asPolyline()`](https://docs.thi.ng/umbrella/geom/functions/asPolyline.html) | convert shape to polyline(s) |
|
|
109
111
|
| [`asSvg()`](https://docs.thi.ng/umbrella/geom/functions/asSvg.html) | serialize shape/group/hierarchy to SVG |
|
|
110
112
|
| [`bounds()`](https://docs.thi.ng/umbrella/geom/functions/bounds.html) | compute bounding box |
|
|
111
113
|
| [`center()`](https://docs.thi.ng/umbrella/geom/functions/center.html) | center shape around origin or point |
|
|
@@ -122,6 +124,7 @@ directly and/or perform automatic resampling/conversion if needed).
|
|
|
122
124
|
| [`offset()`](https://docs.thi.ng/umbrella/geom/functions/offset.html) | shape/path offsetting |
|
|
123
125
|
| [`pointAt()`](https://docs.thi.ng/umbrella/geom/functions/pointAt.html) | compute point on shape boundary at parametric position |
|
|
124
126
|
| [`pointInside()`](https://docs.thi.ng/umbrella/geom/functions/pointInside.html) | check if point is inside shape |
|
|
127
|
+
| [`proximity()`](https://docs.thi.ng/umbrella/geom/functions/proximity.html) | distance from point to shape boundary |
|
|
125
128
|
| [`resample()`](https://docs.thi.ng/umbrella/geom/functions/resample.html) | resample/convert shape |
|
|
126
129
|
| [`rotate()`](https://docs.thi.ng/umbrella/geom/functions/rotate.html) | rotate shape |
|
|
127
130
|
| [`scale()`](https://docs.thi.ng/umbrella/geom/functions/scale.html) | scale shape (uniformly/non-uniformly) |
|
|
@@ -210,7 +213,7 @@ For Node.js REPL:
|
|
|
210
213
|
const geom = await import("@thi.ng/geom");
|
|
211
214
|
```
|
|
212
215
|
|
|
213
|
-
Package sizes (brotli'd, pre-treeshake): ESM:
|
|
216
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 14.59 KB
|
|
214
217
|
|
|
215
218
|
## Dependencies
|
|
216
219
|
|
|
@@ -253,9 +256,11 @@ directory are using this package:
|
|
|
253
256
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/boid-basics.png" width="240"/> | Basic 2D boid simulation and spatial indexing neighbor lookups | [Demo](https://demo.thi.ng/umbrella/boid-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/boid-basics) |
|
|
254
257
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-recorder.png" width="240"/> | Self-modifying, animated typographic grid with emergent complex patterns | [Demo](https://demo.thi.ng/umbrella/canvas-recorder/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/canvas-recorder) |
|
|
255
258
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/fiber-basics.png" width="240"/> | Fiber-based cooperative multitasking basics | [Demo](https://demo.thi.ng/umbrella/fiber-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/fiber-basics) |
|
|
259
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-complex-poly.png" width="240"/> | Shape conversions & operations using polygons with holes | [Demo](https://demo.thi.ng/umbrella/geom-complex-poly/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-complex-poly) |
|
|
256
260
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-convex-hull.png" width="240"/> | Convex hull & shape clipping of 2D polygons | [Demo](https://demo.thi.ng/umbrella/geom-convex-hull/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-convex-hull) |
|
|
257
261
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-fuzz.png" width="240"/> | geom-fuzz basic shape & fill examples | [Demo](https://demo.thi.ng/umbrella/geom-fuzz-basics/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-fuzz-basics) |
|
|
258
262
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-sdf-logo.jpg" width="240"/> | (Re)Constructing the thi.ng logo using a 2D signed-distance field | [Demo](https://demo.thi.ng/umbrella/geom-sdf-logo/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-sdf-logo) |
|
|
263
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-sdf-path.png" width="240"/> | SVG path to SDF, applying deformation and converting back to SVG | [Demo](https://demo.thi.ng/umbrella/geom-sdf-path/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-sdf-path) |
|
|
259
264
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-terrain-viz.jpg" width="240"/> | 2.5D hidden line visualization of digital elevation files (DEM) | [Demo](https://demo.thi.ng/umbrella/geom-terrain-viz/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-terrain-viz) |
|
|
260
265
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/tessel.png" width="240"/> | Animated, recursive polygon tessellations | [Demo](https://demo.thi.ng/umbrella/geom-tessel/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-tessel) |
|
|
261
266
|
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/geom-voronoi-mst.jpg" width="240"/> | Poisson-disk shape-aware sampling, Voronoi & Minimum Spanning Tree visualization | [Demo](https://demo.thi.ng/umbrella/geom-voronoi-mst/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/geom-voronoi-mst) |
|
package/api/arc.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Attribs, IHiccupShape } from "@thi.ng/geom-api";
|
|
2
|
+
import { Polygon } from "./polygon.js";
|
|
3
|
+
export declare class ComplexPolygon implements IHiccupShape {
|
|
4
|
+
boundary: Polygon;
|
|
5
|
+
attribs?: Attribs | undefined;
|
|
6
|
+
children: Polygon[];
|
|
7
|
+
constructor(boundary?: Polygon, children?: Iterable<Polygon>, attribs?: Attribs | undefined);
|
|
8
|
+
get type(): string;
|
|
9
|
+
addChild(poly: Polygon): void;
|
|
10
|
+
copy(): ComplexPolygon;
|
|
11
|
+
withAttribs(attribs: Attribs): ComplexPolygon;
|
|
12
|
+
toHiccup(): (string | any[] | Attribs | undefined)[];
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=complex-polygon.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ensureArray } from "@thi.ng/arrays/ensure-array";
|
|
2
|
+
import { __copyAttribs } from "../internal/copy.js";
|
|
3
|
+
import { Polygon } from "./polygon.js";
|
|
4
|
+
class ComplexPolygon {
|
|
5
|
+
constructor(boundary = new Polygon(), children, attribs) {
|
|
6
|
+
this.boundary = boundary;
|
|
7
|
+
this.attribs = attribs;
|
|
8
|
+
this.children = children ? ensureArray(children) : [];
|
|
9
|
+
}
|
|
10
|
+
children;
|
|
11
|
+
get type() {
|
|
12
|
+
return "complexpoly";
|
|
13
|
+
}
|
|
14
|
+
addChild(poly) {
|
|
15
|
+
this.children.push(poly);
|
|
16
|
+
}
|
|
17
|
+
copy() {
|
|
18
|
+
return new ComplexPolygon(
|
|
19
|
+
this.boundary.copy(),
|
|
20
|
+
this.children.map((h) => h.copy()),
|
|
21
|
+
__copyAttribs(this)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
withAttribs(attribs) {
|
|
25
|
+
return new ComplexPolygon(this.boundary, this.children, attribs);
|
|
26
|
+
}
|
|
27
|
+
toHiccup() {
|
|
28
|
+
const segments = [];
|
|
29
|
+
const $hiccupSegments = ({ points }) => {
|
|
30
|
+
if (!points.length) return;
|
|
31
|
+
segments.push(["M", points[0]]);
|
|
32
|
+
for (let i = 1, n = points.length; i < n; i++) {
|
|
33
|
+
segments.push(["L", points[i]]);
|
|
34
|
+
}
|
|
35
|
+
segments.push(["Z"]);
|
|
36
|
+
};
|
|
37
|
+
$hiccupSegments(this.boundary);
|
|
38
|
+
for (let c of this.children) $hiccupSegments(c);
|
|
39
|
+
return ["path", this.attribs, segments];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
ComplexPolygon
|
|
44
|
+
};
|
package/api/path.d.ts
CHANGED
|
@@ -3,15 +3,23 @@ import type { Attribs, IHiccupShape, PathSegment } from "@thi.ng/geom-api";
|
|
|
3
3
|
export declare class Path implements IClear, IHiccupShape {
|
|
4
4
|
attribs?: Attribs | undefined;
|
|
5
5
|
segments: PathSegment[];
|
|
6
|
-
|
|
7
|
-
constructor(segments?: Iterable<PathSegment>, attribs?: Attribs | undefined);
|
|
6
|
+
subPaths: PathSegment[][];
|
|
7
|
+
constructor(segments?: Iterable<PathSegment>, subPaths?: Iterable<PathSegment[]>, attribs?: Attribs | undefined);
|
|
8
8
|
get type(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Returns true, if the last main segment is a closing segment, e.g. if the
|
|
11
|
+
* path represents a closed shape.
|
|
12
|
+
*/
|
|
13
|
+
get closed(): boolean;
|
|
9
14
|
[Symbol.iterator](): Generator<PathSegment, void, undefined>;
|
|
10
15
|
clear(): void;
|
|
16
|
+
close(): this;
|
|
11
17
|
copy(): Path;
|
|
12
18
|
withAttribs(attribs: Attribs): Path;
|
|
13
19
|
equiv(o: any): boolean;
|
|
14
|
-
|
|
20
|
+
isComplex(): number;
|
|
21
|
+
addSegments(...segments: PathSegment[]): this;
|
|
22
|
+
addSubPaths(...paths: PathSegment[][]): this;
|
|
15
23
|
toHiccup(): (string | any[] | Attribs)[];
|
|
16
24
|
}
|
|
17
25
|
//# sourceMappingURL=path.d.ts.map
|
package/api/path.js
CHANGED
|
@@ -1,68 +1,84 @@
|
|
|
1
1
|
import { ensureArray } from "@thi.ng/arrays/ensure-array";
|
|
2
|
+
import { peek } from "@thi.ng/arrays/peek";
|
|
2
3
|
import { equiv } from "@thi.ng/equiv";
|
|
3
4
|
import { illegalState } from "@thi.ng/errors/illegal-state";
|
|
4
|
-
import {
|
|
5
|
-
|
|
5
|
+
import { __copyAttribs, __copySegment } from "../internal/copy.js";
|
|
6
|
+
const CLOSE = Object.freeze({ type: "z" });
|
|
6
7
|
class Path {
|
|
7
|
-
constructor(segments, attribs) {
|
|
8
|
+
constructor(segments, subPaths, attribs) {
|
|
8
9
|
this.attribs = attribs;
|
|
9
10
|
this.segments = segments ? ensureArray(segments) : [];
|
|
11
|
+
this.subPaths = subPaths ? ensureArray(subPaths) : [];
|
|
10
12
|
}
|
|
11
13
|
segments;
|
|
12
|
-
|
|
14
|
+
subPaths;
|
|
13
15
|
get type() {
|
|
14
16
|
return "path";
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns true, if the last main segment is a closing segment, e.g. if the
|
|
20
|
+
* path represents a closed shape.
|
|
21
|
+
*/
|
|
22
|
+
get closed() {
|
|
23
|
+
return peek(this.segments)?.type === "z";
|
|
24
|
+
}
|
|
16
25
|
*[Symbol.iterator]() {
|
|
17
26
|
yield* this.segments;
|
|
18
27
|
}
|
|
19
28
|
clear() {
|
|
20
29
|
this.segments.length = 0;
|
|
21
30
|
}
|
|
31
|
+
close() {
|
|
32
|
+
if (!this.closed) this.segments.push(CLOSE);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
22
35
|
copy() {
|
|
23
36
|
const p = new Path(
|
|
24
|
-
this.segments.map(
|
|
25
|
-
|
|
26
|
-
s.point && (d.point = copy(s.point));
|
|
27
|
-
s.geo && (d.geo = s.geo.copy());
|
|
28
|
-
return d;
|
|
29
|
-
}),
|
|
37
|
+
this.segments.map(__copySegment),
|
|
38
|
+
this.subPaths.map((sub) => sub.map(__copySegment)),
|
|
30
39
|
__copyAttribs(this)
|
|
31
40
|
);
|
|
32
|
-
p.closed = this.closed;
|
|
33
41
|
return p;
|
|
34
42
|
}
|
|
35
43
|
withAttribs(attribs) {
|
|
36
|
-
|
|
37
|
-
res.closed = this.closed;
|
|
38
|
-
return res;
|
|
44
|
+
return new Path(this.segments, this.subPaths, attribs);
|
|
39
45
|
}
|
|
40
46
|
equiv(o) {
|
|
41
47
|
return o instanceof Path && equiv(this.segments, o.segments);
|
|
42
48
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
isComplex() {
|
|
50
|
+
return this.subPaths.length;
|
|
51
|
+
}
|
|
52
|
+
addSegments(...segments) {
|
|
53
|
+
for (let s of segments) {
|
|
54
|
+
this.closed && illegalState("path already closed");
|
|
55
|
+
this.segments.push(s);
|
|
56
|
+
}
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
addSubPaths(...paths) {
|
|
60
|
+
this.subPaths.push(...paths);
|
|
61
|
+
return this;
|
|
47
62
|
}
|
|
48
63
|
toHiccup() {
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
if (n > 1) {
|
|
53
|
-
for (let i = 0; i < n; i++) {
|
|
64
|
+
const acc = [];
|
|
65
|
+
const $hiccupSegments = (segments) => {
|
|
66
|
+
for (let i = 0, n = segments.length; i < n; i++) {
|
|
54
67
|
const s = segments[i];
|
|
55
68
|
if (s.geo) {
|
|
56
|
-
|
|
69
|
+
acc.push(...s.geo.toHiccupPathSegments());
|
|
57
70
|
} else if (s.point) {
|
|
58
|
-
|
|
71
|
+
acc.push(["M", s.point]);
|
|
72
|
+
} else {
|
|
73
|
+
acc.push([s.type]);
|
|
59
74
|
}
|
|
60
75
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
76
|
+
};
|
|
77
|
+
if (this.segments.length > 1) {
|
|
78
|
+
$hiccupSegments(this.segments);
|
|
64
79
|
}
|
|
65
|
-
|
|
80
|
+
for (let p of this.subPaths) $hiccupSegments(p);
|
|
81
|
+
return ["path", this.attribs || {}, acc];
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
export {
|
package/apply-transforms.js
CHANGED
|
@@ -8,23 +8,18 @@ import { translate } from "./translate.js";
|
|
|
8
8
|
const TX_ATTRIBS = ["transform", "translate", "rotate", "scale"];
|
|
9
9
|
const __apply = ($) => {
|
|
10
10
|
let attribs = $.attribs;
|
|
11
|
-
if (!attribs)
|
|
12
|
-
return $;
|
|
11
|
+
if (!attribs) return $;
|
|
13
12
|
const { transform: tx, translate: t, rotate: r, scale: s } = attribs;
|
|
14
13
|
if (tx)
|
|
15
14
|
return transform(
|
|
16
15
|
$.withAttribs(withoutKeysObj(attribs, TX_ATTRIBS)),
|
|
17
16
|
tx
|
|
18
17
|
);
|
|
19
|
-
if (!(t || r || s))
|
|
20
|
-
return $;
|
|
18
|
+
if (!(t || r || s)) return $;
|
|
21
19
|
$ = $.withAttribs(withoutKeysObj(attribs, TX_ATTRIBS));
|
|
22
|
-
if (r)
|
|
23
|
-
|
|
24
|
-
if (
|
|
25
|
-
$ = scale($, s);
|
|
26
|
-
if (t)
|
|
27
|
-
$ = translate($, t);
|
|
20
|
+
if (r) $ = rotate($, r);
|
|
21
|
+
if (s) $ = scale($, s);
|
|
22
|
+
if (t) $ = translate($, t);
|
|
28
23
|
return $;
|
|
29
24
|
};
|
|
30
25
|
const applyTransforms = defmulti(
|
package/arc-length.d.ts
CHANGED
package/arc-length.js
CHANGED
|
@@ -2,6 +2,8 @@ import { defmulti } from "@thi.ng/defmulti/defmulti";
|
|
|
2
2
|
import { perimeter } from "@thi.ng/geom-poly-utils/perimeter";
|
|
3
3
|
import { PI, TAU } from "@thi.ng/math/api";
|
|
4
4
|
import { dist } from "@thi.ng/vectors/dist";
|
|
5
|
+
import { asPolygon } from "./as-polygon.js";
|
|
6
|
+
import { asPolyline } from "./as-polyline.js";
|
|
5
7
|
import { __dispatch } from "./internal/dispatch.js";
|
|
6
8
|
const arcLength = defmulti(
|
|
7
9
|
__dispatch,
|
|
@@ -11,6 +13,10 @@ const arcLength = defmulti(
|
|
|
11
13
|
},
|
|
12
14
|
{
|
|
13
15
|
circle: ($) => TAU * $.r,
|
|
16
|
+
complexpoly: ($) => [$.boundary, ...$.children].reduce(
|
|
17
|
+
(acc, c) => acc + arcLength(c),
|
|
18
|
+
0
|
|
19
|
+
),
|
|
14
20
|
ellipse: ({ r: [a, b] }) => (
|
|
15
21
|
// Ramanujan approximation
|
|
16
22
|
// https://www.mathsisfun.com/geometry/ellipse-perimeter.html
|
|
@@ -18,6 +24,12 @@ const arcLength = defmulti(
|
|
|
18
24
|
),
|
|
19
25
|
group: ({ children }) => children.reduce((sum, $) => sum + arcLength($), 0),
|
|
20
26
|
line: ({ points }) => dist(points[0], points[1]),
|
|
27
|
+
path: ($) => {
|
|
28
|
+
return ($.closed ? asPolygon($) : asPolyline($)).reduce(
|
|
29
|
+
(acc, p) => acc + arcLength(p),
|
|
30
|
+
0
|
|
31
|
+
);
|
|
32
|
+
},
|
|
21
33
|
poly: ({ points }) => perimeter(points, points.length, true),
|
|
22
34
|
polyline: ({ points }) => perimeter(points, points.length),
|
|
23
35
|
rect: ({ size: [w, h] }) => 2 * (w + h),
|
package/area.d.ts
CHANGED
package/area.js
CHANGED
|
@@ -14,9 +14,12 @@ const area = defmulti(
|
|
|
14
14
|
($) => 0.5 * Math.abs($.start - $.end) * $.r[0] * $.r[1]
|
|
15
15
|
),
|
|
16
16
|
circle: ($) => PI * $.r ** 2,
|
|
17
|
+
complexpoly: ($, signed) => area($.boundary, signed) - $.children.reduce((acc, c) => acc + area(c, signed), 0),
|
|
17
18
|
ellipse: ($) => PI * $.r[0] * $.r[1],
|
|
18
19
|
group: ({ children }) => children.reduce((sum, $) => sum + area($, false), 0),
|
|
19
|
-
path: (
|
|
20
|
+
path: ($, signed) => {
|
|
21
|
+
return $.closed ? asPolygon($).reduce((acc, p) => acc + area(p, signed), 0) : 0;
|
|
22
|
+
},
|
|
20
23
|
plane: () => Infinity,
|
|
21
24
|
poly: ($, signed) => {
|
|
22
25
|
const area2 = polyArea2($.points);
|
package/as-cubic.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { Cubic } from "./api/cubic.js";
|
|
|
10
10
|
*
|
|
11
11
|
* - {@link Arc}
|
|
12
12
|
* - {@link Circle}
|
|
13
|
+
* - {@link ComplexPolygon}
|
|
13
14
|
* - {@link Cubic}
|
|
14
15
|
* - {@link Ellipse}
|
|
15
16
|
* - {@link Group}
|
|
@@ -27,6 +28,7 @@ import { Cubic } from "./api/cubic.js";
|
|
|
27
28
|
* for more details):
|
|
28
29
|
*
|
|
29
30
|
* - {@link Group} (only used for eligible children)
|
|
31
|
+
* - {@link ComplexPolygon}
|
|
30
32
|
* - {@link Polygon}
|
|
31
33
|
* - {@link Polyline}
|
|
32
34
|
* - {@link Quad}
|
package/as-cubic.js
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
openCubicFromControlPoints
|
|
9
9
|
} from "@thi.ng/geom-splines/cubic-from-controlpoints";
|
|
10
10
|
import { TAU } from "@thi.ng/math/api";
|
|
11
|
+
import { concat } from "@thi.ng/transducers/concat";
|
|
12
|
+
import { flatten1 } from "@thi.ng/transducers/flatten1";
|
|
11
13
|
import { mapcat } from "@thi.ng/transducers/mapcat";
|
|
12
14
|
import { Cubic } from "./api/cubic.js";
|
|
13
15
|
import { arc } from "./arc.js";
|
|
@@ -25,6 +27,9 @@ const asCubic = defmulti(
|
|
|
25
27
|
{
|
|
26
28
|
arc: cubicFromArc,
|
|
27
29
|
circle: ($) => asCubic(arc($.pos, $.r, 0, 0, TAU, true, true)),
|
|
30
|
+
complexpoly: ($, opts = {}) => [
|
|
31
|
+
...mapcat((x) => asCubic(x, opts), [$.boundary, ...$.children])
|
|
32
|
+
],
|
|
28
33
|
cubic: ($) => [$],
|
|
29
34
|
group: ($, opts) => [
|
|
30
35
|
...mapcat((x) => asCubic(x, opts), $.children)
|
|
@@ -33,7 +38,10 @@ const asCubic = defmulti(
|
|
|
33
38
|
cubicFromLine(points[0], points[1], { ...attribs })
|
|
34
39
|
],
|
|
35
40
|
path: ($) => [
|
|
36
|
-
...mapcat(
|
|
41
|
+
...mapcat(
|
|
42
|
+
(segment) => segment.geo ? asCubic(segment.geo) : null,
|
|
43
|
+
concat($.segments, flatten1($.subPaths))
|
|
44
|
+
)
|
|
37
45
|
],
|
|
38
46
|
poly: ($, opts = {}) => __polyCubic(
|
|
39
47
|
$,
|
|
@@ -50,7 +58,7 @@ const asCubic = defmulti(
|
|
|
50
58
|
quadratic: ({ attribs, points }) => [
|
|
51
59
|
cubicFromQuadratic(points[0], points[1], points[2], { ...attribs })
|
|
52
60
|
],
|
|
53
|
-
rect: ($, opts) => asCubic(asPolygon($), opts)
|
|
61
|
+
rect: ($, opts) => asCubic(asPolygon($)[0], opts)
|
|
54
62
|
}
|
|
55
63
|
);
|
|
56
64
|
const __polyCubic = ($, opts, breakPoints, controlPoints) => {
|
package/as-path.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Maybe } from "@thi.ng/api";
|
|
2
|
+
import type { MultiFn2O } from "@thi.ng/defmulti";
|
|
3
|
+
import type { Attribs, CubicOpts, IShape } from "@thi.ng/geom-api";
|
|
4
|
+
import { Path } from "./api/path.js";
|
|
5
|
+
export interface AsPathOpts extends CubicOpts {
|
|
6
|
+
/**
|
|
7
|
+
* If true (default: false), creates path consisting of linear segments
|
|
8
|
+
* only.
|
|
9
|
+
*/
|
|
10
|
+
linear: boolean;
|
|
11
|
+
}
|
|
2
12
|
/**
|
|
3
|
-
* Converts given shape into a {@link Path} (via {@link asCubic} and
|
|
13
|
+
* Converts given shape into a {@link Path} (by default via {@link asCubic} and
|
|
4
14
|
* {@link pathFromCubics}).
|
|
5
15
|
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* If {@link AsPathOpts.linear} is enabled the shape will be converted into a
|
|
18
|
+
* path consisting only of linear segments (NOT cubic beziers). As an interim
|
|
19
|
+
* step this will involve a conversion via {@link asPolygon} or
|
|
20
|
+
* {@link asPolyline} with default opts.
|
|
21
|
+
*
|
|
6
22
|
* @param src
|
|
7
23
|
* @param attribs
|
|
8
24
|
*/
|
|
9
|
-
export declare const asPath: (
|
|
25
|
+
export declare const asPath: ((shape: IShape, opts?: Partial<AsPathOpts>, attribs?: Attribs) => Path) & MultiFn2O<IShape, Maybe<Partial<AsPathOpts>>, Attribs, Path>;
|
|
10
26
|
//# sourceMappingURL=as-path.d.ts.map
|