@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.
Files changed (251) hide show
  1. package/CHANGELOG.md +190 -1
  2. package/README.md +349 -112
  3. package/aabb.d.ts +26 -1
  4. package/api/aabb.d.ts +5 -4
  5. package/api/aabb.js +10 -7
  6. package/api/apc.d.ts +5 -3
  7. package/api/arc.d.ts +6 -5
  8. package/api/arc.js +3 -4
  9. package/api/bpatch.d.ts +6 -3
  10. package/api/bpatch.js +5 -3
  11. package/api/circle.d.ts +4 -3
  12. package/api/circle.js +9 -6
  13. package/api/complex-polygon.d.ts +7 -3
  14. package/api/complex-polygon.js +14 -4
  15. package/api/cubic.d.ts +8 -5
  16. package/api/cubic.js +12 -6
  17. package/api/cubic3.d.ts +15 -0
  18. package/api/cubic3.js +38 -0
  19. package/api/ellipse.d.ts +4 -3
  20. package/api/ellipse.js +7 -8
  21. package/api/extra.d.ts +15 -0
  22. package/api/extra.js +19 -0
  23. package/api/group.d.ts +12 -11
  24. package/api/group.js +4 -5
  25. package/api/group3.d.ts +30 -0
  26. package/api/group3.js +48 -0
  27. package/api/line.d.ts +8 -5
  28. package/api/line.js +8 -8
  29. package/api/line3.d.ts +15 -0
  30. package/api/line3.js +29 -0
  31. package/api/path.d.ts +14 -11
  32. package/api/path.js +17 -12
  33. package/api/path3.d.ts +28 -0
  34. package/api/path3.js +91 -0
  35. package/api/plane.d.ts +4 -3
  36. package/api/plane.js +7 -4
  37. package/api/points.d.ts +8 -10
  38. package/api/points.js +7 -20
  39. package/api/points3.d.ts +13 -0
  40. package/api/points3.js +21 -0
  41. package/api/polygon.d.ts +7 -4
  42. package/api/polygon.js +5 -3
  43. package/api/polygon3.d.ts +14 -0
  44. package/api/polygon3.js +24 -0
  45. package/api/polyline.d.ts +18 -4
  46. package/api/polyline.js +8 -5
  47. package/api/polyline3.d.ts +28 -0
  48. package/api/polyline3.js +31 -0
  49. package/api/quad.d.ts +7 -4
  50. package/api/quad.js +5 -3
  51. package/api/quad3.d.ts +7 -4
  52. package/api/quad3.js +6 -4
  53. package/api/quadratic.d.ts +8 -5
  54. package/api/quadratic.js +12 -6
  55. package/api/quadratic3.d.ts +15 -0
  56. package/api/quadratic3.js +38 -0
  57. package/api/ray.d.ts +4 -3
  58. package/api/ray.js +6 -7
  59. package/api/ray3.d.ts +14 -0
  60. package/api/ray3.js +33 -0
  61. package/api/rect.d.ts +5 -3
  62. package/api/rect.js +11 -8
  63. package/api/sphere.d.ts +4 -3
  64. package/api/sphere.js +8 -5
  65. package/api/text.d.ts +4 -3
  66. package/api/text.js +8 -5
  67. package/api/triangle.d.ts +7 -4
  68. package/api/triangle.js +5 -3
  69. package/api/triangle3.d.ts +14 -0
  70. package/api/triangle3.js +26 -0
  71. package/api.d.ts +193 -0
  72. package/api.js +10 -0
  73. package/apply-transforms.d.ts +33 -11
  74. package/apply-transforms.js +24 -4
  75. package/arc-length.d.ts +18 -4
  76. package/arc-length.js +18 -3
  77. package/arc.d.ts +1 -1
  78. package/area.d.ts +6 -10
  79. package/area.js +3 -3
  80. package/as-cubic.d.ts +31 -5
  81. package/as-cubic.js +86 -24
  82. package/as-path.d.ts +14 -7
  83. package/as-path.js +49 -24
  84. package/as-polygon.d.ts +20 -5
  85. package/as-polygon.js +46 -12
  86. package/as-polyline.d.ts +18 -5
  87. package/as-polyline.js +29 -23
  88. package/as-sector.d.ts +13 -0
  89. package/as-sector.js +18 -0
  90. package/as-svg.d.ts +31 -9
  91. package/as-svg.js +21 -18
  92. package/bounds.d.ts +12 -2
  93. package/bounds.js +15 -0
  94. package/bpatch.d.ts +26 -1
  95. package/center-of-weight.d.ts +22 -0
  96. package/center-of-weight.js +23 -0
  97. package/center.d.ts +11 -5
  98. package/center.js +9 -4
  99. package/centroid-of-bounds.d.ts +12 -0
  100. package/centroid-of-bounds.js +9 -0
  101. package/centroid.d.ts +14 -4
  102. package/centroid.js +16 -17
  103. package/circle.d.ts +1 -1
  104. package/classify-point.d.ts +3 -1
  105. package/classify-point.js +7 -4
  106. package/clip-convex.d.ts +27 -8
  107. package/clip-convex.js +52 -17
  108. package/closest-point.d.ts +1 -1
  109. package/complex-polygon-from-path.d.ts +1 -1
  110. package/complex-polygon.d.ts +1 -1
  111. package/convex-hull.d.ts +9 -2
  112. package/convex-hull.js +3 -3
  113. package/convolve.d.ts +72 -0
  114. package/convolve.js +33 -0
  115. package/cubic.d.ts +1 -1
  116. package/cubic.js +7 -7
  117. package/cubic3.d.ts +8 -0
  118. package/cubic3.js +14 -0
  119. package/edges.d.ts +2 -2
  120. package/ellipse.d.ts +1 -1
  121. package/extra.d.ts +14 -0
  122. package/extra.js +5 -0
  123. package/fit-into-bounds.d.ts +14 -4
  124. package/fit-into-bounds.js +6 -6
  125. package/flip.d.ts +21 -5
  126. package/flip.js +19 -12
  127. package/from-tessellation.d.ts +54 -0
  128. package/from-tessellation.js +27 -0
  129. package/group.d.ts +2 -2
  130. package/group3.d.ts +16 -0
  131. package/group3.js +5 -0
  132. package/index.d.ts +35 -1
  133. package/index.js +35 -1
  134. package/internal/bounds.d.ts +3 -4
  135. package/internal/copy.d.ts +8 -7
  136. package/internal/copy.js +3 -7
  137. package/internal/dispatch.d.ts +1 -1
  138. package/internal/error.d.ts +3 -0
  139. package/internal/error.js +6 -0
  140. package/internal/pclike.d.ts +3 -2
  141. package/internal/pclike.js +6 -0
  142. package/internal/points-as-shape.d.ts +11 -2
  143. package/internal/points-as-shape.js +10 -1
  144. package/internal/split.d.ts +2 -2
  145. package/internal/split.js +13 -8
  146. package/internal/transform.d.ts +6 -22
  147. package/internal/transform.js +2 -21
  148. package/internal/vertices.d.ts +3 -2
  149. package/internal/vertices.js +3 -1
  150. package/intersects.d.ts +5 -4
  151. package/intersects.js +6 -4
  152. package/line.d.ts +1 -1
  153. package/line3.d.ts +6 -0
  154. package/line3.js +9 -0
  155. package/map-point.d.ts +1 -1
  156. package/normalized-path.d.ts +17 -0
  157. package/normalized-path.js +23 -0
  158. package/offset.d.ts +16 -2
  159. package/offset.js +2 -2
  160. package/package.json +149 -35
  161. package/path-builder.d.ts +42 -13
  162. package/path-builder.js +68 -42
  163. package/path-from-cubics.d.ts +26 -0
  164. package/path-from-cubics.js +39 -0
  165. package/path-from-svg.d.ts +1 -1
  166. package/path-from-svg.js +29 -29
  167. package/path.d.ts +2 -52
  168. package/path.js +1 -58
  169. package/path3.d.ts +16 -0
  170. package/path3.js +5 -0
  171. package/plane.d.ts +11 -1
  172. package/plane.js +3 -0
  173. package/point-at.d.ts +1 -1
  174. package/point-inside.d.ts +3 -1
  175. package/point-inside.js +4 -1
  176. package/points.d.ts +2 -3
  177. package/points.js +2 -4
  178. package/points3.d.ts +5 -0
  179. package/points3.js +5 -0
  180. package/polygon.d.ts +5 -5
  181. package/polygon3.d.ts +5 -0
  182. package/polygon3.js +5 -0
  183. package/polyline.d.ts +2 -2
  184. package/polyline3.d.ts +5 -0
  185. package/polyline3.js +5 -0
  186. package/proximity.d.ts +5 -3
  187. package/proximity.js +2 -2
  188. package/quad.d.ts +2 -7
  189. package/quad.js +1 -29
  190. package/quad3.d.ts +8 -0
  191. package/quad3.js +30 -0
  192. package/quadratic.d.ts +1 -1
  193. package/quadratic3.d.ts +7 -0
  194. package/quadratic3.js +11 -0
  195. package/ray.d.ts +1 -1
  196. package/ray.js +2 -2
  197. package/ray3.d.ts +5 -0
  198. package/ray3.js +6 -0
  199. package/rect.d.ts +1 -1
  200. package/resample.d.ts +45 -4
  201. package/resample.js +26 -16
  202. package/rotate-around-axis.d.ts +33 -0
  203. package/rotate-around-axis.js +57 -0
  204. package/rotate.d.ts +15 -2
  205. package/rotate.js +47 -45
  206. package/rounded-rect.d.ts +25 -0
  207. package/rounded-rect.js +18 -0
  208. package/scale-with-center.d.ts +2 -2
  209. package/scale.d.ts +24 -2
  210. package/scale.js +59 -43
  211. package/scatter.d.ts +1 -1
  212. package/simplify.d.ts +8 -2
  213. package/simplify.js +7 -4
  214. package/smooth-poly.d.ts +27 -0
  215. package/smooth-poly.js +11 -0
  216. package/sphere.d.ts +1 -1
  217. package/split-arclength.d.ts +6 -2
  218. package/split-at.d.ts +18 -2
  219. package/split-at.js +66 -34
  220. package/split-near.d.ts +13 -2
  221. package/split-near.js +23 -27
  222. package/subdiv-curve.d.ts +81 -27
  223. package/subdiv-curve.js +44 -28
  224. package/tangent-at.d.ts +1 -1
  225. package/tessellate.d.ts +72 -18
  226. package/tessellate.js +53 -8
  227. package/text.d.ts +1 -1
  228. package/transform-vertices.d.ts +30 -6
  229. package/transform-vertices.js +36 -38
  230. package/transform.d.ts +30 -2
  231. package/transform.js +54 -40
  232. package/translate.d.ts +12 -2
  233. package/translate.js +42 -43
  234. package/triangle.d.ts +1 -1
  235. package/triangle3.d.ts +6 -0
  236. package/triangle3.js +8 -0
  237. package/union.d.ts +11 -2
  238. package/union.js +6 -7
  239. package/unmap-point.d.ts +1 -1
  240. package/vertices.d.ts +3 -3
  241. package/vertices.js +14 -4
  242. package/volume.d.ts +1 -1
  243. package/warp-points.d.ts +35 -4
  244. package/warp-points.js +2 -0
  245. package/with-attribs.d.ts +4 -5
  246. package/internal/rotate.d.ts +0 -5
  247. package/internal/rotate.js +0 -8
  248. package/internal/scale.d.ts +0 -5
  249. package/internal/scale.js +0 -12
  250. package/internal/translate.d.ts +0 -5
  251. 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 { add2 } from "@thi.ng/vectors/add";
4
+ import { add } from "@thi.ng/vectors/add";
4
5
  import { copy } from "@thi.ng/vectors/copy";
5
- import { eqDelta2 } from "@thi.ng/vectors/eqdelta";
6
- import { mulN2 } from "@thi.ng/vectors/muln";
7
- import { set2 } from "@thi.ng/vectors/set";
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 { sub2 } from "@thi.ng/vectors/sub";
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 Path(
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
- this.currP = zeroes(2);
52
- this.bezierP = zeroes(2);
53
- this.startP = zeroes(2);
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 Path([], [], this.attribs);
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
- set2(this.startP, p);
62
- set2(this.bezierP, p);
81
+ set(this.startP, p);
82
+ set(this.bezierP, p);
63
83
  this.curr.addSegments({
64
- point: p,
65
- type: "m"
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
- geo: new Line([copy(this.currP), this.updateCurrent(p, relative)]),
72
- type: "l"
91
+ type: "l",
92
+ geo: new this.ctors.l([
93
+ copy(this.currP),
94
+ this.updateCurrent(p, relative)
95
+ ])
73
96
  });
74
- set2(this.bezierP, this.currP);
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" && add2(null, sub2([], c1, this.bezierP), c1);
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" && sub2(null, mulN2(null, c1, 2), this.bezierP);
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
- geo: arcFrom2Points(
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
- set2(this.bezierP, this.currP);
149
+ set(this.bezierP, this.currP);
126
150
  return this;
127
151
  }
128
152
  close() {
129
- if (!eqDelta2(this.startP, this.currP)) {
153
+ if (!eqDeltaV(this.startP, this.currP)) {
130
154
  this.curr.addSegments({
131
- geo: new Line([copy(this.currP), copy(this.startP)]),
132
- type: "l"
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 ? add2(null, this.currP, p) : set2(this.currP, p));
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 ? add2(null, p, this.currP) : p;
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
- set2(this.bezierP, this.currP);
172
+ set(this.bezierP, this.currP);
149
173
  this.curr.addSegments({
150
- geo: new Line([prev, copy(this.currP)]),
151
- type: "l"
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
- set2(this.bezierP, cp2);
180
+ set(this.bezierP, cp2);
157
181
  this.curr.addSegments({
158
- geo: new Cubic([
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
- set2(this.bezierP, cp);
192
+ set(this.bezierP, cp);
169
193
  this.curr.addSegments({
170
- geo: new Quadratic([
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
+ };
@@ -1,4 +1,4 @@
1
- import type { Attribs } from "@thi.ng/geom-api";
1
+ import type { Attribs } from "./api.js";
2
2
  /**
3
3
  * Takes a SVG path string and parses it into a {@link Path} shape, optionally
4
4
  * with given attributes.
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 { PathBuilder } from "./path-builder.js";
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 = new PathBuilder(attribs);
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 = skipWS(svg, 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] = readPoint(svg, i);
21
+ [p, i] = __readPoint(svg, i);
22
22
  b.moveTo(p, cmd === "m");
23
23
  break;
24
24
  case "l":
25
- [p, i] = readPoint(svg, i);
25
+ [p, i] = __readPoint(svg, i);
26
26
  b.lineTo(p, cmd === "l");
27
27
  break;
28
28
  case "h":
29
- [p, i] = readFloat(svg, i);
29
+ [p, i] = __readFloat(svg, i);
30
30
  b.hlineTo(p, cmd === "h");
31
31
  break;
32
32
  case "v":
33
- [p, i] = readFloat(svg, i);
33
+ [p, i] = __readFloat(svg, i);
34
34
  b.vlineTo(p, cmd === "v");
35
35
  break;
36
36
  case "q":
37
- [pa, i] = readPoint(svg, i);
38
- [p, i] = readPoint(svg, 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] = readPoint(svg, i);
43
- [pb, i] = readPoint(svg, i);
44
- [p, i] = readPoint(svg, 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] = readPoint(svg, i);
49
- [p, i] = readPoint(svg, 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] = readPoint(svg, i);
53
+ [p, i] = __readPoint(svg, i);
54
54
  b.quadraticChainTo(p, cmd === "t");
55
55
  break;
56
56
  case "a": {
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);
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 skipWS = (src, i) => {
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 readPoint = (src, index) => {
85
+ const __readPoint = (src, index) => {
86
86
  let x, y;
87
- [x, index] = readFloat(src, index);
88
- index = skipWS(src, index);
89
- [y, index] = readFloat(src, 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 readFlag = (src, i) => {
93
- i = skipWS(src, 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 readFloat = (src, index) => {
101
- index = skipWS(src, 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, PathSegment } from "@thi.ng/geom-api";
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<PathSegment>, subPaths?: Iterable<PathSegment[]>, attribs?: Attribs) => Path;
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
- normalizedPath,
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
@@ -0,0 +1,5 @@
1
+ import { Path3 } from "./api/path3.js";
2
+ const path3 = (segments, subPaths, attribs) => new Path3(segments, subPaths, attribs);
3
+ export {
4
+ path3
5
+ };
package/plane.d.ts CHANGED
@@ -1,7 +1,17 @@
1
- import type { Attribs } from "@thi.ng/geom-api";
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 "@thi.ng/geom-api";
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 "@thi.ng/geom-api";
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 "@thi.ng/geom-api";
1
+ import type { Attribs } from "./api.js";
2
2
  import type { Vec } from "@thi.ng/vectors";
3
- import { Points, Points3 } from "./api/points.js";
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
@@ -1,7 +1,5 @@
1
- import { Points, Points3 } from "./api/points.js";
1
+ import { Points } from "./api/points.js";
2
2
  const points = (pts, attribs) => new Points(pts, attribs);
3
- const points3 = (pts, attribs) => new Points3(pts, attribs);
4
3
  export {
5
- points,
6
- points3
4
+ points
7
5
  };