@immugio/three-math-extensions 0.2.21 → 0.2.23

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/src/Line2D.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Point2 } from "./Point2";
2
- import { Vector2 } from "three";
2
+ import { MathUtils, Vector2 } from "three";
3
3
  import { Vec2 } from "./Vec2";
4
- import { MathUtils } from "three";
5
4
  import { TwoPI } from "./MathConstants";
6
5
  import { Line3D } from "./Line3D";
7
6
  import { directions2d } from "./directions2d";
@@ -11,6 +10,8 @@ const _startEnd = /*@__PURE__*/ new Vec2();
11
10
 
12
11
  export class Line2D {
13
12
 
13
+ readonly #target: Vec2 = new Vec2();
14
+
14
15
  constructor(public start: Vec2, public end: Vec2, public index: number = 0) {
15
16
  }
16
17
 
@@ -161,6 +162,47 @@ export class Line2D {
161
162
  return [this.start, this.end];
162
163
  }
163
164
 
165
+ /**
166
+ * Check that this line segment contains provided point.
167
+ * @param p
168
+ * @param tolerance
169
+ */
170
+ public containsPoint(p: Vector2, tolerance: number = 0): boolean {
171
+ const closestPointToPoint = this.closestPointToPoint(p, true, this.#target);
172
+ return closestPointToPoint.distanceTo(p) <= tolerance;
173
+ }
174
+
175
+ /**
176
+ * Distance from this line to the provided point.
177
+ * @param param
178
+ * @param clampToLine
179
+ */
180
+ public distanceToPoint(p: Vector2, clampToLine: boolean = true): number {
181
+ const closestPointToPoint = this.closestPointToPoint(p, clampToLine, this.#target);
182
+ return closestPointToPoint.distanceTo(p);
183
+ }
184
+
185
+ /**
186
+ * Returns a copy of @other line, the direction of @other is reversed if needed.
187
+ * Returns null if lines are not parallel.
188
+ * @param other
189
+ * @param parallelTolerance
190
+ */
191
+ public getParallelLineInTheSameDirection(other: Line2D, parallelTolerance: number = 0): Line2D {
192
+ const direction = this.direction;
193
+
194
+ if (direction.angleTo(other.direction) <= parallelTolerance) {
195
+ return other.clone();
196
+ }
197
+
198
+ const otherLineOppositeDirection = other.clone().flip();
199
+ if (otherLineOppositeDirection.direction.angleTo(direction) <= parallelTolerance) {
200
+ return otherLineOppositeDirection;
201
+ }
202
+
203
+ return null;
204
+ }
205
+
164
206
  /**
165
207
  * Returns the direction of this line.
166
208
  */
@@ -173,9 +215,9 @@ export class Line2D {
173
215
  * Modifies this line.
174
216
  */
175
217
  public flip(): this {
176
- const temp = this.start.clone();
218
+ this.#target.copy(this.start);
177
219
  this.start.copy(this.end);
178
- this.end.copy(temp);
220
+ this.end.copy(this.#target);
179
221
 
180
222
  return this;
181
223
  }
@@ -284,16 +326,38 @@ export class Line2D {
284
326
  /**
285
327
  * Returns true if there is any overlap between this line and the @other line section.
286
328
  */
287
- public overlaps(other: Line2D): boolean {
288
- if (!this.isCollinearWithTouchOrOverlap(other)) {
289
- return false;
329
+ public overlaps(other: Line2D, distanceTolerance: number = 0, parallelTolerance: number = 0): boolean {
330
+ // Special case
331
+ if (this.equals(other, distanceTolerance)) {
332
+ return true;
290
333
  }
291
334
 
292
- if (this.start.equals(other.start) && this.end.equals(other.end)) {
293
- return true;
335
+ // Always have to be parallel
336
+ if (this.isParallelTo(other, parallelTolerance)) {
337
+ // To pass as overlapping, at least one point has to be within the other line, but they mush not be equal - "touching" is not considered overlapping
338
+
339
+ const otherStartEqualsToAnyOfThisPoint = other.start.distanceTo(this.start) <= distanceTolerance || other.start.distanceTo(this.end) <= distanceTolerance;
340
+ if (this.containsPoint(other.start, distanceTolerance) && !otherStartEqualsToAnyOfThisPoint) {
341
+ return true;
342
+ }
343
+
344
+ const otherEndEqualsToAnyOfThisPoint = other.end.distanceTo(this.start) <= distanceTolerance || other.end.distanceTo(this.end) <= distanceTolerance;
345
+ if (this.containsPoint(other.end, distanceTolerance) && !otherEndEqualsToAnyOfThisPoint) {
346
+ return true;
347
+ }
348
+
349
+ const thisStartEqualsToAnyOfOtherPoint = this.start.distanceTo(other.start) <= distanceTolerance || this.start.distanceTo(other.end) <= distanceTolerance;
350
+ if (other.containsPoint(this.start, distanceTolerance) && !thisStartEqualsToAnyOfOtherPoint) {
351
+ return true;
352
+ }
353
+
354
+ const thisEndEqualsToAnyOfOtherPoint = this.end.distanceTo(other.start) <= distanceTolerance || this.end.distanceTo(other.end) <= distanceTolerance;
355
+ if (other.containsPoint(this.end, distanceTolerance) && !thisEndEqualsToAnyOfOtherPoint) {
356
+ return true;
357
+ }
294
358
  }
295
359
 
296
- return !this.start.equals(other.end) && !this.end.equals(other.start);
360
+ return false;
297
361
  }
298
362
 
299
363
  /**
@@ -382,6 +446,19 @@ export class Line2D {
382
446
  return result;
383
447
  }
384
448
 
449
+ /**
450
+ * Checks if the current line covers another line.
451
+ * A line is considered to cover another line if they are parallel and both the start and end points of the other line are contained within the current line.
452
+ * Both distance and angle tolerance can be provided.
453
+ */
454
+ public covers(other: Line2D, tolerance: number = 0, parallelTolerance: number = 0): boolean {
455
+ if (!this.isParallelTo(other, parallelTolerance)) {
456
+ return false;
457
+ }
458
+
459
+ return this.containsPoint(other.start, tolerance) && this.containsPoint(other.end, tolerance);
460
+ }
461
+
385
462
  /**
386
463
  * Returns a new line that is the projection of this line onto @other. Uses `closestPointToPoint` to find the projection.
387
464
  * @param other
@@ -759,8 +836,12 @@ export class Line2D {
759
836
  return new Line3D(this.start.in3DSpace(y), this.end.in3DSpace(y));
760
837
  }
761
838
 
762
- public equals(other: Line2D): boolean {
763
- return !!other && this.start.equals(other.start) && this.end.equals(other.end);
839
+ public equals(other: Line2D, tolerance: number = 0): boolean {
840
+ if (!tolerance) {
841
+ return !!other && this.start.equals(other.start) && this.end.equals(other.end);
842
+ }
843
+
844
+ return !!other && this.start.distanceTo(other.start) <= tolerance && this.end.distanceTo(other.end) <= tolerance;
764
845
  }
765
846
 
766
847
  /**
package/src/Line3D.ts CHANGED
@@ -305,7 +305,7 @@ export class Line3D extends Line3 {
305
305
  }
306
306
 
307
307
  /**
308
- * Distance from this line to provided point.
308
+ * Distance from this line to the provided point.
309
309
  * @param p
310
310
  * @param clampToLine
311
311
  */
package/types/Line2D.d.ts CHANGED
@@ -3,6 +3,7 @@ import { Vector2 } from "three";
3
3
  import { Vec2 } from "./Vec2";
4
4
  import { Line3D } from "./Line3D";
5
5
  export declare class Line2D {
6
+ #private;
6
7
  start: Vec2;
7
8
  end: Vec2;
8
9
  index: number;
@@ -55,6 +56,25 @@ export declare class Line2D {
55
56
  * Endpoints are not cloned.
56
57
  */
57
58
  get endpoints(): Vec2[];
59
+ /**
60
+ * Check that this line segment contains provided point.
61
+ * @param p
62
+ * @param tolerance
63
+ */
64
+ containsPoint(p: Vector2, tolerance?: number): boolean;
65
+ /**
66
+ * Distance from this line to the provided point.
67
+ * @param param
68
+ * @param clampToLine
69
+ */
70
+ distanceToPoint(p: Vector2, clampToLine?: boolean): number;
71
+ /**
72
+ * Returns a copy of @other line, the direction of @other is reversed if needed.
73
+ * Returns null if lines are not parallel.
74
+ * @param other
75
+ * @param parallelTolerance
76
+ */
77
+ getParallelLineInTheSameDirection(other: Line2D, parallelTolerance?: number): Line2D;
58
78
  /**
59
79
  * Returns the direction of this line.
60
80
  */
@@ -117,7 +137,7 @@ export declare class Line2D {
117
137
  /**
118
138
  * Returns true if there is any overlap between this line and the @other line section.
119
139
  */
120
- overlaps(other: Line2D): boolean;
140
+ overlaps(other: Line2D, distanceTolerance?: number, parallelTolerance?: number): boolean;
121
141
  /**
122
142
  * Logical AND of this and the other line section.
123
143
  * @param other
@@ -139,6 +159,12 @@ export declare class Line2D {
139
159
  * @param lines
140
160
  */
141
161
  static joinLines(lines: Line2D[]): Line2D[];
162
+ /**
163
+ * Checks if the current line covers another line.
164
+ * A line is considered to cover another line if they are parallel and both the start and end points of the other line are contained within the current line.
165
+ * Both distance and angle tolerance can be provided.
166
+ */
167
+ covers(other: Line2D, tolerance?: number, parallelTolerance?: number): boolean;
142
168
  /**
143
169
  * Returns a new line that is the projection of this line onto @other. Uses `closestPointToPoint` to find the projection.
144
170
  * @param other
@@ -241,7 +267,7 @@ export declare class Line2D {
241
267
  * @returns A new Line3D instance.
242
268
  */
243
269
  in3DSpace(y?: number): Line3D;
244
- equals(other: Line2D): boolean;
270
+ equals(other: Line2D, tolerance?: number): boolean;
245
271
  /**
246
272
  * Deep clone of this line
247
273
  */
package/types/Line3D.d.ts CHANGED
@@ -94,7 +94,7 @@ export declare class Line3D extends Line3 {
94
94
  */
95
95
  containsPoint(p: Vector3, tolerance?: number): boolean;
96
96
  /**
97
- * Distance from this line to provided point.
97
+ * Distance from this line to the provided point.
98
98
  * @param p
99
99
  * @param clampToLine
100
100
  */
package/docs/README.md DELETED
@@ -1,90 +0,0 @@
1
- @immugio/three-math-extensions / [Exports](modules.md)
2
-
3
- # Set of utilities for 2d and 3d math built on top of three.js
4
-
5
- [![Build](https://github.com/Immugio/three-math-extensions/actions/workflows/build.yml/badge.svg)](https://github.com/Immugio/three-math-extensions/actions/workflows/build.yml)
6
-
7
- [@immugio/three-math-extensions](README.md) / Exports
8
-
9
- # @immugio/three-math-extensions
10
-
11
- ## Table of contents
12
-
13
- ### Classes
14
-
15
- - [BoundingBox](docs/classes/BoundingBox.md)
16
- - [Line2D](docs/classes/Line2D.md)
17
- - [Line3D](docs/classes/Line3D.md)
18
- - [Polygon](docs/classes/Polygon.md)
19
- - [Rectangle](docs/classes/Rectangle.md)
20
- - [Size2](docs/classes/Size2.md)
21
- - [Vec2](docs/classes/Vec2.md)
22
- - [Vec3](docs/classes/Vec3.md)
23
-
24
- ### Interfaces
25
-
26
- - [Point2](docs/interfaces/Point2.md)
27
- - [Point3](docs/interfaces/Point3.md)
28
-
29
- ### Variables
30
-
31
- - [TwoPI](docs/modules.md#twopi)
32
-
33
- ### Functions
34
-
35
- - [normalizeAngleDegrees](docs/modules.md#normalizeangledegrees)
36
- - [normalizeAngleRadians](docs/modules.md#normalizeangleradians)
37
-
38
- ## Variables
39
-
40
- ### TwoPI
41
-
42
- • `Const` **TwoPI**: `number`
43
-
44
- #### Defined in
45
-
46
- [src/MathConstants.ts:1](https://github.com/Immugio/three-math-extensions/blob/151f214/src/MathConstants.ts#L1)
47
-
48
- ## Functions
49
-
50
- ### normalizeAngleDegrees
51
-
52
- ▸ **normalizeAngleDegrees**(`angle`): `number`
53
-
54
- Normalizes an angle in degrees to the range [0, 360].
55
-
56
- #### Parameters
57
-
58
- | Name | Type | Description |
59
- | :------ | :------ | :------ |
60
- | `angle` | `number` | in degrees |
61
-
62
- #### Returns
63
-
64
- `number`
65
-
66
- #### Defined in
67
-
68
- [src/normalizeAngleDegrees.ts:5](https://github.com/Immugio/three-math-extensions/blob/151f214/src/normalizeAngleDegrees.ts#L5)
69
-
70
- ___
71
-
72
- ### normalizeAngleRadians
73
-
74
- ▸ **normalizeAngleRadians**(`angle`): `number`
75
-
76
- Normalize an angle in radians to the range of 0 to 2π.
77
-
78
- #### Parameters
79
-
80
- | Name | Type | Description |
81
- | :------ | :------ | :------ |
82
- | `angle` | `number` | in radians |
83
-
84
- #### Returns
85
-
86
- `number`
87
-
88
- #### Defined in
89
-
90
- [src/normalizeAngleRadians.ts:7](https://github.com/Immugio/three-math-extensions/blob/151f214/src/normalizeAngleRadians.ts#L7)