@thi.ng/geom 7.0.1 → 8.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 +190 -1
- package/README.md +349 -112
- package/aabb.d.ts +26 -1
- package/api/aabb.d.ts +5 -4
- package/api/aabb.js +10 -7
- package/api/apc.d.ts +5 -3
- package/api/arc.d.ts +6 -5
- package/api/arc.js +3 -4
- package/api/bpatch.d.ts +6 -3
- package/api/bpatch.js +5 -3
- package/api/circle.d.ts +4 -3
- package/api/circle.js +9 -6
- package/api/complex-polygon.d.ts +7 -3
- package/api/complex-polygon.js +14 -4
- package/api/cubic.d.ts +8 -5
- package/api/cubic.js +12 -6
- package/api/cubic3.d.ts +15 -0
- package/api/cubic3.js +38 -0
- package/api/ellipse.d.ts +4 -3
- package/api/ellipse.js +7 -8
- package/api/extra.d.ts +15 -0
- package/api/extra.js +19 -0
- package/api/group.d.ts +12 -11
- package/api/group.js +4 -5
- package/api/group3.d.ts +30 -0
- package/api/group3.js +48 -0
- package/api/line.d.ts +8 -5
- package/api/line.js +8 -8
- package/api/line3.d.ts +15 -0
- package/api/line3.js +29 -0
- package/api/path.d.ts +14 -11
- package/api/path.js +17 -12
- package/api/path3.d.ts +28 -0
- package/api/path3.js +91 -0
- package/api/plane.d.ts +4 -3
- package/api/plane.js +7 -4
- package/api/points.d.ts +8 -10
- package/api/points.js +7 -20
- package/api/points3.d.ts +13 -0
- package/api/points3.js +21 -0
- package/api/polygon.d.ts +7 -4
- package/api/polygon.js +5 -3
- package/api/polygon3.d.ts +14 -0
- package/api/polygon3.js +24 -0
- package/api/polyline.d.ts +18 -4
- package/api/polyline.js +8 -5
- package/api/polyline3.d.ts +28 -0
- package/api/polyline3.js +31 -0
- package/api/quad.d.ts +7 -4
- package/api/quad.js +5 -3
- package/api/quad3.d.ts +7 -4
- package/api/quad3.js +6 -4
- package/api/quadratic.d.ts +8 -5
- package/api/quadratic.js +12 -6
- package/api/quadratic3.d.ts +15 -0
- package/api/quadratic3.js +38 -0
- package/api/ray.d.ts +4 -3
- package/api/ray.js +6 -7
- package/api/ray3.d.ts +14 -0
- package/api/ray3.js +33 -0
- package/api/rect.d.ts +5 -3
- package/api/rect.js +11 -8
- package/api/sphere.d.ts +4 -3
- package/api/sphere.js +8 -5
- package/api/text.d.ts +4 -3
- package/api/text.js +8 -5
- package/api/triangle.d.ts +7 -4
- package/api/triangle.js +5 -3
- package/api/triangle3.d.ts +14 -0
- package/api/triangle3.js +26 -0
- package/api.d.ts +193 -0
- package/api.js +10 -0
- package/apply-transforms.d.ts +33 -11
- package/apply-transforms.js +24 -4
- package/arc-length.d.ts +18 -4
- package/arc-length.js +18 -3
- package/arc.d.ts +1 -1
- package/area.d.ts +6 -10
- package/area.js +3 -3
- package/as-cubic.d.ts +31 -5
- package/as-cubic.js +86 -24
- package/as-path.d.ts +14 -7
- package/as-path.js +49 -24
- package/as-polygon.d.ts +20 -5
- package/as-polygon.js +46 -12
- package/as-polyline.d.ts +18 -5
- package/as-polyline.js +29 -23
- package/as-sector.d.ts +13 -0
- package/as-sector.js +18 -0
- package/as-svg.d.ts +31 -9
- package/as-svg.js +21 -18
- package/bounds.d.ts +12 -2
- package/bounds.js +15 -0
- package/bpatch.d.ts +26 -1
- package/center-of-weight.d.ts +22 -0
- package/center-of-weight.js +23 -0
- package/center.d.ts +11 -5
- package/center.js +9 -4
- package/centroid-of-bounds.d.ts +12 -0
- package/centroid-of-bounds.js +9 -0
- package/centroid.d.ts +14 -4
- package/centroid.js +16 -17
- package/circle.d.ts +1 -1
- package/classify-point.d.ts +3 -1
- package/classify-point.js +7 -4
- package/clip-convex.d.ts +27 -8
- package/clip-convex.js +52 -17
- package/closest-point.d.ts +1 -1
- package/complex-polygon-from-path.d.ts +1 -1
- package/complex-polygon.d.ts +1 -1
- package/convex-hull.d.ts +9 -2
- package/convex-hull.js +3 -3
- package/convolve.d.ts +72 -0
- package/convolve.js +33 -0
- package/cubic.d.ts +1 -1
- package/cubic.js +7 -7
- package/cubic3.d.ts +8 -0
- package/cubic3.js +14 -0
- package/edges.d.ts +2 -2
- package/ellipse.d.ts +1 -1
- package/extra.d.ts +14 -0
- package/extra.js +5 -0
- package/fit-into-bounds.d.ts +14 -4
- package/fit-into-bounds.js +6 -6
- package/flip.d.ts +21 -5
- package/flip.js +19 -12
- package/from-tessellation.d.ts +54 -0
- package/from-tessellation.js +27 -0
- package/group.d.ts +2 -2
- package/group3.d.ts +16 -0
- package/group3.js +5 -0
- package/index.d.ts +35 -1
- package/index.js +35 -1
- package/internal/bounds.d.ts +3 -4
- package/internal/copy.d.ts +8 -7
- package/internal/copy.js +3 -7
- package/internal/dispatch.d.ts +1 -1
- package/internal/error.d.ts +3 -0
- package/internal/error.js +6 -0
- package/internal/pclike.d.ts +3 -2
- package/internal/pclike.js +6 -0
- package/internal/points-as-shape.d.ts +11 -2
- package/internal/points-as-shape.js +10 -1
- package/internal/split.d.ts +2 -2
- package/internal/split.js +13 -8
- package/internal/transform.d.ts +6 -22
- package/internal/transform.js +2 -21
- package/internal/vertices.d.ts +3 -2
- package/internal/vertices.js +3 -1
- package/intersects.d.ts +5 -4
- package/intersects.js +6 -4
- package/line.d.ts +1 -1
- package/line3.d.ts +6 -0
- package/line3.js +9 -0
- package/map-point.d.ts +1 -1
- package/normalized-path.d.ts +17 -0
- package/normalized-path.js +23 -0
- package/offset.d.ts +16 -2
- package/offset.js +2 -2
- package/package.json +149 -35
- package/path-builder.d.ts +42 -13
- package/path-builder.js +68 -42
- package/path-from-cubics.d.ts +26 -0
- package/path-from-cubics.js +39 -0
- package/path-from-svg.d.ts +1 -1
- package/path-from-svg.js +29 -29
- package/path.d.ts +2 -52
- package/path.js +1 -58
- package/path3.d.ts +16 -0
- package/path3.js +5 -0
- package/plane.d.ts +11 -1
- package/plane.js +3 -0
- package/point-at.d.ts +1 -1
- package/point-inside.d.ts +3 -1
- package/point-inside.js +4 -1
- package/points.d.ts +2 -3
- package/points.js +2 -4
- package/points3.d.ts +5 -0
- package/points3.js +5 -0
- package/polygon.d.ts +5 -5
- package/polygon3.d.ts +5 -0
- package/polygon3.js +5 -0
- package/polyline.d.ts +2 -2
- package/polyline3.d.ts +5 -0
- package/polyline3.js +5 -0
- package/proximity.d.ts +5 -3
- package/proximity.js +2 -2
- package/quad.d.ts +2 -7
- package/quad.js +1 -29
- package/quad3.d.ts +8 -0
- package/quad3.js +30 -0
- package/quadratic.d.ts +1 -1
- package/quadratic3.d.ts +7 -0
- package/quadratic3.js +11 -0
- package/ray.d.ts +1 -1
- package/ray.js +2 -2
- package/ray3.d.ts +5 -0
- package/ray3.js +6 -0
- package/rect.d.ts +1 -1
- package/resample.d.ts +45 -4
- package/resample.js +26 -16
- package/rotate-around-axis.d.ts +33 -0
- package/rotate-around-axis.js +57 -0
- package/rotate.d.ts +15 -2
- package/rotate.js +47 -45
- package/rounded-rect.d.ts +25 -0
- package/rounded-rect.js +18 -0
- package/scale-with-center.d.ts +2 -2
- package/scale.d.ts +24 -2
- package/scale.js +59 -43
- package/scatter.d.ts +1 -1
- package/simplify.d.ts +8 -2
- package/simplify.js +7 -4
- package/smooth-poly.d.ts +27 -0
- package/smooth-poly.js +11 -0
- package/sphere.d.ts +1 -1
- package/split-arclength.d.ts +6 -2
- package/split-at.d.ts +18 -2
- package/split-at.js +66 -34
- package/split-near.d.ts +13 -2
- package/split-near.js +23 -27
- package/subdiv-curve.d.ts +81 -27
- package/subdiv-curve.js +44 -28
- package/tangent-at.d.ts +1 -1
- package/tessellate.d.ts +72 -18
- package/tessellate.js +53 -8
- package/text.d.ts +1 -1
- package/transform-vertices.d.ts +30 -6
- package/transform-vertices.js +36 -38
- package/transform.d.ts +30 -2
- package/transform.js +54 -40
- package/translate.d.ts +12 -2
- package/translate.js +42 -43
- package/triangle.d.ts +1 -1
- package/triangle3.d.ts +6 -0
- package/triangle3.js +8 -0
- package/union.d.ts +11 -2
- package/union.js +6 -7
- package/unmap-point.d.ts +1 -1
- package/vertices.d.ts +3 -3
- package/vertices.js +14 -4
- package/volume.d.ts +1 -1
- package/warp-points.d.ts +35 -4
- package/warp-points.js +2 -0
- package/with-attribs.d.ts +4 -5
- package/internal/rotate.d.ts +0 -5
- package/internal/rotate.js +0 -8
- package/internal/scale.d.ts +0 -5
- package/internal/scale.js +0 -12
- package/internal/translate.d.ts +0 -5
- package/internal/translate.js +0 -8
package/path-builder.js
CHANGED
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
import { peek } from "@thi.ng/arrays/peek";
|
|
2
|
+
import { unsupported } from "@thi.ng/errors/unsupported";
|
|
2
3
|
import { eqDelta } from "@thi.ng/math/eqdelta";
|
|
3
|
-
import {
|
|
4
|
+
import { add } from "@thi.ng/vectors/add";
|
|
4
5
|
import { copy } from "@thi.ng/vectors/copy";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { eqDelta as eqDeltaV } from "@thi.ng/vectors/eqdelta";
|
|
7
|
+
import { mulN } from "@thi.ng/vectors/muln";
|
|
8
|
+
import { set } from "@thi.ng/vectors/set";
|
|
8
9
|
import { zeroes } from "@thi.ng/vectors/setn";
|
|
9
|
-
import {
|
|
10
|
+
import { sub } from "@thi.ng/vectors/sub";
|
|
10
11
|
import { Cubic } from "./api/cubic.js";
|
|
12
|
+
import { Cubic3 } from "./api/cubic3.js";
|
|
11
13
|
import { Line } from "./api/line.js";
|
|
14
|
+
import { Line3 } from "./api/line3.js";
|
|
12
15
|
import { Path } from "./api/path.js";
|
|
16
|
+
import { Path3 } from "./api/path3.js";
|
|
13
17
|
import { Quadratic } from "./api/quadratic.js";
|
|
18
|
+
import { Quadratic3 } from "./api/quadratic3.js";
|
|
14
19
|
import { arcFrom2Points } from "./arc.js";
|
|
20
|
+
const P2D = {
|
|
21
|
+
path: Path,
|
|
22
|
+
a: arcFrom2Points,
|
|
23
|
+
c: Cubic,
|
|
24
|
+
l: Line,
|
|
25
|
+
q: Quadratic
|
|
26
|
+
};
|
|
27
|
+
const P3D = {
|
|
28
|
+
path: Path3,
|
|
29
|
+
c: Cubic3,
|
|
30
|
+
l: Line3,
|
|
31
|
+
q: Quadratic3
|
|
32
|
+
};
|
|
15
33
|
class PathBuilder {
|
|
16
|
-
constructor(attribs, opts = {}) {
|
|
34
|
+
constructor(ctors, attribs, opts = {}) {
|
|
35
|
+
this.ctors = ctors;
|
|
17
36
|
this.attribs = attribs;
|
|
18
37
|
this.opts = opts;
|
|
19
38
|
this.paths = [];
|
|
@@ -42,36 +61,40 @@ class PathBuilder {
|
|
|
42
61
|
* will only act on this new path.
|
|
43
62
|
*/
|
|
44
63
|
newPath() {
|
|
45
|
-
this.curr = new
|
|
64
|
+
this.curr = new this.ctors.path(
|
|
46
65
|
[],
|
|
47
66
|
[],
|
|
48
67
|
this.attribs ? { ...this.attribs } : void 0
|
|
49
68
|
);
|
|
50
69
|
this.paths.push(this.curr);
|
|
51
|
-
|
|
52
|
-
this.
|
|
53
|
-
this.
|
|
70
|
+
const dim = this.curr.dim;
|
|
71
|
+
this.currP = zeroes(dim);
|
|
72
|
+
this.bezierP = zeroes(dim);
|
|
73
|
+
this.startP = zeroes(dim);
|
|
54
74
|
}
|
|
55
75
|
moveTo(p, relative = false) {
|
|
56
76
|
if (this.opts.autoSplit !== false && this.curr.segments.length > 0) {
|
|
57
|
-
this.curr = new
|
|
77
|
+
this.curr = new this.ctors.path([], [], this.attribs);
|
|
58
78
|
this.paths.push(this.curr);
|
|
59
79
|
}
|
|
60
80
|
p = this.updateCurrent(p, relative);
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
set(this.startP, p);
|
|
82
|
+
set(this.bezierP, p);
|
|
63
83
|
this.curr.addSegments({
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
type: "m",
|
|
85
|
+
point: p
|
|
66
86
|
});
|
|
67
87
|
return this;
|
|
68
88
|
}
|
|
69
89
|
lineTo(p, relative = false) {
|
|
70
90
|
this.curr.addSegments({
|
|
71
|
-
|
|
72
|
-
|
|
91
|
+
type: "l",
|
|
92
|
+
geo: new this.ctors.l([
|
|
93
|
+
copy(this.currP),
|
|
94
|
+
this.updateCurrent(p, relative)
|
|
95
|
+
])
|
|
73
96
|
});
|
|
74
|
-
|
|
97
|
+
set(this.bezierP, this.currP);
|
|
75
98
|
return this;
|
|
76
99
|
}
|
|
77
100
|
hlineTo(x, relative = false) {
|
|
@@ -95,89 +118,92 @@ class PathBuilder {
|
|
|
95
118
|
cubicChainTo(cp2, p, relative = false) {
|
|
96
119
|
const prevMode = peek(this.curr.segments).type;
|
|
97
120
|
const c1 = copy(this.currP);
|
|
98
|
-
prevMode === "c" &&
|
|
121
|
+
prevMode === "c" && add(null, sub([], c1, this.bezierP), c1);
|
|
99
122
|
this.addCubic(c1, cp2, p, relative);
|
|
100
123
|
return this;
|
|
101
124
|
}
|
|
102
125
|
quadraticChainTo(p, relative = false) {
|
|
103
126
|
const prevMode = peek(this.curr.segments).type;
|
|
104
127
|
const c1 = copy(this.currP);
|
|
105
|
-
prevMode === "q" &&
|
|
128
|
+
prevMode === "q" && sub(null, mulN(null, c1, 2), this.bezierP);
|
|
106
129
|
this.addQuadratic(c1, p, relative);
|
|
107
130
|
return this;
|
|
108
131
|
}
|
|
109
132
|
arcTo(p, r, xaxis, xl, clockwise, relative = false) {
|
|
133
|
+
if (!this.ctors.a) unsupported("arcs");
|
|
110
134
|
if (eqDelta(r[0], 0) || eqDelta(r[1], 0)) {
|
|
111
135
|
return this.lineTo(p, relative);
|
|
112
136
|
}
|
|
113
137
|
const prev = copy(this.currP);
|
|
114
138
|
this.curr.addSegments({
|
|
115
|
-
|
|
139
|
+
type: "a",
|
|
140
|
+
geo: this.ctors.a(
|
|
116
141
|
prev,
|
|
117
142
|
this.updateCurrent(p, relative),
|
|
118
143
|
r,
|
|
119
144
|
xaxis,
|
|
120
145
|
xl,
|
|
121
146
|
clockwise
|
|
122
|
-
)
|
|
123
|
-
type: "a"
|
|
147
|
+
)
|
|
124
148
|
});
|
|
125
|
-
|
|
149
|
+
set(this.bezierP, this.currP);
|
|
126
150
|
return this;
|
|
127
151
|
}
|
|
128
152
|
close() {
|
|
129
|
-
if (!
|
|
153
|
+
if (!eqDeltaV(this.startP, this.currP)) {
|
|
130
154
|
this.curr.addSegments({
|
|
131
|
-
|
|
132
|
-
|
|
155
|
+
type: "l",
|
|
156
|
+
geo: new this.ctors.l([copy(this.currP), copy(this.startP)])
|
|
133
157
|
});
|
|
134
158
|
}
|
|
135
159
|
this.curr.close();
|
|
136
160
|
return this;
|
|
137
161
|
}
|
|
138
162
|
updateCurrent(p, relative) {
|
|
139
|
-
p = copy(relative ?
|
|
163
|
+
p = copy(relative ? add(null, this.currP, p) : set(this.currP, p));
|
|
140
164
|
return p;
|
|
141
165
|
}
|
|
142
166
|
absPoint(p, relative) {
|
|
143
|
-
return relative ?
|
|
167
|
+
return relative ? add(null, p, this.currP) : p;
|
|
144
168
|
}
|
|
145
169
|
addHVLine(p, i, relative) {
|
|
146
170
|
const prev = copy(this.currP);
|
|
147
171
|
this.currP[i] = relative ? this.currP[i] + p : p;
|
|
148
|
-
|
|
172
|
+
set(this.bezierP, this.currP);
|
|
149
173
|
this.curr.addSegments({
|
|
150
|
-
|
|
151
|
-
|
|
174
|
+
type: "l",
|
|
175
|
+
geo: new this.ctors.l([prev, copy(this.currP)])
|
|
152
176
|
});
|
|
153
177
|
}
|
|
154
178
|
addCubic(cp1, cp2, p, relative) {
|
|
155
179
|
cp2 = this.absPoint(cp2, relative);
|
|
156
|
-
|
|
180
|
+
set(this.bezierP, cp2);
|
|
157
181
|
this.curr.addSegments({
|
|
158
|
-
|
|
182
|
+
type: "c",
|
|
183
|
+
geo: new this.ctors.c([
|
|
159
184
|
copy(this.currP),
|
|
160
185
|
cp1,
|
|
161
186
|
cp2,
|
|
162
187
|
this.updateCurrent(p, relative)
|
|
163
|
-
])
|
|
164
|
-
type: "c"
|
|
188
|
+
])
|
|
165
189
|
});
|
|
166
190
|
}
|
|
167
191
|
addQuadratic(cp, p, relative) {
|
|
168
|
-
|
|
192
|
+
set(this.bezierP, cp);
|
|
169
193
|
this.curr.addSegments({
|
|
170
|
-
|
|
194
|
+
type: "q",
|
|
195
|
+
geo: new this.ctors.q([
|
|
171
196
|
copy(this.currP),
|
|
172
197
|
cp,
|
|
173
198
|
this.updateCurrent(p, relative)
|
|
174
|
-
])
|
|
175
|
-
type: "q"
|
|
199
|
+
])
|
|
176
200
|
});
|
|
177
201
|
}
|
|
178
202
|
}
|
|
179
|
-
const pathBuilder = (attribs, opts) => new PathBuilder(attribs, opts);
|
|
203
|
+
const pathBuilder = (attribs, opts) => new PathBuilder(P2D, attribs, opts);
|
|
204
|
+
const pathBuilder3 = (attribs, opts) => new PathBuilder(P3D, attribs, opts);
|
|
180
205
|
export {
|
|
181
206
|
PathBuilder,
|
|
182
|
-
pathBuilder
|
|
207
|
+
pathBuilder,
|
|
208
|
+
pathBuilder3
|
|
183
209
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Attribs } from "./api.js";
|
|
2
|
+
import type { Cubic } from "./api/cubic.js";
|
|
3
|
+
import type { Cubic3 } from "./api/cubic3.js";
|
|
4
|
+
import { Path } from "./api/path.js";
|
|
5
|
+
import { Path3 } from "./api/path3.js";
|
|
6
|
+
/**
|
|
7
|
+
* Constructs a {@link Path} or {@link Path3} from given sequence of cubic
|
|
8
|
+
* curves, with optional `attribs`.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* If no `attribs` are given, those from the first curve will be used (if any).
|
|
12
|
+
*
|
|
13
|
+
* For each successive curve segment, if the start point of the current curve is
|
|
14
|
+
* not the same as the last point of the previous curve, a new sub path will be
|
|
15
|
+
* started.
|
|
16
|
+
*
|
|
17
|
+
* The path will automatically be closed if possible.
|
|
18
|
+
*
|
|
19
|
+
* Also see {@link normalizedPath}.
|
|
20
|
+
*
|
|
21
|
+
* @param cubics
|
|
22
|
+
* @param attribs
|
|
23
|
+
*/
|
|
24
|
+
export declare function pathFromCubics(cubics: Cubic[], attribs?: Attribs): Path;
|
|
25
|
+
export declare function pathFromCubics(cubics: Cubic3[], attribs?: Attribs): Path3;
|
|
26
|
+
//# sourceMappingURL=path-from-cubics.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { peek } from "@thi.ng/arrays/peek";
|
|
2
|
+
import { eqDelta } from "@thi.ng/vectors/eqdelta";
|
|
3
|
+
import { equals } from "@thi.ng/vectors/equals";
|
|
4
|
+
import { Path } from "./api/path.js";
|
|
5
|
+
import { Path3 } from "./api/path3.js";
|
|
6
|
+
function pathFromCubics(cubics, attribs) {
|
|
7
|
+
return __pathFromCubics(
|
|
8
|
+
cubics[0].dim === 2 ? Path : Path3,
|
|
9
|
+
cubics,
|
|
10
|
+
attribs
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
const __pathFromCubics = (ctor, cubics, attribs) => {
|
|
14
|
+
let subPaths = [];
|
|
15
|
+
let curr;
|
|
16
|
+
let lastP;
|
|
17
|
+
const $beginPath = (c) => {
|
|
18
|
+
curr = [{ type: "m", point: c.points[0] }];
|
|
19
|
+
subPaths.push(curr);
|
|
20
|
+
};
|
|
21
|
+
for (let c of cubics) {
|
|
22
|
+
if (!(lastP && equals(lastP, c.points[0]))) $beginPath(c);
|
|
23
|
+
curr.push({ type: "c", geo: c });
|
|
24
|
+
lastP = c.points[3];
|
|
25
|
+
}
|
|
26
|
+
const path = new ctor(
|
|
27
|
+
subPaths[0],
|
|
28
|
+
subPaths.slice(1),
|
|
29
|
+
attribs || cubics[0].attribs
|
|
30
|
+
);
|
|
31
|
+
const segments = path.segments;
|
|
32
|
+
if (segments.length > 1 && eqDelta(segments[0].point, peek(peek(segments).geo.points))) {
|
|
33
|
+
path.close();
|
|
34
|
+
}
|
|
35
|
+
return path;
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
pathFromCubics
|
|
39
|
+
};
|
package/path-from-svg.d.ts
CHANGED
package/path-from-svg.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { illegalState } from "@thi.ng/errors/illegal-state";
|
|
2
2
|
import { rad } from "@thi.ng/math/angle";
|
|
3
3
|
import { WS } from "@thi.ng/strings/groups";
|
|
4
|
-
import {
|
|
4
|
+
import { pathBuilder } from "./path-builder.js";
|
|
5
5
|
const CMD_RE = /[achlmqstvz]/i;
|
|
6
6
|
const WSC = { ...WS, ",": true };
|
|
7
7
|
const pathFromSvg = (svg, attribs) => {
|
|
8
|
-
const b =
|
|
8
|
+
const b = pathBuilder(attribs);
|
|
9
9
|
try {
|
|
10
10
|
let cmd = "";
|
|
11
11
|
for (let n = svg.length, i = 0; i < n; ) {
|
|
12
|
-
i =
|
|
12
|
+
i = __skipWS(svg, i);
|
|
13
13
|
const c = svg.charAt(i);
|
|
14
14
|
if (CMD_RE.test(c)) {
|
|
15
15
|
cmd = c;
|
|
@@ -18,47 +18,47 @@ const pathFromSvg = (svg, attribs) => {
|
|
|
18
18
|
let p, pa, pb, t1, t2, t3;
|
|
19
19
|
switch (cmd.toLowerCase()) {
|
|
20
20
|
case "m":
|
|
21
|
-
[p, i] =
|
|
21
|
+
[p, i] = __readPoint(svg, i);
|
|
22
22
|
b.moveTo(p, cmd === "m");
|
|
23
23
|
break;
|
|
24
24
|
case "l":
|
|
25
|
-
[p, i] =
|
|
25
|
+
[p, i] = __readPoint(svg, i);
|
|
26
26
|
b.lineTo(p, cmd === "l");
|
|
27
27
|
break;
|
|
28
28
|
case "h":
|
|
29
|
-
[p, i] =
|
|
29
|
+
[p, i] = __readFloat(svg, i);
|
|
30
30
|
b.hlineTo(p, cmd === "h");
|
|
31
31
|
break;
|
|
32
32
|
case "v":
|
|
33
|
-
[p, i] =
|
|
33
|
+
[p, i] = __readFloat(svg, i);
|
|
34
34
|
b.vlineTo(p, cmd === "v");
|
|
35
35
|
break;
|
|
36
36
|
case "q":
|
|
37
|
-
[pa, i] =
|
|
38
|
-
[p, i] =
|
|
37
|
+
[pa, i] = __readPoint(svg, i);
|
|
38
|
+
[p, i] = __readPoint(svg, i);
|
|
39
39
|
b.quadraticTo(pa, p, cmd === "q");
|
|
40
40
|
break;
|
|
41
41
|
case "c":
|
|
42
|
-
[pa, i] =
|
|
43
|
-
[pb, i] =
|
|
44
|
-
[p, i] =
|
|
42
|
+
[pa, i] = __readPoint(svg, i);
|
|
43
|
+
[pb, i] = __readPoint(svg, i);
|
|
44
|
+
[p, i] = __readPoint(svg, i);
|
|
45
45
|
b.cubicTo(pa, pb, p, cmd === "c");
|
|
46
46
|
break;
|
|
47
47
|
case "s":
|
|
48
|
-
[pa, i] =
|
|
49
|
-
[p, i] =
|
|
48
|
+
[pa, i] = __readPoint(svg, i);
|
|
49
|
+
[p, i] = __readPoint(svg, i);
|
|
50
50
|
b.cubicChainTo(pa, p, cmd === "s");
|
|
51
51
|
break;
|
|
52
52
|
case "t":
|
|
53
|
-
[p, i] =
|
|
53
|
+
[p, i] = __readPoint(svg, i);
|
|
54
54
|
b.quadraticChainTo(p, cmd === "t");
|
|
55
55
|
break;
|
|
56
56
|
case "a": {
|
|
57
|
-
[pa, i] =
|
|
58
|
-
[t1, i] =
|
|
59
|
-
[t2, i] =
|
|
60
|
-
[t3, i] =
|
|
61
|
-
[pb, i] =
|
|
57
|
+
[pa, i] = __readPoint(svg, i);
|
|
58
|
+
[t1, i] = __readFloat(svg, i);
|
|
59
|
+
[t2, i] = __readFlag(svg, i);
|
|
60
|
+
[t3, i] = __readFlag(svg, i);
|
|
61
|
+
[pb, i] = __readPoint(svg, i);
|
|
62
62
|
b.arcTo(pb, pa, rad(t1), t2, t3, cmd === "a");
|
|
63
63
|
break;
|
|
64
64
|
}
|
|
@@ -77,28 +77,28 @@ const pathFromSvg = (svg, attribs) => {
|
|
|
77
77
|
throw e instanceof Error ? e : new Error(`illegal char '${svg.charAt(e)}' @ ${e}`);
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
const
|
|
80
|
+
const __skipWS = (src, i) => {
|
|
81
81
|
const n = src.length;
|
|
82
82
|
while (i < n && WSC[src.charAt(i)]) i++;
|
|
83
83
|
return i;
|
|
84
84
|
};
|
|
85
|
-
const
|
|
85
|
+
const __readPoint = (src, index) => {
|
|
86
86
|
let x, y;
|
|
87
|
-
[x, index] =
|
|
88
|
-
index =
|
|
89
|
-
[y, index] =
|
|
87
|
+
[x, index] = __readFloat(src, index);
|
|
88
|
+
index = __skipWS(src, index);
|
|
89
|
+
[y, index] = __readFloat(src, index);
|
|
90
90
|
return [[x, y], index];
|
|
91
91
|
};
|
|
92
|
-
const
|
|
93
|
-
i =
|
|
92
|
+
const __readFlag = (src, i) => {
|
|
93
|
+
i = __skipWS(src, i);
|
|
94
94
|
const c = src.charAt(i);
|
|
95
95
|
return [
|
|
96
96
|
c === "0" ? false : c === "1" ? true : illegalState(`expected '0' or '1' @ pos: ${i}`),
|
|
97
97
|
i + 1
|
|
98
98
|
];
|
|
99
99
|
};
|
|
100
|
-
const
|
|
101
|
-
index =
|
|
100
|
+
const __readFloat = (src, index) => {
|
|
101
|
+
index = __skipWS(src, index);
|
|
102
102
|
let signOk = true;
|
|
103
103
|
let dotOk = true;
|
|
104
104
|
let expOk = false;
|
package/path.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { Attribs,
|
|
2
|
-
import type { Vec } from "@thi.ng/vectors";
|
|
3
|
-
import type { Cubic } from "./api/cubic.js";
|
|
1
|
+
import type { Attribs, PathSegment2 } from "./api.js";
|
|
4
2
|
import { Path } from "./api/path.js";
|
|
5
3
|
/**
|
|
6
4
|
* Creates a new {@link Path} instance, optional with given `segments`,
|
|
@@ -14,53 +12,5 @@ import { Path } from "./api/path.js";
|
|
|
14
12
|
* @param subPaths
|
|
15
13
|
* @param attribs
|
|
16
14
|
*/
|
|
17
|
-
export declare const path: (segments?: Iterable<
|
|
18
|
-
/**
|
|
19
|
-
* Constructs a {@link Path} from given sequence of cubic curves, with optional
|
|
20
|
-
* `attribs`.
|
|
21
|
-
*
|
|
22
|
-
* @remarks
|
|
23
|
-
* If no `attribs` are given, those from the first curve will be used.
|
|
24
|
-
*
|
|
25
|
-
* For each successive curve segment, if the start point of the current curve is
|
|
26
|
-
* not the same as the last point of the previous curve, a new sub path will be
|
|
27
|
-
* started.
|
|
28
|
-
*
|
|
29
|
-
* Also see {@link normalizedPath}.
|
|
30
|
-
*
|
|
31
|
-
* @param cubics
|
|
32
|
-
* @param attribs
|
|
33
|
-
*/
|
|
34
|
-
export declare const pathFromCubics: (cubics: Cubic[], attribs?: Attribs) => Path;
|
|
35
|
-
/**
|
|
36
|
-
* Converts given path into a new one with all segments converted to
|
|
37
|
-
* {@link Cubic} bezier segments.
|
|
38
|
-
*
|
|
39
|
-
* @remarks
|
|
40
|
-
* Also see {@link pathFromCubics}.
|
|
41
|
-
*
|
|
42
|
-
* @param path
|
|
43
|
-
*/
|
|
44
|
-
export declare const normalizedPath: (path: Path) => Path;
|
|
45
|
-
/**
|
|
46
|
-
* Creates a new rounded rect {@link Path}, using the given corner radius or
|
|
47
|
-
* radii.
|
|
48
|
-
*
|
|
49
|
-
* @remarks
|
|
50
|
-
* If multiple `radii` are given, the interpretation logic is the same as:
|
|
51
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/roundRect
|
|
52
|
-
*
|
|
53
|
-
* - number: all corners
|
|
54
|
-
* - `[top-left-and-bottom-right, top-right-and-bottom-left]`
|
|
55
|
-
* - `[top-left, top-right-and-bottom-left, bottom-right]`
|
|
56
|
-
* - `[top-left, top-right, bottom-right, bottom-left]`
|
|
57
|
-
*
|
|
58
|
-
* No arc segments will be generated for those corners where the radius <= 0
|
|
59
|
-
*
|
|
60
|
-
* @param pos
|
|
61
|
-
* @param size
|
|
62
|
-
* @param radii
|
|
63
|
-
* @param attribs
|
|
64
|
-
*/
|
|
65
|
-
export declare const roundedRect: (pos: Vec, [w, h]: Vec, radii: number | [number, number] | [number, number, number] | [number, number, number, number], attribs?: Attribs) => Path;
|
|
15
|
+
export declare const path: (segments?: Iterable<PathSegment2>, subPaths?: Iterable<PathSegment2[]>, attribs?: Attribs) => Path;
|
|
66
16
|
//# sourceMappingURL=path.d.ts.map
|
package/path.js
CHANGED
|
@@ -1,62 +1,5 @@
|
|
|
1
|
-
import { isNumber } from "@thi.ng/checks/is-number";
|
|
2
|
-
import { map } from "@thi.ng/transducers/map";
|
|
3
|
-
import { mapcat } from "@thi.ng/transducers/mapcat";
|
|
4
|
-
import { equals2 } from "@thi.ng/vectors/equals";
|
|
5
1
|
import { Path } from "./api/path.js";
|
|
6
|
-
import { asCubic } from "./as-cubic.js";
|
|
7
|
-
import { PathBuilder } from "./path-builder.js";
|
|
8
2
|
const path = (segments, subPaths, attribs) => new Path(segments, subPaths, attribs);
|
|
9
|
-
const pathFromCubics = (cubics, attribs) => {
|
|
10
|
-
let subPaths = [];
|
|
11
|
-
let curr;
|
|
12
|
-
let lastP;
|
|
13
|
-
const $beginPath = (c) => {
|
|
14
|
-
curr = [{ type: "m", point: c.points[0] }];
|
|
15
|
-
subPaths.push(curr);
|
|
16
|
-
};
|
|
17
|
-
for (let c of cubics) {
|
|
18
|
-
if (!(lastP && equals2(lastP, c.points[0]))) $beginPath(c);
|
|
19
|
-
curr.push({ type: "c", geo: c });
|
|
20
|
-
lastP = c.points[3];
|
|
21
|
-
}
|
|
22
|
-
const path2 = new Path(
|
|
23
|
-
subPaths[0],
|
|
24
|
-
subPaths.slice(1),
|
|
25
|
-
attribs || cubics[0].attribs
|
|
26
|
-
);
|
|
27
|
-
return path2;
|
|
28
|
-
};
|
|
29
|
-
const normalizedPath = (path2) => {
|
|
30
|
-
const $normalize = (segments) => [
|
|
31
|
-
...mapcat(
|
|
32
|
-
(s) => s.geo ? map(
|
|
33
|
-
(c) => ({ type: "c", geo: c }),
|
|
34
|
-
asCubic(s.geo)
|
|
35
|
-
) : [{ ...s }],
|
|
36
|
-
segments
|
|
37
|
-
)
|
|
38
|
-
];
|
|
39
|
-
return new Path(
|
|
40
|
-
$normalize(path2.segments),
|
|
41
|
-
path2.subPaths.map($normalize),
|
|
42
|
-
path2.attribs
|
|
43
|
-
);
|
|
44
|
-
};
|
|
45
|
-
const roundedRect = (pos, [w, h], radii, attribs) => {
|
|
46
|
-
const [tl, tr, br, bl] = isNumber(radii) ? [radii, radii, radii, radii] : radii.length === 2 ? [radii[0], radii[1], radii[0], radii[1]] : radii.length === 3 ? [radii[0], radii[1], radii[2], radii[1]] : radii;
|
|
47
|
-
const b = new PathBuilder(attribs).moveTo([pos[0] + tl, pos[1]]).hlineTo(w - tl - tr, true);
|
|
48
|
-
if (tr > 0) b.arcTo([tr, tr], [tr, tr], 0, false, true, true);
|
|
49
|
-
b.vlineTo(h - tr - br, true);
|
|
50
|
-
if (br > 0) b.arcTo([-br, br], [br, br], 0, false, true, true);
|
|
51
|
-
b.hlineTo(-(w - br - bl), true);
|
|
52
|
-
if (bl > 0) b.arcTo([-bl, -bl], [bl, bl], 0, false, true, true);
|
|
53
|
-
b.vlineTo(-(h - bl - tl), true);
|
|
54
|
-
if (tl > 0) b.arcTo([tl, -tl], [tl, tl], 0, false, true, true);
|
|
55
|
-
return b.current().close();
|
|
56
|
-
};
|
|
57
3
|
export {
|
|
58
|
-
|
|
59
|
-
path,
|
|
60
|
-
pathFromCubics,
|
|
61
|
-
roundedRect
|
|
4
|
+
path
|
|
62
5
|
};
|
package/path3.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Attribs, PathSegment3 } from "./api.js";
|
|
2
|
+
import { Path3 } from "./api/path3.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new {@link Path3} instance, optional with given `segments`,
|
|
5
|
+
* `subPaths` and `attribs`.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Segments and sub-paths can also be later added via {@link Path3.addSegments}
|
|
9
|
+
* or {@link Path3.addSubPaths}.
|
|
10
|
+
*
|
|
11
|
+
* @param segments
|
|
12
|
+
* @param subPaths
|
|
13
|
+
* @param attribs
|
|
14
|
+
*/
|
|
15
|
+
export declare const path3: (segments?: Iterable<PathSegment3>, subPaths?: Iterable<PathSegment3[]>, attribs?: Attribs) => Path3;
|
|
16
|
+
//# sourceMappingURL=path3.d.ts.map
|
package/path3.js
ADDED
package/plane.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import type { Attribs } from "
|
|
1
|
+
import type { Attribs } from "./api.js";
|
|
2
2
|
import type { ReadonlyVec, Vec } from "@thi.ng/vectors";
|
|
3
3
|
import { Plane } from "./api/plane.js";
|
|
4
|
+
import type { Ray3 } from "./api/ray3.js";
|
|
4
5
|
export declare const plane: (normal: Vec, w: number, attribs?: Attribs) => Plane;
|
|
5
6
|
export declare const planeWithPoint: (normal: Vec, p: ReadonlyVec, attribs?: Attribs) => Plane;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new plane from the given ray, using the ray's position as point on
|
|
9
|
+
* the plane and the ray's direction as plane normal. If `attribs` are given,
|
|
10
|
+
* they take precedence over the ray's attribs.
|
|
11
|
+
*
|
|
12
|
+
* @param ray
|
|
13
|
+
* @param attribs
|
|
14
|
+
*/
|
|
15
|
+
export declare const planeFromRay: ({ pos, dir, attribs }: Ray3, $attribs?: Attribs) => Plane;
|
|
6
16
|
export declare const planeFrom3Points: (a: ReadonlyVec, b: ReadonlyVec, c: ReadonlyVec, attribs?: Attribs) => Plane;
|
|
7
17
|
//# sourceMappingURL=plane.d.ts.map
|
package/plane.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { dot3 } from "@thi.ng/vectors/dot";
|
|
2
2
|
import { normalize3 } from "@thi.ng/vectors/normalize";
|
|
3
3
|
import { orthoNormal3 } from "@thi.ng/vectors/ortho-normal";
|
|
4
|
+
import { set3 } from "@thi.ng/vectors/set";
|
|
4
5
|
import { Plane } from "./api/plane.js";
|
|
5
6
|
const plane = (normal, w, attribs) => new Plane(normalize3(null, normal), w, attribs);
|
|
6
7
|
const planeWithPoint = (normal, p, attribs) => {
|
|
7
8
|
normal = normalize3(null, normal);
|
|
8
9
|
return new Plane(normal, dot3(normal, p), attribs);
|
|
9
10
|
};
|
|
11
|
+
const planeFromRay = ({ pos, dir, attribs }, $attribs) => new Plane(set3([], dir), dot3(dir, pos), $attribs || attribs);
|
|
10
12
|
const planeFrom3Points = (a, b, c, attribs) => planeWithPoint(orthoNormal3([], a, b, c), a, attribs);
|
|
11
13
|
export {
|
|
12
14
|
plane,
|
|
13
15
|
planeFrom3Points,
|
|
16
|
+
planeFromRay,
|
|
14
17
|
planeWithPoint
|
|
15
18
|
};
|
package/point-at.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Maybe } from "@thi.ng/api";
|
|
2
2
|
import type { MultiFn2 } from "@thi.ng/defmulti";
|
|
3
|
-
import type { IShape } from "
|
|
3
|
+
import type { IShape } from "./api.js";
|
|
4
4
|
import type { Vec } from "@thi.ng/vectors";
|
|
5
5
|
/**
|
|
6
6
|
* Samples and returns point on the boundary of given 2D shape at normalized
|
package/point-inside.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MultiFn2 } from "@thi.ng/defmulti";
|
|
2
|
-
import type { IShape } from "
|
|
2
|
+
import type { IShape } from "./api.js";
|
|
3
3
|
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
4
4
|
/**
|
|
5
5
|
* Returns true if point `p` is inside the given shape.
|
|
@@ -10,6 +10,8 @@ import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
|
10
10
|
* - {@link AABB}
|
|
11
11
|
* - {@link Circle}
|
|
12
12
|
* - {@link ComplexPolygon}
|
|
13
|
+
* - {@link Group}
|
|
14
|
+
* - {@link Group3}
|
|
13
15
|
* - {@link Line} (if `p` is on line segment)
|
|
14
16
|
* - {@link Points} (i.e. if `p` is one of the points in the cloud)
|
|
15
17
|
* - {@link Points3} (same as w/ Points)
|
package/point-inside.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defmulti } from "@thi.ng/defmulti/defmulti";
|
|
1
|
+
import { DEFAULT, defmulti } from "@thi.ng/defmulti/defmulti";
|
|
2
2
|
import {
|
|
3
3
|
pointInAABB,
|
|
4
4
|
pointInCircle,
|
|
@@ -13,14 +13,17 @@ import { __dispatch } from "./internal/dispatch.js";
|
|
|
13
13
|
const pointInside = defmulti(
|
|
14
14
|
__dispatch,
|
|
15
15
|
{
|
|
16
|
+
group3: "group",
|
|
16
17
|
points3: "points",
|
|
17
18
|
quad: "poly",
|
|
18
19
|
sphere: "circle"
|
|
19
20
|
},
|
|
20
21
|
{
|
|
22
|
+
[DEFAULT]: () => false,
|
|
21
23
|
aabb: ($, p) => pointInAABB(p, $.pos, $.size),
|
|
22
24
|
circle: ($, p) => pointInCircle(p, $.pos, $.r),
|
|
23
25
|
complexpoly: ($, p) => pointInPolygon2(p, $.boundary.points) ? !$.children.some((child) => pointInPolygon2(p, child.points)) : false,
|
|
26
|
+
group: ($, p) => $.children.some((child) => pointInside(child, p)),
|
|
24
27
|
line: ($, p) => pointInSegment(p, $.points[0], $.points[1]),
|
|
25
28
|
points: ({ points }, p) => isInArray(p, points),
|
|
26
29
|
poly: ($, p) => pointInPolygon2(p, $.points) > 0,
|
package/points.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { Attribs } from "
|
|
1
|
+
import type { Attribs } from "./api.js";
|
|
2
2
|
import type { Vec } from "@thi.ng/vectors";
|
|
3
|
-
import { Points
|
|
3
|
+
import { Points } from "./api/points.js";
|
|
4
4
|
export declare const points: (pts?: Iterable<Vec>, attribs?: Attribs) => Points;
|
|
5
|
-
export declare const points3: (pts?: Iterable<Vec>, attribs?: Attribs) => Points3;
|
|
6
5
|
//# sourceMappingURL=points.d.ts.map
|
package/points.js
CHANGED