@immugio/three-math-extensions 0.2.13 → 0.2.15
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 +66 -3
- package/cjs/Line2D.js +45 -0
- package/cjs/Line3D.js +12 -10
- package/cjs/MathConstants.js +2 -1
- package/cjs/index.js +4 -1
- package/cjs/isContinuousClosedShape.js +21 -0
- package/esm/Line2D.js +45 -0
- package/esm/Line3D.js +12 -10
- package/esm/MathConstants.js +1 -0
- package/esm/index.js +2 -1
- package/esm/isContinuousClosedShape.js +17 -0
- package/package.json +11 -11
- package/src/Line2D.ts +55 -0
- package/src/Line3D.ts +14 -10
- package/src/MathConstants.ts +2 -1
- package/src/index.ts +3 -2
- package/src/isContinuousClosedShape.ts +24 -0
- package/types/Line2D.d.ts +14 -0
- package/types/Line3D.d.ts +7 -5
- package/types/MathConstants.d.ts +1 -0
- package/types/index.d.ts +2 -1
- package/types/isContinuousClosedShape.d.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,16 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
9
9
|
|
|
10
|
-
## [0.2.
|
|
10
|
+
## [0.2.15](https://github.com/Immugio/three-math-extensions/compare/16.15.10...0.2.15)
|
|
11
11
|
|
|
12
12
|
### Commits
|
|
13
13
|
|
|
14
|
+
- Packages update [`0d85b39`](https://github.com/Immugio/three-math-extensions/commit/0d85b392029f7bbaa5063cd0494e34f593d62ea5)
|
|
14
15
|
- Add eslint [`98e4912`](https://github.com/Immugio/three-math-extensions/commit/98e4912d637b42ba80e2f3267638b43296113019)
|
|
15
16
|
- Update jest packages [`af23b4f`](https://github.com/Immugio/three-math-extensions/commit/af23b4f08154bba3407f05b773865215e7e1cba8)
|
|
16
17
|
- Add Rectangle, update Polygon [`58ee875`](https://github.com/Immugio/three-math-extensions/commit/58ee87539af8f9ade186e5250cba9e01926da514)
|
|
17
18
|
- Add isPointInPolygon [`a59eb4b`](https://github.com/Immugio/three-math-extensions/commit/a59eb4be026f17a3106070ae626a0588cd4f4411)
|
|
18
19
|
- Improve Line2D.closestPointToPoint, add Vec2.signedAngle [`151f214`](https://github.com/Immugio/three-math-extensions/commit/151f21462e0358057ad8e9d75d5782563a1061f6)
|
|
19
20
|
- Improve documentation [`d0fcb51`](https://github.com/Immugio/three-math-extensions/commit/d0fcb5132f127b4382ac5f7291575a061b8ec121)
|
|
21
|
+
- Add isContinuousClosedShape, add Line2D.groupConnectedLines [`4ef8c2f`](https://github.com/Immugio/three-math-extensions/commit/4ef8c2fe83fdc71dd87fee4cbc478ddf0a086442)
|
|
20
22
|
- Vec3, Line3D - update documentation [`67d9c32`](https://github.com/Immugio/three-math-extensions/commit/67d9c328e08cc0a5599932d2f0529e97f31c9213)
|
|
21
23
|
- Add Polygon [`629cff8`](https://github.com/Immugio/three-math-extensions/commit/629cff8ecbb963477e8ea76d7f8b16d95435cbad)
|
|
22
24
|
- Line3D.groupConnectedLines added [`29f372b`](https://github.com/Immugio/three-math-extensions/commit/29f372bc984c06b00c50fcd9428ce9a7b9cab799)
|
|
@@ -27,6 +29,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
27
29
|
- Add Vec2.fromPoints to accept multiple points [`a261402`](https://github.com/Immugio/three-math-extensions/commit/a2614027cf5fb8263189b48f7e0bb9a23a552c15)
|
|
28
30
|
- Add Vec2.parallelTo [`989874d`](https://github.com/Immugio/three-math-extensions/commit/989874dcfe122d3ee84d8d56d79cb88e4e441736)
|
|
29
31
|
- Line2D.intersect - enable line segments intersection only [`1f1470e`](https://github.com/Immugio/three-math-extensions/commit/1f1470e1cf00118e643f5c44a135e0baf6b76d41)
|
|
32
|
+
- Line3D.groupConnectedLines now supports line breaks [`417a9ea`](https://github.com/Immugio/three-math-extensions/commit/417a9ea471bf4c539f73f5fb170c962a78ee4ab4)
|
|
30
33
|
- Add Line2D.projectOn [`4c52c5c`](https://github.com/Immugio/three-math-extensions/commit/4c52c5c2e649fbddb72ce3fca60cfd3f1319f72f)
|
|
31
34
|
- Add Line3D.index [`7ed13d2`](https://github.com/Immugio/three-math-extensions/commit/7ed13d213748056c9dafd86288c3bcec9a28d1ba)
|
|
32
35
|
- Polygon from bounding size [`eae6701`](https://github.com/Immugio/three-math-extensions/commit/eae67012f57f426f8b5259b765000447ce06d608)
|
|
@@ -39,10 +42,23 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
39
42
|
- Update release instructions [`5b41a2e`](https://github.com/Immugio/three-math-extensions/commit/5b41a2ed7e15450dbb6088a7f7ed0031a013badc)
|
|
40
43
|
- Add Polygon to exports [`ed66775`](https://github.com/Immugio/three-math-extensions/commit/ed66775c33e961835b23843222b822cfd9c16b1d)
|
|
41
44
|
- Vec2.fromPoint and Vec3.fromPoint should accept null [`4b871af`](https://github.com/Immugio/three-math-extensions/commit/4b871af297bdcbe8584f1e2b99d602247b77687c)
|
|
45
|
+
- Add HalfPI [`7a6614c`](https://github.com/Immugio/three-math-extensions/commit/7a6614c3d6f59ac216e58986927112f94207a755)
|
|
42
46
|
- Documentation update [`d5c7a07`](https://github.com/Immugio/three-math-extensions/commit/d5c7a0765f6097f5d3a3be01967d4059f19682fb)
|
|
43
47
|
- Excluded files from build [`ec70614`](https://github.com/Immugio/three-math-extensions/commit/ec70614bc7df7a98f854c7a6693365118e04faf7)
|
|
44
48
|
|
|
45
|
-
## [16.15.10](https://github.com/Immugio/three-math-extensions/compare/0.2.
|
|
49
|
+
## [16.15.10](https://github.com/Immugio/three-math-extensions/compare/0.2.14...16.15.10) - 2023-01-02
|
|
50
|
+
|
|
51
|
+
## [0.2.14](https://github.com/Immugio/three-math-extensions/compare/0.2.13...0.2.14) - 2023-08-31
|
|
52
|
+
|
|
53
|
+
### Commits
|
|
54
|
+
|
|
55
|
+
- Line3D.groupConnectedLines now supports line breaks [`417a9ea`](https://github.com/Immugio/three-math-extensions/commit/417a9ea471bf4c539f73f5fb170c962a78ee4ab4)
|
|
56
|
+
|
|
57
|
+
## [0.2.13](https://github.com/Immugio/three-math-extensions/compare/0.2.12...0.2.13) - 2023-08-31
|
|
58
|
+
|
|
59
|
+
### Commits
|
|
60
|
+
|
|
61
|
+
- Line3D.connectsTo added [`6d2cfa0`](https://github.com/Immugio/three-math-extensions/commit/6d2cfa0f5335c665f325a694a32c57b574ec326d)
|
|
46
62
|
|
|
47
63
|
## [0.2.12](https://github.com/Immugio/three-math-extensions/compare/0.2.11...0.2.12) - 2023-08-30
|
|
48
64
|
|
|
@@ -214,15 +230,62 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
214
230
|
|
|
215
231
|
## [0.0.7](https://github.com/Immugio/three-math-extensions/compare/0.0.6...0.0.7) - 2022-11-21
|
|
216
232
|
|
|
217
|
-
## [0.0.6](https://github.com/Immugio/three-math-extensions/compare/0.0.
|
|
233
|
+
## [0.0.6](https://github.com/Immugio/three-math-extensions/compare/0.0.5...0.0.6) - 2022-11-24
|
|
234
|
+
|
|
235
|
+
## [0.0.5](https://github.com/Immugio/three-math-extensions/compare/0.0.4...0.0.5) - 2023-09-01
|
|
218
236
|
|
|
219
237
|
### Commits
|
|
220
238
|
|
|
239
|
+
- Generate documentation using TSDoc [`304c3a8`](https://github.com/Immugio/three-math-extensions/commit/304c3a84b5dcc49183db57083f550d134ae641b2)
|
|
240
|
+
- Add eslint [`98e4912`](https://github.com/Immugio/three-math-extensions/commit/98e4912d637b42ba80e2f3267638b43296113019)
|
|
241
|
+
- Update jest packages [`af23b4f`](https://github.com/Immugio/three-math-extensions/commit/af23b4f08154bba3407f05b773865215e7e1cba8)
|
|
242
|
+
- Add Rectangle, update Polygon [`58ee875`](https://github.com/Immugio/three-math-extensions/commit/58ee87539af8f9ade186e5250cba9e01926da514)
|
|
243
|
+
- Add isPointInPolygon [`a59eb4b`](https://github.com/Immugio/three-math-extensions/commit/a59eb4be026f17a3106070ae626a0588cd4f4411)
|
|
244
|
+
- Improve Line2D.closestPointToPoint, add Vec2.signedAngle [`151f214`](https://github.com/Immugio/three-math-extensions/commit/151f21462e0358057ad8e9d75d5782563a1061f6)
|
|
245
|
+
- Improve documentation [`d0fcb51`](https://github.com/Immugio/three-math-extensions/commit/d0fcb5132f127b4382ac5f7291575a061b8ec121)
|
|
246
|
+
- Vec3, Line3D - update documentation [`67d9c32`](https://github.com/Immugio/three-math-extensions/commit/67d9c328e08cc0a5599932d2f0529e97f31c9213)
|
|
247
|
+
- Add Polygon [`629cff8`](https://github.com/Immugio/three-math-extensions/commit/629cff8ecbb963477e8ea76d7f8b16d95435cbad)
|
|
221
248
|
- Improve API, minor bug fix, improve test coverage [`881a5f0`](https://github.com/Immugio/three-math-extensions/commit/881a5f096823f0d5fd90faa76cd602f076291bc5)
|
|
249
|
+
- Line3D.groupConnectedLines added [`29f372b`](https://github.com/Immugio/three-math-extensions/commit/29f372bc984c06b00c50fcd9428ce9a7b9cab799)
|
|
250
|
+
- Dependencies update and remove now duplicate Vec2.angleTo implementation [`4774abb`](https://github.com/Immugio/three-math-extensions/commit/4774abb81d882082df0da606c79a3c7bd3aecc57)
|
|
251
|
+
- Line2D.isCloserToHorizontal [`b6f1429`](https://github.com/Immugio/three-math-extensions/commit/b6f14292d1d2765f7314c45e4c74be91280ac764)
|
|
252
|
+
- Add Vec2.angleTo and tests [`dcf1e53`](https://github.com/Immugio/three-math-extensions/commit/dcf1e531aecf8c115f323e14e5e44059e5c5d15c)
|
|
253
|
+
- Add Vec2.signedAngle [`863c8f2`](https://github.com/Immugio/three-math-extensions/commit/863c8f27f11288cbda535e21bb688206259269ed)
|
|
254
|
+
- Add intersect method to Line3D [`6fe47de`](https://github.com/Immugio/three-math-extensions/commit/6fe47de7caaa1807b47a4363e551510c463757d7)
|
|
255
|
+
- Add Line2D.extendToOrTrimAtIntersection [`ab82a36`](https://github.com/Immugio/three-math-extensions/commit/ab82a36db52b9ae83cf8bfb848362d295140d073)
|
|
256
|
+
- Add Vec2.fromPoints to accept multiple points [`a261402`](https://github.com/Immugio/three-math-extensions/commit/a2614027cf5fb8263189b48f7e0bb9a23a552c15)
|
|
257
|
+
- Improve documentation for Vec2 and Vec3 [`6a2373d`](https://github.com/Immugio/three-math-extensions/commit/6a2373d8b6754a87720dcaea5d98336bfa7bc5b5)
|
|
258
|
+
- Add Vec2.parallelTo [`989874d`](https://github.com/Immugio/three-math-extensions/commit/989874dcfe122d3ee84d8d56d79cb88e4e441736)
|
|
259
|
+
- Line2D.intersect - enable line segments intersection only [`1f1470e`](https://github.com/Immugio/three-math-extensions/commit/1f1470e1cf00118e643f5c44a135e0baf6b76d41)
|
|
260
|
+
- Line3D.groupConnectedLines now supports line breaks [`417a9ea`](https://github.com/Immugio/three-math-extensions/commit/417a9ea471bf4c539f73f5fb170c962a78ee4ab4)
|
|
261
|
+
- Add Line2D.projectOn [`4c52c5c`](https://github.com/Immugio/three-math-extensions/commit/4c52c5c2e649fbddb72ce3fca60cfd3f1319f72f)
|
|
262
|
+
- Added "isNear" to Vec2 & Vec3 as a shorthand for distanceTo <= maxDistance [`a27cff8`](https://github.com/Immugio/three-math-extensions/commit/a27cff8421472f625ed240439b9e6a7d2c430db8)
|
|
263
|
+
- Add Line3D.index [`7ed13d2`](https://github.com/Immugio/three-math-extensions/commit/7ed13d213748056c9dafd86288c3bcec9a28d1ba)
|
|
222
264
|
- Add .npmignore [`f58329a`](https://github.com/Immugio/three-math-extensions/commit/f58329a86b96589bb574d6ebed37d4cc4474663a)
|
|
265
|
+
- Polygon from bounding size [`eae6701`](https://github.com/Immugio/three-math-extensions/commit/eae67012f57f426f8b5259b765000447ce06d608)
|
|
266
|
+
- Add Vec2 documentation [`f625e66`](https://github.com/Immugio/three-math-extensions/commit/f625e66b60ee0d90c5c788a80989f64013d60265)
|
|
267
|
+
- Clean up documentation [`70c8d5e`](https://github.com/Immugio/three-math-extensions/commit/70c8d5efe8b7095d7a03af637df3af5d46615293)
|
|
268
|
+
- Line2D and Line3D to return this instead of specific type [`761ef6a`](https://github.com/Immugio/three-math-extensions/commit/761ef6a9d8cc4e35120b666576794e521aa3b991)
|
|
269
|
+
- Line2D.in3DSpace added [`a6ce0ec`](https://github.com/Immugio/three-math-extensions/commit/a6ce0ecb67f5c7b2a75fcc283c28af626153a4af)
|
|
270
|
+
- Line3D.connectsTo added [`6d2cfa0`](https://github.com/Immugio/three-math-extensions/commit/6d2cfa0f5335c665f325a694a32c57b574ec326d)
|
|
271
|
+
- Line2D.hasIntersectionWithAngle to support optional tolerance [`b313bbe`](https://github.com/Immugio/three-math-extensions/commit/b313bbe118d435d53750deefd9a9e29ba6ec5c71)
|
|
272
|
+
- Add Vec2.moveTowards [`b46ba12`](https://github.com/Immugio/three-math-extensions/commit/b46ba1286f9924cd9bfecfb37200664202e964ba)
|
|
273
|
+
- Line2D.hasIntersectionWithAngle - modulo all angles [`5409aa0`](https://github.com/Immugio/three-math-extensions/commit/5409aa0bc41510efa86d548e91837e44e5b6c343)
|
|
274
|
+
- Use Vec2 instead of Vector2 [`7e6a6ea`](https://github.com/Immugio/three-math-extensions/commit/7e6a6ea272f4441ef4bc78b3fdec23fc783fa1db)
|
|
275
|
+
- Add release instructions into README.md [`03653b1`](https://github.com/Immugio/three-math-extensions/commit/03653b1ffa55be606d3f9cd588e28a6084462c2e)
|
|
276
|
+
- Documentation improvements [`160db8b`](https://github.com/Immugio/three-math-extensions/commit/160db8ba6d6e5eb63a4e91ed9c40efd6fa70181a)
|
|
277
|
+
- Update release instructions [`5b41a2e`](https://github.com/Immugio/three-math-extensions/commit/5b41a2ed7e15450dbb6088a7f7ed0031a013badc)
|
|
278
|
+
- Add Polygon to exports [`ed66775`](https://github.com/Immugio/three-math-extensions/commit/ed66775c33e961835b23843222b822cfd9c16b1d)
|
|
279
|
+
- Vec2.fromPoint and Vec3.fromPoint should accept null [`4b871af`](https://github.com/Immugio/three-math-extensions/commit/4b871af297bdcbe8584f1e2b99d602247b77687c)
|
|
280
|
+
- Documentation improvements [`2f3e676`](https://github.com/Immugio/three-math-extensions/commit/2f3e6768b3b0139b60688fc151a4084f15566f8d)
|
|
281
|
+
- Documentation update [`d5c7a07`](https://github.com/Immugio/three-math-extensions/commit/d5c7a0765f6097f5d3a3be01967d4059f19682fb)
|
|
282
|
+
- Fix peer dependency version [`00dd116`](https://github.com/Immugio/three-math-extensions/commit/00dd1169f578d5769207031fa625f29c96a38c31)
|
|
283
|
+
- Add Line2D.extendToOrTrimAtIntersection [`b22aa12`](https://github.com/Immugio/three-math-extensions/commit/b22aa120b5eb02562cebc4573374ebb61e2dba14)
|
|
223
284
|
- Correct change log version [`c6244bf`](https://github.com/Immugio/three-math-extensions/commit/c6244bf1488ad21bcc5589d1dff62c41d8182d48)
|
|
224
285
|
- Release 0.0.4 - tag pattern 6 [`c1c5454`](https://github.com/Immugio/three-math-extensions/commit/c1c54541ed400e1ad49bf42fe8926cd5293efefd)
|
|
225
286
|
- Release 0.0.4 - tag pattern 5 [`5245eed`](https://github.com/Immugio/three-math-extensions/commit/5245eed60195103e989c0fadf9bd642f39ef4589)
|
|
287
|
+
- Excluded files from build [`ec70614`](https://github.com/Immugio/three-math-extensions/commit/ec70614bc7df7a98f854c7a6693365118e04faf7)
|
|
288
|
+
- Revert npm ignore [`590b26a`](https://github.com/Immugio/three-math-extensions/commit/590b26a9e57fc41466b51e711f3f5c648e2d56ed)
|
|
226
289
|
|
|
227
290
|
## 0.0.4 - 2022-11-21
|
|
228
291
|
|
package/cjs/Line2D.js
CHANGED
|
@@ -580,6 +580,51 @@ class Line2D {
|
|
|
580
580
|
get isCloserToVertical() {
|
|
581
581
|
return !this.isCloserToHorizontal;
|
|
582
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Accepts an array of Line2D and groups them into arrays of connected lines
|
|
585
|
+
* @param lines Lines to be grouped
|
|
586
|
+
* @param tolerance Tolerance for considering lines as connected
|
|
587
|
+
* @param breakpoints
|
|
588
|
+
*/
|
|
589
|
+
static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
|
|
590
|
+
const visited = new Set();
|
|
591
|
+
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
592
|
+
// Then use Depth-First Search (DFS) to find connected components in the graph.
|
|
593
|
+
const dfs = (line, group) => {
|
|
594
|
+
if (visited.has(line))
|
|
595
|
+
return;
|
|
596
|
+
visited.add(line);
|
|
597
|
+
group.push(line);
|
|
598
|
+
lines.forEach((neighbor) => {
|
|
599
|
+
if (!visited.has(neighbor)) {
|
|
600
|
+
if (line.connectsTo(neighbor, tolerance, breakpoints)) {
|
|
601
|
+
dfs(neighbor, group);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
};
|
|
606
|
+
const connectedLines = [];
|
|
607
|
+
lines.forEach((line) => {
|
|
608
|
+
if (!visited.has(line)) {
|
|
609
|
+
const group = [];
|
|
610
|
+
dfs(line, group);
|
|
611
|
+
connectedLines.push(group);
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
return connectedLines;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
618
|
+
* @param other
|
|
619
|
+
* @param tolerance
|
|
620
|
+
* @param breakpoints
|
|
621
|
+
*/
|
|
622
|
+
connectsTo(other, tolerance = 0, breakpoints = []) {
|
|
623
|
+
return ((this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
624
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
625
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
626
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))));
|
|
627
|
+
}
|
|
583
628
|
/**
|
|
584
629
|
* Project the line to 2D space. For start and end points Vec2.y becomes Vec3.z. and Vec3.y is provided as an argument.
|
|
585
630
|
* @param y - The y value of the new Vec3 instance.
|
package/cjs/Line3D.js
CHANGED
|
@@ -371,8 +371,8 @@ class Line3D extends three_1.Line3 {
|
|
|
371
371
|
}
|
|
372
372
|
/**
|
|
373
373
|
* Calculates the intersection between this and `other` line. The lines are assumed to be infinite.
|
|
374
|
-
* In a lot of cases an actual intersection cannot be calculated due to rounding errors.
|
|
375
|
-
* Therefore, the intersection calculated by this method comes in
|
|
374
|
+
* In a lot of cases, an actual intersection cannot be calculated due to rounding errors.
|
|
375
|
+
* Therefore, the intersection calculated by this method comes in the form of the shorted possible line segment connecting the two lines.
|
|
376
376
|
* Sources:
|
|
377
377
|
* http://paulbourke.net/geometry/pointlineplane/
|
|
378
378
|
* https://stackoverflow.com/questions/2316490/the-algorithm-to-find-the-point-of-intersection-of-two-3d-line-segment/2316934#2316934
|
|
@@ -412,8 +412,9 @@ class Line3D extends three_1.Line3 {
|
|
|
412
412
|
* Accepts an array of Line3D and groups them into arrays of connected lines
|
|
413
413
|
* @param lines Lines to be grouped
|
|
414
414
|
* @param tolerance Tolerance for considering lines as connected
|
|
415
|
+
* @param breakpoints
|
|
415
416
|
*/
|
|
416
|
-
static groupConnectedLines(lines, tolerance = 0) {
|
|
417
|
+
static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
|
|
417
418
|
const visited = new Set();
|
|
418
419
|
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
419
420
|
// Then use Depth-First Search (DFS) to find connected components in the graph.
|
|
@@ -424,7 +425,7 @@ class Line3D extends three_1.Line3 {
|
|
|
424
425
|
group.push(line);
|
|
425
426
|
lines.forEach((neighbor) => {
|
|
426
427
|
if (!visited.has(neighbor)) {
|
|
427
|
-
if (line.connectsTo(neighbor, tolerance)) {
|
|
428
|
+
if (line.connectsTo(neighbor, tolerance, breakpoints)) {
|
|
428
429
|
dfs(neighbor, group);
|
|
429
430
|
}
|
|
430
431
|
}
|
|
@@ -441,15 +442,16 @@ class Line3D extends three_1.Line3 {
|
|
|
441
442
|
return connectedLines;
|
|
442
443
|
}
|
|
443
444
|
/**
|
|
444
|
-
* Returns true if any endpoint of this line
|
|
445
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
445
446
|
* @param other
|
|
446
447
|
* @param tolerance
|
|
448
|
+
* @param breakpoints
|
|
447
449
|
*/
|
|
448
|
-
connectsTo(other, tolerance = 0) {
|
|
449
|
-
return this.start.isNear(other.start, tolerance) ||
|
|
450
|
-
this.start.isNear(other.end, tolerance) ||
|
|
451
|
-
this.end.isNear(other.start, tolerance) ||
|
|
452
|
-
this.end.isNear(other.end, tolerance);
|
|
450
|
+
connectsTo(other, tolerance = 0, breakpoints = []) {
|
|
451
|
+
return ((this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
452
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
453
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
454
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))));
|
|
453
455
|
}
|
|
454
456
|
/**
|
|
455
457
|
* Project the line to 2D space, Y value is dropped
|
package/cjs/MathConstants.js
CHANGED
package/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.directions2d = exports.directions = exports.isPointInPolygon = exports.TwoPI = exports.normalizeAngleRadians = exports.normalizeAngleDegrees = exports.Rectangle = exports.BoundingBox = exports.Polygon = exports.Size2 = exports.Line3D = exports.Line2D = exports.Vec3 = exports.Vec2 = void 0;
|
|
3
|
+
exports.isContinuousClosedShape = exports.directions2d = exports.directions = exports.isPointInPolygon = exports.HalfPI = exports.TwoPI = exports.normalizeAngleRadians = exports.normalizeAngleDegrees = exports.Rectangle = exports.BoundingBox = exports.Polygon = exports.Size2 = exports.Line3D = exports.Line2D = exports.Vec3 = exports.Vec2 = void 0;
|
|
4
4
|
var Vec2_1 = require("./Vec2");
|
|
5
5
|
Object.defineProperty(exports, "Vec2", { enumerable: true, get: function () { return Vec2_1.Vec2; } });
|
|
6
6
|
var Vec3_1 = require("./Vec3");
|
|
@@ -23,9 +23,12 @@ var normalizeAngleRadians_1 = require("./normalizeAngleRadians");
|
|
|
23
23
|
Object.defineProperty(exports, "normalizeAngleRadians", { enumerable: true, get: function () { return normalizeAngleRadians_1.normalizeAngleRadians; } });
|
|
24
24
|
var MathConstants_1 = require("./MathConstants");
|
|
25
25
|
Object.defineProperty(exports, "TwoPI", { enumerable: true, get: function () { return MathConstants_1.TwoPI; } });
|
|
26
|
+
Object.defineProperty(exports, "HalfPI", { enumerable: true, get: function () { return MathConstants_1.HalfPI; } });
|
|
26
27
|
var isPointInPolygon_1 = require("./isPointInPolygon");
|
|
27
28
|
Object.defineProperty(exports, "isPointInPolygon", { enumerable: true, get: function () { return isPointInPolygon_1.isPointInPolygon; } });
|
|
28
29
|
var directions_1 = require("./directions");
|
|
29
30
|
Object.defineProperty(exports, "directions", { enumerable: true, get: function () { return directions_1.directions; } });
|
|
30
31
|
var directions2d_1 = require("./directions2d");
|
|
31
32
|
Object.defineProperty(exports, "directions2d", { enumerable: true, get: function () { return directions2d_1.directions2d; } });
|
|
33
|
+
var isContinuousClosedShape_1 = require("./isContinuousClosedShape");
|
|
34
|
+
Object.defineProperty(exports, "isContinuousClosedShape", { enumerable: true, get: function () { return isContinuousClosedShape_1.isContinuousClosedShape; } });
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isContinuousClosedShape = void 0;
|
|
4
|
+
function isContinuousClosedShape(lines, tolerance = 0) {
|
|
5
|
+
if (lines.length < 3) {
|
|
6
|
+
return false; // A shape needs at least 3 lines to be closed
|
|
7
|
+
}
|
|
8
|
+
// Starting from the first line, check if the end of the current line is the start of the next line
|
|
9
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
10
|
+
const endCurrent = lines[i].end;
|
|
11
|
+
const startNext = lines[i + 1].start;
|
|
12
|
+
if (!endCurrent.isNear(startNext, tolerance)) {
|
|
13
|
+
return false; // If the end of the current line and start of the next line are not close, return false
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Lastly, we should check the end of the last line with the start of the first line
|
|
17
|
+
const endLast = lines[lines.length - 1].end;
|
|
18
|
+
const startFirst = lines[0].start;
|
|
19
|
+
return endLast.isNear(startFirst, tolerance);
|
|
20
|
+
}
|
|
21
|
+
exports.isContinuousClosedShape = isContinuousClosedShape;
|
package/esm/Line2D.js
CHANGED
|
@@ -577,6 +577,51 @@ export class Line2D {
|
|
|
577
577
|
get isCloserToVertical() {
|
|
578
578
|
return !this.isCloserToHorizontal;
|
|
579
579
|
}
|
|
580
|
+
/**
|
|
581
|
+
* Accepts an array of Line2D and groups them into arrays of connected lines
|
|
582
|
+
* @param lines Lines to be grouped
|
|
583
|
+
* @param tolerance Tolerance for considering lines as connected
|
|
584
|
+
* @param breakpoints
|
|
585
|
+
*/
|
|
586
|
+
static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
|
|
587
|
+
const visited = new Set();
|
|
588
|
+
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
589
|
+
// Then use Depth-First Search (DFS) to find connected components in the graph.
|
|
590
|
+
const dfs = (line, group) => {
|
|
591
|
+
if (visited.has(line))
|
|
592
|
+
return;
|
|
593
|
+
visited.add(line);
|
|
594
|
+
group.push(line);
|
|
595
|
+
lines.forEach((neighbor) => {
|
|
596
|
+
if (!visited.has(neighbor)) {
|
|
597
|
+
if (line.connectsTo(neighbor, tolerance, breakpoints)) {
|
|
598
|
+
dfs(neighbor, group);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
};
|
|
603
|
+
const connectedLines = [];
|
|
604
|
+
lines.forEach((line) => {
|
|
605
|
+
if (!visited.has(line)) {
|
|
606
|
+
const group = [];
|
|
607
|
+
dfs(line, group);
|
|
608
|
+
connectedLines.push(group);
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
return connectedLines;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
615
|
+
* @param other
|
|
616
|
+
* @param tolerance
|
|
617
|
+
* @param breakpoints
|
|
618
|
+
*/
|
|
619
|
+
connectsTo(other, tolerance = 0, breakpoints = []) {
|
|
620
|
+
return ((this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
621
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
622
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
623
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))));
|
|
624
|
+
}
|
|
580
625
|
/**
|
|
581
626
|
* Project the line to 2D space. For start and end points Vec2.y becomes Vec3.z. and Vec3.y is provided as an argument.
|
|
582
627
|
* @param y - The y value of the new Vec3 instance.
|
package/esm/Line3D.js
CHANGED
|
@@ -368,8 +368,8 @@ export class Line3D extends Line3 {
|
|
|
368
368
|
}
|
|
369
369
|
/**
|
|
370
370
|
* Calculates the intersection between this and `other` line. The lines are assumed to be infinite.
|
|
371
|
-
* In a lot of cases an actual intersection cannot be calculated due to rounding errors.
|
|
372
|
-
* Therefore, the intersection calculated by this method comes in
|
|
371
|
+
* In a lot of cases, an actual intersection cannot be calculated due to rounding errors.
|
|
372
|
+
* Therefore, the intersection calculated by this method comes in the form of the shorted possible line segment connecting the two lines.
|
|
373
373
|
* Sources:
|
|
374
374
|
* http://paulbourke.net/geometry/pointlineplane/
|
|
375
375
|
* https://stackoverflow.com/questions/2316490/the-algorithm-to-find-the-point-of-intersection-of-two-3d-line-segment/2316934#2316934
|
|
@@ -409,8 +409,9 @@ export class Line3D extends Line3 {
|
|
|
409
409
|
* Accepts an array of Line3D and groups them into arrays of connected lines
|
|
410
410
|
* @param lines Lines to be grouped
|
|
411
411
|
* @param tolerance Tolerance for considering lines as connected
|
|
412
|
+
* @param breakpoints
|
|
412
413
|
*/
|
|
413
|
-
static groupConnectedLines(lines, tolerance = 0) {
|
|
414
|
+
static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
|
|
414
415
|
const visited = new Set();
|
|
415
416
|
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
416
417
|
// Then use Depth-First Search (DFS) to find connected components in the graph.
|
|
@@ -421,7 +422,7 @@ export class Line3D extends Line3 {
|
|
|
421
422
|
group.push(line);
|
|
422
423
|
lines.forEach((neighbor) => {
|
|
423
424
|
if (!visited.has(neighbor)) {
|
|
424
|
-
if (line.connectsTo(neighbor, tolerance)) {
|
|
425
|
+
if (line.connectsTo(neighbor, tolerance, breakpoints)) {
|
|
425
426
|
dfs(neighbor, group);
|
|
426
427
|
}
|
|
427
428
|
}
|
|
@@ -438,15 +439,16 @@ export class Line3D extends Line3 {
|
|
|
438
439
|
return connectedLines;
|
|
439
440
|
}
|
|
440
441
|
/**
|
|
441
|
-
* Returns true if any endpoint of this line
|
|
442
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
442
443
|
* @param other
|
|
443
444
|
* @param tolerance
|
|
445
|
+
* @param breakpoints
|
|
444
446
|
*/
|
|
445
|
-
connectsTo(other, tolerance = 0) {
|
|
446
|
-
return this.start.isNear(other.start, tolerance) ||
|
|
447
|
-
this.start.isNear(other.end, tolerance) ||
|
|
448
|
-
this.end.isNear(other.start, tolerance) ||
|
|
449
|
-
this.end.isNear(other.end, tolerance);
|
|
447
|
+
connectsTo(other, tolerance = 0, breakpoints = []) {
|
|
448
|
+
return ((this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
449
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
450
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
451
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))));
|
|
450
452
|
}
|
|
451
453
|
/**
|
|
452
454
|
* Project the line to 2D space, Y value is dropped
|
package/esm/MathConstants.js
CHANGED
package/esm/index.js
CHANGED
|
@@ -8,7 +8,8 @@ export { BoundingBox } from "./BoundingBox";
|
|
|
8
8
|
export { Rectangle } from "./Rectangle";
|
|
9
9
|
export { normalizeAngleDegrees } from "./normalizeAngleDegrees";
|
|
10
10
|
export { normalizeAngleRadians } from "./normalizeAngleRadians";
|
|
11
|
-
export { TwoPI } from "./MathConstants";
|
|
11
|
+
export { TwoPI, HalfPI } from "./MathConstants";
|
|
12
12
|
export { isPointInPolygon } from "./isPointInPolygon";
|
|
13
13
|
export { directions } from "./directions";
|
|
14
14
|
export { directions2d } from "./directions2d";
|
|
15
|
+
export { isContinuousClosedShape } from "./isContinuousClosedShape";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function isContinuousClosedShape(lines, tolerance = 0) {
|
|
2
|
+
if (lines.length < 3) {
|
|
3
|
+
return false; // A shape needs at least 3 lines to be closed
|
|
4
|
+
}
|
|
5
|
+
// Starting from the first line, check if the end of the current line is the start of the next line
|
|
6
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
7
|
+
const endCurrent = lines[i].end;
|
|
8
|
+
const startNext = lines[i + 1].start;
|
|
9
|
+
if (!endCurrent.isNear(startNext, tolerance)) {
|
|
10
|
+
return false; // If the end of the current line and start of the next line are not close, return false
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// Lastly, we should check the end of the last line with the start of the first line
|
|
14
|
+
const endLast = lines[lines.length - 1].end;
|
|
15
|
+
const startFirst = lines[0].start;
|
|
16
|
+
return endLast.isNear(startFirst, tolerance);
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immugio/three-math-extensions",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "Set of utilities for 2d and 3d line math built on top of three.js",
|
|
5
5
|
"author": "Jan Mikeska <janmikeska@gmail.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
"postversion": "git push && git push --tags"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/jest": "^29.5.
|
|
37
|
-
"@types/offscreencanvas": "2019.7.
|
|
36
|
+
"@types/jest": "^29.5.5",
|
|
37
|
+
"@types/offscreencanvas": "2019.7.1",
|
|
38
38
|
"@types/three": "0.152.0",
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "^6.5
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
|
40
40
|
"auto-changelog": "^2.4.0",
|
|
41
|
-
"jest": "^29.
|
|
42
|
-
"rimraf": "^
|
|
43
|
-
"ts-jest": "^29.
|
|
44
|
-
"typedoc": "^0.
|
|
45
|
-
"typedoc-plugin-markdown": "^3.
|
|
46
|
-
"typescript": "
|
|
47
|
-
"eslint": "^8.
|
|
41
|
+
"jest": "^29.7.0",
|
|
42
|
+
"rimraf": "^5.0.5",
|
|
43
|
+
"ts-jest": "^29.1.1",
|
|
44
|
+
"typedoc": "^0.25.2",
|
|
45
|
+
"typedoc-plugin-markdown": "^3.16.0",
|
|
46
|
+
"typescript": "5.2.2",
|
|
47
|
+
"eslint": "^8.51.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"three": "0.152.2"
|
package/src/Line2D.ts
CHANGED
|
@@ -682,6 +682,61 @@ export class Line2D {
|
|
|
682
682
|
return !this.isCloserToHorizontal;
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
+
/**
|
|
686
|
+
* Accepts an array of Line2D and groups them into arrays of connected lines
|
|
687
|
+
* @param lines Lines to be grouped
|
|
688
|
+
* @param tolerance Tolerance for considering lines as connected
|
|
689
|
+
* @param breakpoints
|
|
690
|
+
*/
|
|
691
|
+
public static groupConnectedLines(lines: Line2D[], tolerance: number = 0, breakpoints: Vec2[] = []): Line2D[][] {
|
|
692
|
+
const visited: Set<Line2D> = new Set();
|
|
693
|
+
|
|
694
|
+
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
695
|
+
// Then use Depth-First Search (DFS) to find connected components in the graph.
|
|
696
|
+
const dfs = (line: Line2D, group: Line2D[]) => {
|
|
697
|
+
if (visited.has(line)) return;
|
|
698
|
+
visited.add(line);
|
|
699
|
+
group.push(line);
|
|
700
|
+
|
|
701
|
+
lines.forEach((neighbor) => {
|
|
702
|
+
if (!visited.has(neighbor)) {
|
|
703
|
+
if (
|
|
704
|
+
line.connectsTo(neighbor, tolerance, breakpoints)
|
|
705
|
+
) {
|
|
706
|
+
dfs(neighbor, group);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
const connectedLines: Line2D[][] = [];
|
|
713
|
+
|
|
714
|
+
lines.forEach((line) => {
|
|
715
|
+
if (!visited.has(line)) {
|
|
716
|
+
const group: Line2D[] = [];
|
|
717
|
+
dfs(line, group);
|
|
718
|
+
connectedLines.push(group);
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
return connectedLines;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
727
|
+
* @param other
|
|
728
|
+
* @param tolerance
|
|
729
|
+
* @param breakpoints
|
|
730
|
+
*/
|
|
731
|
+
public connectsTo(other: Line2D, tolerance: number = 0, breakpoints: typeof other.start[] = []): boolean {
|
|
732
|
+
return (
|
|
733
|
+
(this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
734
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
735
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
736
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance)))
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
685
740
|
/**
|
|
686
741
|
* Project the line to 2D space. For start and end points Vec2.y becomes Vec3.z. and Vec3.y is provided as an argument.
|
|
687
742
|
* @param y - The y value of the new Vec3 instance.
|
package/src/Line3D.ts
CHANGED
|
@@ -446,8 +446,8 @@ export class Line3D extends Line3 {
|
|
|
446
446
|
|
|
447
447
|
/**
|
|
448
448
|
* Calculates the intersection between this and `other` line. The lines are assumed to be infinite.
|
|
449
|
-
* In a lot of cases an actual intersection cannot be calculated due to rounding errors.
|
|
450
|
-
* Therefore, the intersection calculated by this method comes in
|
|
449
|
+
* In a lot of cases, an actual intersection cannot be calculated due to rounding errors.
|
|
450
|
+
* Therefore, the intersection calculated by this method comes in the form of the shorted possible line segment connecting the two lines.
|
|
451
451
|
* Sources:
|
|
452
452
|
* http://paulbourke.net/geometry/pointlineplane/
|
|
453
453
|
* https://stackoverflow.com/questions/2316490/the-algorithm-to-find-the-point-of-intersection-of-two-3d-line-segment/2316934#2316934
|
|
@@ -506,8 +506,9 @@ export class Line3D extends Line3 {
|
|
|
506
506
|
* Accepts an array of Line3D and groups them into arrays of connected lines
|
|
507
507
|
* @param lines Lines to be grouped
|
|
508
508
|
* @param tolerance Tolerance for considering lines as connected
|
|
509
|
+
* @param breakpoints
|
|
509
510
|
*/
|
|
510
|
-
public static groupConnectedLines(lines: Line3D[], tolerance: number = 0): Line3D[][] {
|
|
511
|
+
public static groupConnectedLines(lines: Line3D[], tolerance: number = 0, breakpoints: Vec3[] = []): Line3D[][] {
|
|
511
512
|
const visited: Set<Line3D> = new Set();
|
|
512
513
|
|
|
513
514
|
// Use graph-based approach. Each line can be considered as an edge in the graph, and the endpoints of the lines can be considered as vertices.
|
|
@@ -520,7 +521,7 @@ export class Line3D extends Line3 {
|
|
|
520
521
|
lines.forEach((neighbor) => {
|
|
521
522
|
if (!visited.has(neighbor)) {
|
|
522
523
|
if (
|
|
523
|
-
line.connectsTo(neighbor, tolerance)
|
|
524
|
+
line.connectsTo(neighbor, tolerance, breakpoints)
|
|
524
525
|
) {
|
|
525
526
|
dfs(neighbor, group);
|
|
526
527
|
}
|
|
@@ -542,15 +543,18 @@ export class Line3D extends Line3 {
|
|
|
542
543
|
}
|
|
543
544
|
|
|
544
545
|
/**
|
|
545
|
-
* Returns true if any endpoint of this line
|
|
546
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
546
547
|
* @param other
|
|
547
548
|
* @param tolerance
|
|
549
|
+
* @param breakpoints
|
|
548
550
|
*/
|
|
549
|
-
public connectsTo(other: Line3D, tolerance: number = 0): boolean {
|
|
550
|
-
return
|
|
551
|
-
this.start.isNear(other.
|
|
552
|
-
this.
|
|
553
|
-
this.end.isNear(other.end, tolerance)
|
|
551
|
+
public connectsTo(other: Line3D, tolerance: number = 0, breakpoints: Vec3[] = []): boolean {
|
|
552
|
+
return (
|
|
553
|
+
(this.start.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
554
|
+
(this.start.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.start, tolerance))) ||
|
|
555
|
+
(this.end.isNear(other.start, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance))) ||
|
|
556
|
+
(this.end.isNear(other.end, tolerance) && breakpoints.every(b => !b.isNear(this.end, tolerance)))
|
|
557
|
+
);
|
|
554
558
|
}
|
|
555
559
|
|
|
556
560
|
/**
|
package/src/MathConstants.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export const TwoPI = 2 * Math.PI;
|
|
1
|
+
export const TwoPI = 2 * Math.PI;
|
|
2
|
+
export const HalfPI = Math.PI / 2;
|
package/src/index.ts
CHANGED
|
@@ -8,9 +8,10 @@ export { BoundingBox } from "./BoundingBox";
|
|
|
8
8
|
export { Rectangle } from "./Rectangle";
|
|
9
9
|
export { normalizeAngleDegrees } from "./normalizeAngleDegrees";
|
|
10
10
|
export { normalizeAngleRadians } from "./normalizeAngleRadians";
|
|
11
|
-
export { TwoPI } from "./MathConstants";
|
|
11
|
+
export { TwoPI, HalfPI } from "./MathConstants";
|
|
12
12
|
export { Point2 } from "./Point2";
|
|
13
13
|
export { Point3 } from "./Point3";
|
|
14
14
|
export { isPointInPolygon } from "./isPointInPolygon";
|
|
15
15
|
export { directions } from "./directions";
|
|
16
|
-
export { directions2d } from "./directions2d";
|
|
16
|
+
export { directions2d } from "./directions2d";
|
|
17
|
+
export { isContinuousClosedShape } from "./isContinuousClosedShape";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Line3D } from "./Line3D";
|
|
2
|
+
import { Line2D } from "./Line2D";
|
|
3
|
+
|
|
4
|
+
export function isContinuousClosedShape<T extends Line2D | Line3D>(lines: T[], tolerance: number = 0): boolean {
|
|
5
|
+
if (lines.length < 3) {
|
|
6
|
+
return false; // A shape needs at least 3 lines to be closed
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Starting from the first line, check if the end of the current line is the start of the next line
|
|
10
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
11
|
+
const endCurrent = lines[i].end;
|
|
12
|
+
const startNext = lines[i + 1].start;
|
|
13
|
+
|
|
14
|
+
if (!endCurrent.isNear(startNext as any, tolerance)) {
|
|
15
|
+
return false; // If the end of the current line and start of the next line are not close, return false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Lastly, we should check the end of the last line with the start of the first line
|
|
20
|
+
const endLast = lines[lines.length - 1].end;
|
|
21
|
+
const startFirst = lines[0].start;
|
|
22
|
+
|
|
23
|
+
return endLast.isNear(startFirst as any, tolerance);
|
|
24
|
+
}
|
package/types/Line2D.d.ts
CHANGED
|
@@ -220,6 +220,20 @@ export declare class Line2D {
|
|
|
220
220
|
hasIntersectionWithAngle(other: Line2D, expectedAngleInRads: number, angleTolerance?: number, distanceTolerance?: number): Vec2;
|
|
221
221
|
get isCloserToHorizontal(): boolean;
|
|
222
222
|
get isCloserToVertical(): boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Accepts an array of Line2D and groups them into arrays of connected lines
|
|
225
|
+
* @param lines Lines to be grouped
|
|
226
|
+
* @param tolerance Tolerance for considering lines as connected
|
|
227
|
+
* @param breakpoints
|
|
228
|
+
*/
|
|
229
|
+
static groupConnectedLines(lines: Line2D[], tolerance?: number, breakpoints?: Vec2[]): Line2D[][];
|
|
230
|
+
/**
|
|
231
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
232
|
+
* @param other
|
|
233
|
+
* @param tolerance
|
|
234
|
+
* @param breakpoints
|
|
235
|
+
*/
|
|
236
|
+
connectsTo(other: Line2D, tolerance?: number, breakpoints?: typeof other.start[]): boolean;
|
|
223
237
|
/**
|
|
224
238
|
* Project the line to 2D space. For start and end points Vec2.y becomes Vec3.z. and Vec3.y is provided as an argument.
|
|
225
239
|
* @param y - The y value of the new Vec3 instance.
|
package/types/Line3D.d.ts
CHANGED
|
@@ -138,8 +138,8 @@ export declare class Line3D extends Line3 {
|
|
|
138
138
|
translate(p: Vector3): this;
|
|
139
139
|
/**
|
|
140
140
|
* Calculates the intersection between this and `other` line. The lines are assumed to be infinite.
|
|
141
|
-
* In a lot of cases an actual intersection cannot be calculated due to rounding errors.
|
|
142
|
-
* Therefore, the intersection calculated by this method comes in
|
|
141
|
+
* In a lot of cases, an actual intersection cannot be calculated due to rounding errors.
|
|
142
|
+
* Therefore, the intersection calculated by this method comes in the form of the shorted possible line segment connecting the two lines.
|
|
143
143
|
* Sources:
|
|
144
144
|
* http://paulbourke.net/geometry/pointlineplane/
|
|
145
145
|
* https://stackoverflow.com/questions/2316490/the-algorithm-to-find-the-point-of-intersection-of-two-3d-line-segment/2316934#2316934
|
|
@@ -150,14 +150,16 @@ export declare class Line3D extends Line3 {
|
|
|
150
150
|
* Accepts an array of Line3D and groups them into arrays of connected lines
|
|
151
151
|
* @param lines Lines to be grouped
|
|
152
152
|
* @param tolerance Tolerance for considering lines as connected
|
|
153
|
+
* @param breakpoints
|
|
153
154
|
*/
|
|
154
|
-
static groupConnectedLines(lines: Line3D[], tolerance?: number): Line3D[][];
|
|
155
|
+
static groupConnectedLines(lines: Line3D[], tolerance?: number, breakpoints?: Vec3[]): Line3D[][];
|
|
155
156
|
/**
|
|
156
|
-
* Returns true if any endpoint of this line
|
|
157
|
+
* Returns true if any endpoint of this line is within the tolerance of any @other line's endpoints.
|
|
157
158
|
* @param other
|
|
158
159
|
* @param tolerance
|
|
160
|
+
* @param breakpoints
|
|
159
161
|
*/
|
|
160
|
-
connectsTo(other: Line3D, tolerance?: number): boolean;
|
|
162
|
+
connectsTo(other: Line3D, tolerance?: number, breakpoints?: Vec3[]): boolean;
|
|
161
163
|
/**
|
|
162
164
|
* Project the line to 2D space, Y value is dropped
|
|
163
165
|
*/
|
package/types/MathConstants.d.ts
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -8,9 +8,10 @@ export { BoundingBox } from "./BoundingBox";
|
|
|
8
8
|
export { Rectangle } from "./Rectangle";
|
|
9
9
|
export { normalizeAngleDegrees } from "./normalizeAngleDegrees";
|
|
10
10
|
export { normalizeAngleRadians } from "./normalizeAngleRadians";
|
|
11
|
-
export { TwoPI } from "./MathConstants";
|
|
11
|
+
export { TwoPI, HalfPI } from "./MathConstants";
|
|
12
12
|
export { Point2 } from "./Point2";
|
|
13
13
|
export { Point3 } from "./Point3";
|
|
14
14
|
export { isPointInPolygon } from "./isPointInPolygon";
|
|
15
15
|
export { directions } from "./directions";
|
|
16
16
|
export { directions2d } from "./directions2d";
|
|
17
|
+
export { isContinuousClosedShape } from "./isContinuousClosedShape";
|