@immugio/three-math-extensions 0.2.30 → 0.2.32

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 CHANGED
@@ -7,7 +7,20 @@ 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.30](https://github.com/Immugio/three-math-extensions/compare/0.2.29...0.2.30)
10
+ ## [0.2.32](https://github.com/Immugio/three-math-extensions/compare/0.2.31...0.2.32)
11
+
12
+ ### Commits
13
+
14
+ - Improve offsetPolyline to correctly handle open polylines [`4c5a003`](https://github.com/Immugio/three-math-extensions/commit/4c5a003e9d46fc1ef8a63ec765941232d2dda933)
15
+ - Line2D.groupConnectedLines sorts each group based on connection order [`16e22f9`](https://github.com/Immugio/three-math-extensions/commit/16e22f9adb7df290e36381b198d7f0381dfb1f5c)
16
+
17
+ ## [0.2.31](https://github.com/Immugio/three-math-extensions/compare/0.2.30...0.2.31) - 2024-09-17
18
+
19
+ ### Commits
20
+
21
+ - Add Vec3.applyAxisAngleAroundCenter [`a45aaea`](https://github.com/Immugio/three-math-extensions/commit/a45aaea2b6579e8f94859d1ed29abf81479d3a76)
22
+
23
+ ## [0.2.30](https://github.com/Immugio/three-math-extensions/compare/0.2.29...0.2.30) - 2024-09-12
11
24
 
12
25
  ### Commits
13
26
 
package/cjs/Line2D.js CHANGED
@@ -658,7 +658,7 @@ class Line2D {
658
658
  * Accepts an array of Line2D and groups them into arrays of connected lines
659
659
  * @param lines Lines to be grouped
660
660
  * @param tolerance Tolerance for considering lines as connected
661
- * @param breakpoints
661
+ * @param breakpoints Endpoints on breakpoints are not considered as connected
662
662
  */
663
663
  static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
664
664
  const visited = new Set();
@@ -685,6 +685,18 @@ class Line2D {
685
685
  connectedLines.push(group);
686
686
  }
687
687
  });
688
+ // Sort each group based on connection order
689
+ connectedLines.forEach(group => {
690
+ group.sort((a, b) => {
691
+ if (a.start.isNear(b.start, tolerance) || a.end.isNear(b.start, tolerance)) {
692
+ return -1;
693
+ }
694
+ if (a.start.isNear(b.end, tolerance) || a.end.isNear(b.end, tolerance)) {
695
+ return 1;
696
+ }
697
+ return 0;
698
+ });
699
+ });
688
700
  return connectedLines;
689
701
  }
690
702
  /**
package/cjs/Vec3.js CHANGED
@@ -81,6 +81,15 @@ class Vec3 extends three_1.Vector3 {
81
81
  const closest = withDistances.reduce((a, b) => a.distance < b.distance ? a : b);
82
82
  return Vec3.fromPoint(closest.point);
83
83
  }
84
+ applyAxisAngleAroundCenter(axis, angle, center) {
85
+ // Translate the vector to the origin
86
+ this.sub(center);
87
+ // Apply the axis-angle rotation
88
+ this.applyAxisAngle(axis, angle);
89
+ // Translate the vector back to the original position
90
+ this.add(center);
91
+ return this;
92
+ }
84
93
  roundIfCloseToInteger(max = 0.000000000001) {
85
94
  if (Math.abs(this.x - Math.round(this.x)) < max) {
86
95
  this.x = Math.round(this.x);
@@ -1,16 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.offsetPolyline = void 0;
4
- function offsetPolyline(lines, offset) {
4
+ function offsetPolyline(lines, offset, tolerance = 0) {
5
+ const isClosed = lines[0].start.isNear(lines.at(-1).end, tolerance);
5
6
  for (let i = 0; i < lines.length; i++) {
7
+ const isFirst = i === 0;
8
+ const isLast = i === lines.length - 1;
6
9
  const line = lines[i];
7
10
  line.translateLeft(offset);
8
11
  const next = lines[(i + 1) % lines.length];
9
- line.extendToOrTrimAtIntersection(next);
10
- next.extendToOrTrimAtIntersection(line);
12
+ if (!isLast || isClosed) {
13
+ line.extendToOrTrimAtIntersection(next);
14
+ next.extendToOrTrimAtIntersection(line);
15
+ }
11
16
  const previous = lines[(i + lines.length - 1) % lines.length];
12
- line.extendToOrTrimAtIntersection(previous);
13
- previous.extendToOrTrimAtIntersection(line);
17
+ if (!isFirst || isClosed) {
18
+ line.extendToOrTrimAtIntersection(previous);
19
+ previous.extendToOrTrimAtIntersection(line);
20
+ }
14
21
  }
15
22
  return lines;
16
23
  }
package/esm/Line2D.js CHANGED
@@ -655,7 +655,7 @@ export class Line2D {
655
655
  * Accepts an array of Line2D and groups them into arrays of connected lines
656
656
  * @param lines Lines to be grouped
657
657
  * @param tolerance Tolerance for considering lines as connected
658
- * @param breakpoints
658
+ * @param breakpoints Endpoints on breakpoints are not considered as connected
659
659
  */
660
660
  static groupConnectedLines(lines, tolerance = 0, breakpoints = []) {
661
661
  const visited = new Set();
@@ -682,6 +682,18 @@ export class Line2D {
682
682
  connectedLines.push(group);
683
683
  }
684
684
  });
685
+ // Sort each group based on connection order
686
+ connectedLines.forEach(group => {
687
+ group.sort((a, b) => {
688
+ if (a.start.isNear(b.start, tolerance) || a.end.isNear(b.start, tolerance)) {
689
+ return -1;
690
+ }
691
+ if (a.start.isNear(b.end, tolerance) || a.end.isNear(b.end, tolerance)) {
692
+ return 1;
693
+ }
694
+ return 0;
695
+ });
696
+ });
685
697
  return connectedLines;
686
698
  }
687
699
  /**
package/esm/Vec3.js CHANGED
@@ -78,6 +78,15 @@ export class Vec3 extends Vector3 {
78
78
  const closest = withDistances.reduce((a, b) => a.distance < b.distance ? a : b);
79
79
  return Vec3.fromPoint(closest.point);
80
80
  }
81
+ applyAxisAngleAroundCenter(axis, angle, center) {
82
+ // Translate the vector to the origin
83
+ this.sub(center);
84
+ // Apply the axis-angle rotation
85
+ this.applyAxisAngle(axis, angle);
86
+ // Translate the vector back to the original position
87
+ this.add(center);
88
+ return this;
89
+ }
81
90
  roundIfCloseToInteger(max = 0.000000000001) {
82
91
  if (Math.abs(this.x - Math.round(this.x)) < max) {
83
92
  this.x = Math.round(this.x);
@@ -1,13 +1,20 @@
1
- export function offsetPolyline(lines, offset) {
1
+ export function offsetPolyline(lines, offset, tolerance = 0) {
2
+ const isClosed = lines[0].start.isNear(lines.at(-1).end, tolerance);
2
3
  for (let i = 0; i < lines.length; i++) {
4
+ const isFirst = i === 0;
5
+ const isLast = i === lines.length - 1;
3
6
  const line = lines[i];
4
7
  line.translateLeft(offset);
5
8
  const next = lines[(i + 1) % lines.length];
6
- line.extendToOrTrimAtIntersection(next);
7
- next.extendToOrTrimAtIntersection(line);
9
+ if (!isLast || isClosed) {
10
+ line.extendToOrTrimAtIntersection(next);
11
+ next.extendToOrTrimAtIntersection(line);
12
+ }
8
13
  const previous = lines[(i + lines.length - 1) % lines.length];
9
- line.extendToOrTrimAtIntersection(previous);
10
- previous.extendToOrTrimAtIntersection(line);
14
+ if (!isFirst || isClosed) {
15
+ line.extendToOrTrimAtIntersection(previous);
16
+ previous.extendToOrTrimAtIntersection(line);
17
+ }
11
18
  }
12
19
  return lines;
13
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immugio/three-math-extensions",
3
- "version": "0.2.30",
3
+ "version": "0.2.32",
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",
package/src/Line2D.ts CHANGED
@@ -776,7 +776,7 @@ export class Line2D {
776
776
  * Accepts an array of Line2D and groups them into arrays of connected lines
777
777
  * @param lines Lines to be grouped
778
778
  * @param tolerance Tolerance for considering lines as connected
779
- * @param breakpoints
779
+ * @param breakpoints Endpoints on breakpoints are not considered as connected
780
780
  */
781
781
  public static groupConnectedLines(lines: Line2D[], tolerance: number = 0, breakpoints: Vec2[] = []): Line2D[][] {
782
782
  const visited: Set<Line2D> = new Set();
@@ -790,9 +790,7 @@ export class Line2D {
790
790
 
791
791
  lines.forEach((neighbor) => {
792
792
  if (!visited.has(neighbor)) {
793
- if (
794
- line.connectsTo(neighbor, tolerance, breakpoints)
795
- ) {
793
+ if (line.connectsTo(neighbor, tolerance, breakpoints)) {
796
794
  dfs(neighbor, group);
797
795
  }
798
796
  }
@@ -809,6 +807,19 @@ export class Line2D {
809
807
  }
810
808
  });
811
809
 
810
+ // Sort each group based on connection order
811
+ connectedLines.forEach(group => {
812
+ group.sort((a, b) => {
813
+ if (a.start.isNear(b.start, tolerance) || a.end.isNear(b.start, tolerance)) {
814
+ return -1;
815
+ }
816
+ if (a.start.isNear(b.end, tolerance) || a.end.isNear(b.end, tolerance)) {
817
+ return 1;
818
+ }
819
+ return 0;
820
+ });
821
+ });
822
+
812
823
  return connectedLines;
813
824
  }
814
825
 
package/src/Vec3.ts CHANGED
@@ -94,6 +94,19 @@ export class Vec3 extends Vector3 {
94
94
  return Vec3.fromPoint(closest.point);
95
95
  }
96
96
 
97
+ public applyAxisAngleAroundCenter(axis: Vector3, angle: number, center: Vector3): this {
98
+ // Translate the vector to the origin
99
+ this.sub(center);
100
+
101
+ // Apply the axis-angle rotation
102
+ this.applyAxisAngle(axis, angle);
103
+
104
+ // Translate the vector back to the original position
105
+ this.add(center);
106
+
107
+ return this;
108
+ }
109
+
97
110
  public roundIfCloseToInteger(max: number = 0.000000000001): this {
98
111
  if (Math.abs(this.x - Math.round(this.x)) < max) {
99
112
  this.x = Math.round(this.x);
@@ -1,17 +1,26 @@
1
1
  import { Line2D } from "./Line2D";
2
2
 
3
- export function offsetPolyline(lines: Line2D[], offset: number): Line2D[] {
4
- for (let i = 0; i < lines.length; i++){
3
+ export function offsetPolyline(lines: Line2D[], offset: number, tolerance: number = 0): Line2D[] {
4
+ const isClosed = lines[0].start.isNear(lines.at(-1).end, tolerance);
5
+
6
+ for (let i = 0; i < lines.length; i++) {
7
+ const isFirst = i === 0;
8
+ const isLast = i === lines.length - 1;
9
+
5
10
  const line = lines[i];
6
11
  line.translateLeft(offset);
7
12
 
8
13
  const next = lines[(i + 1) % lines.length];
9
- line.extendToOrTrimAtIntersection(next);
10
- next.extendToOrTrimAtIntersection(line);
14
+ if (!isLast || isClosed) {
15
+ line.extendToOrTrimAtIntersection(next);
16
+ next.extendToOrTrimAtIntersection(line);
17
+ }
11
18
 
12
19
  const previous = lines[(i + lines.length - 1) % lines.length];
13
- line.extendToOrTrimAtIntersection(previous);
14
- previous.extendToOrTrimAtIntersection(line);
20
+ if (!isFirst || isClosed) {
21
+ line.extendToOrTrimAtIntersection(previous);
22
+ previous.extendToOrTrimAtIntersection(line);
23
+ }
15
24
  }
16
25
 
17
26
  return lines;
package/types/Line2D.d.ts CHANGED
@@ -251,7 +251,7 @@ export declare class Line2D {
251
251
  * Accepts an array of Line2D and groups them into arrays of connected lines
252
252
  * @param lines Lines to be grouped
253
253
  * @param tolerance Tolerance for considering lines as connected
254
- * @param breakpoints
254
+ * @param breakpoints Endpoints on breakpoints are not considered as connected
255
255
  */
256
256
  static groupConnectedLines(lines: Line2D[], tolerance?: number, breakpoints?: Vec2[]): Line2D[][];
257
257
  /**
package/types/Vec3.d.ts CHANGED
@@ -50,6 +50,7 @@ export declare class Vec3 extends Vector3 {
50
50
  * @param points
51
51
  */
52
52
  closest(...points: Vector3[]): Vec3;
53
+ applyAxisAngleAroundCenter(axis: Vector3, angle: number, center: Vector3): this;
53
54
  roundIfCloseToInteger(max?: number): this;
54
55
  /**
55
56
  * Returns a clone of this Vec3 instance with y and z swapped.
@@ -1,2 +1,2 @@
1
1
  import { Line2D } from "./Line2D";
2
- export declare function offsetPolyline(lines: Line2D[], offset: number): Line2D[];
2
+ export declare function offsetPolyline(lines: Line2D[], offset: number, tolerance?: number): Line2D[];