@immugio/three-math-extensions 0.2.14 → 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 +59 -3
- package/cjs/Line2D.js +45 -0
- package/cjs/Line3D.js +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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)
|
|
@@ -40,10 +42,17 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
40
42
|
- Update release instructions [`5b41a2e`](https://github.com/Immugio/three-math-extensions/commit/5b41a2ed7e15450dbb6088a7f7ed0031a013badc)
|
|
41
43
|
- Add Polygon to exports [`ed66775`](https://github.com/Immugio/three-math-extensions/commit/ed66775c33e961835b23843222b822cfd9c16b1d)
|
|
42
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)
|
|
43
46
|
- Documentation update [`d5c7a07`](https://github.com/Immugio/three-math-extensions/commit/d5c7a0765f6097f5d3a3be01967d4059f19682fb)
|
|
44
47
|
- Excluded files from build [`ec70614`](https://github.com/Immugio/three-math-extensions/commit/ec70614bc7df7a98f854c7a6693365118e04faf7)
|
|
45
48
|
|
|
46
|
-
## [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)
|
|
47
56
|
|
|
48
57
|
## [0.2.13](https://github.com/Immugio/three-math-extensions/compare/0.2.12...0.2.13) - 2023-08-31
|
|
49
58
|
|
|
@@ -221,15 +230,62 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
221
230
|
|
|
222
231
|
## [0.0.7](https://github.com/Immugio/three-math-extensions/compare/0.0.6...0.0.7) - 2022-11-21
|
|
223
232
|
|
|
224
|
-
## [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
|
|
225
236
|
|
|
226
237
|
### Commits
|
|
227
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)
|
|
228
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)
|
|
229
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)
|
|
230
284
|
- Correct change log version [`c6244bf`](https://github.com/Immugio/three-math-extensions/commit/c6244bf1488ad21bcc5589d1dff62c41d8182d48)
|
|
231
285
|
- Release 0.0.4 - tag pattern 6 [`c1c5454`](https://github.com/Immugio/three-math-extensions/commit/c1c54541ed400e1ad49bf42fe8926cd5293efefd)
|
|
232
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)
|
|
233
289
|
|
|
234
290
|
## 0.0.4 - 2022-11-21
|
|
235
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
|
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
|
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
|
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
|
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";
|