@immugio/three-math-extensions 0.3.4 → 0.3.7
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 +23 -1
- package/cjs/Line2D.js +90 -13
- package/cjs/Polygon.js +3 -0
- package/docs/classes/BoundingBox.md +121 -121
- package/docs/classes/Line2D.md +1366 -1366
- package/docs/classes/Line3D.md +831 -831
- package/docs/classes/Polygon.md +297 -297
- package/docs/classes/Rectangle.md +291 -291
- package/docs/classes/Size2.md +55 -55
- package/docs/classes/Vec2.md +282 -282
- package/docs/classes/Vec3.md +338 -338
- package/docs/interfaces/Point2.md +30 -30
- package/docs/interfaces/Point3.md +41 -41
- package/docs/modules.md +209 -209
- package/eslint.config.mjs +111 -111
- package/esm/Line2D.js +90 -13
- package/esm/Polygon.js +3 -0
- package/package.json +62 -62
- package/src/BoundingBox.ts +13 -13
- package/src/Line2D.ts +951 -857
- package/src/Line3D.ts +586 -586
- package/src/MathConstants.ts +1 -1
- package/src/Point2.ts +3 -3
- package/src/Point3.ts +4 -4
- package/src/Polygon.ts +290 -286
- package/src/Rectangle.ts +92 -92
- package/src/Size2.ts +3 -3
- package/src/Vec2.ts +124 -124
- package/src/Vec3.ts +167 -167
- package/src/containsPoint.ts +65 -65
- package/src/directions.ts +9 -9
- package/src/directions2d.ts +7 -7
- package/src/ensurePolygonClockwise.ts +9 -9
- package/src/extendOrTrimPolylinesAtIntersections.ts +10 -10
- package/src/getPolygonArea.ts +21 -21
- package/src/index.ts +24 -24
- package/src/isContinuousClosedShape.ts +24 -24
- package/src/isPointInPolygon.ts +23 -23
- package/src/isPolygonClockwise.ts +15 -15
- package/src/normalizeAngleDegrees.ts +6 -6
- package/src/normalizeAngleRadians.ts +14 -14
- package/src/offsetPolyline.ts +26 -26
- package/src/polygonPerimeter.ts +13 -13
- package/src/sortLinesByConnections.ts +45 -45
- package/types/Line2D.d.ts +12 -5
package/eslint.config.mjs
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
import react from "eslint-plugin-react";
|
|
2
|
-
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
|
3
|
-
import globals from "globals";
|
|
4
|
-
import tsParser from "@typescript-eslint/parser";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
|
-
import js from "@eslint/js";
|
|
8
|
-
import { FlatCompat } from "@eslint/eslintrc";
|
|
9
|
-
import stylistic from "@stylistic/eslint-plugin";
|
|
10
|
-
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = path.dirname(__filename);
|
|
13
|
-
const compat = new FlatCompat({
|
|
14
|
-
baseDirectory: __dirname,
|
|
15
|
-
recommendedConfig: js.configs.recommended,
|
|
16
|
-
allConfig: js.configs.all
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
export default [
|
|
20
|
-
{
|
|
21
|
-
ignores: ["cjs/", "esm/", "types/"],
|
|
22
|
-
},
|
|
23
|
-
...compat.extends("eslint:recommended",
|
|
24
|
-
"plugin:react/recommended",
|
|
25
|
-
"plugin:@typescript-eslint/recommended"),
|
|
26
|
-
{
|
|
27
|
-
plugins: {
|
|
28
|
-
react,
|
|
29
|
-
"@typescript-eslint": typescriptEslint,
|
|
30
|
-
"@stylistic": stylistic
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
languageOptions: {
|
|
34
|
-
globals: {
|
|
35
|
-
...globals.browser,
|
|
36
|
-
...globals.jest,
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
parser: tsParser,
|
|
40
|
-
ecmaVersion: 11,
|
|
41
|
-
sourceType: "module",
|
|
42
|
-
|
|
43
|
-
parserOptions: {
|
|
44
|
-
ecmaFeatures: {
|
|
45
|
-
jsx: true,
|
|
46
|
-
},
|
|
47
|
-
lib: ["esnext", "dom"]
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
settings: {
|
|
52
|
-
react: {
|
|
53
|
-
pragma: "dom",
|
|
54
|
-
version: "17.0"
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
rules: {
|
|
59
|
-
"@stylistic/indent": ["warn", 4, { "SwitchCase": 1 }],
|
|
60
|
-
"@stylistic/linebreak-style": ["error", "windows"],
|
|
61
|
-
"@stylistic/quotes": ["error", "double"],
|
|
62
|
-
"@stylistic/semi": ["error", "always"],
|
|
63
|
-
"@stylistic/no-extra-semi": ["error"],
|
|
64
|
-
"@stylistic/no-trailing-spaces": ["error"],
|
|
65
|
-
"@stylistic/no-multiple-empty-lines": ["error", { max: 1 }],
|
|
66
|
-
"@stylistic/space-in-parens": ["error", "never"],
|
|
67
|
-
"@stylistic/space-infix-ops": ["error", { int32Hint: false }],
|
|
68
|
-
"@stylistic/no-mixed-spaces-and-tabs": ["error"],
|
|
69
|
-
"@stylistic/space-before-blocks": ["error", "always"],
|
|
70
|
-
"@stylistic/function-call-spacing": ["error", "never"],
|
|
71
|
-
"@stylistic/key-spacing": ["error", { "beforeColon": false, "afterColon": true }],
|
|
72
|
-
"@stylistic/array-bracket-spacing": ["error", "never"],
|
|
73
|
-
"@stylistic/arrow-spacing": ["error", { "before": true, "after": true }],
|
|
74
|
-
"@stylistic/block-spacing": ["error", "always"],
|
|
75
|
-
"@stylistic/brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
|
76
|
-
"@stylistic/semi-spacing": ["error", { "before": false, "after": true }],
|
|
77
|
-
"@stylistic/space-before-function-paren": ["error", "never"],
|
|
78
|
-
"@stylistic/switch-colon-spacing": ["error", { "after": true, "before": false }],
|
|
79
|
-
"@stylistic/template-curly-spacing": ["error", "never"],
|
|
80
|
-
"@stylistic/type-annotation-spacing": ["error", { "after": true }],
|
|
81
|
-
"@stylistic/object-curly-spacing": ["error", "always"],
|
|
82
|
-
"@stylistic/keyword-spacing": ["error", { "before": true, "after": true }],
|
|
83
|
-
"no-undef": "error",
|
|
84
|
-
"consistent-return": "error",
|
|
85
|
-
"no-invalid-this": "error",
|
|
86
|
-
"arrow-parens": ["error", "as-needed"],
|
|
87
|
-
"eol-last": ["error", "never"],
|
|
88
|
-
"@typescript-eslint/no-inferrable-types": "off",
|
|
89
|
-
"@typescript-eslint/no-empty-interface": "off",
|
|
90
|
-
"@typescript-eslint/no-this-alias": "off",
|
|
91
|
-
"no-inv": "off",
|
|
92
|
-
"no-prototype-builtins": "off",
|
|
93
|
-
"react/react-in-jsx-scope": "off",
|
|
94
|
-
"react/no-unknown-property": "off",
|
|
95
|
-
"react/no-unescaped-entities": "off",
|
|
96
|
-
"react/jsx-key": "off",
|
|
97
|
-
"react/prop-types": "off",
|
|
98
|
-
"react/no-is-mounted": "off",
|
|
99
|
-
"@typescript-eslint/explicit-member-accessibility": ["error", {
|
|
100
|
-
"accessibility": "explicit",
|
|
101
|
-
"overrides": {
|
|
102
|
-
"constructors": "no-public"
|
|
103
|
-
}
|
|
104
|
-
}],
|
|
105
|
-
"react/self-closing-comp": ["warn", {
|
|
106
|
-
"component": true,
|
|
107
|
-
"html": true
|
|
108
|
-
}],
|
|
109
|
-
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
110
|
-
"eqeqeq": ["error", "always"]
|
|
111
|
-
},
|
|
1
|
+
import react from "eslint-plugin-react";
|
|
2
|
+
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
|
3
|
+
import globals from "globals";
|
|
4
|
+
import tsParser from "@typescript-eslint/parser";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import js from "@eslint/js";
|
|
8
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
9
|
+
import stylistic from "@stylistic/eslint-plugin";
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
const compat = new FlatCompat({
|
|
14
|
+
baseDirectory: __dirname,
|
|
15
|
+
recommendedConfig: js.configs.recommended,
|
|
16
|
+
allConfig: js.configs.all
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default [
|
|
20
|
+
{
|
|
21
|
+
ignores: ["cjs/", "esm/", "types/"],
|
|
22
|
+
},
|
|
23
|
+
...compat.extends("eslint:recommended",
|
|
24
|
+
"plugin:react/recommended",
|
|
25
|
+
"plugin:@typescript-eslint/recommended"),
|
|
26
|
+
{
|
|
27
|
+
plugins: {
|
|
28
|
+
react,
|
|
29
|
+
"@typescript-eslint": typescriptEslint,
|
|
30
|
+
"@stylistic": stylistic
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
languageOptions: {
|
|
34
|
+
globals: {
|
|
35
|
+
...globals.browser,
|
|
36
|
+
...globals.jest,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
parser: tsParser,
|
|
40
|
+
ecmaVersion: 11,
|
|
41
|
+
sourceType: "module",
|
|
42
|
+
|
|
43
|
+
parserOptions: {
|
|
44
|
+
ecmaFeatures: {
|
|
45
|
+
jsx: true,
|
|
46
|
+
},
|
|
47
|
+
lib: ["esnext", "dom"]
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
settings: {
|
|
52
|
+
react: {
|
|
53
|
+
pragma: "dom",
|
|
54
|
+
version: "17.0"
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
rules: {
|
|
59
|
+
"@stylistic/indent": ["warn", 4, { "SwitchCase": 1 }],
|
|
60
|
+
"@stylistic/linebreak-style": ["error", "windows"],
|
|
61
|
+
"@stylistic/quotes": ["error", "double"],
|
|
62
|
+
"@stylistic/semi": ["error", "always"],
|
|
63
|
+
"@stylistic/no-extra-semi": ["error"],
|
|
64
|
+
"@stylistic/no-trailing-spaces": ["error"],
|
|
65
|
+
"@stylistic/no-multiple-empty-lines": ["error", { max: 1 }],
|
|
66
|
+
"@stylistic/space-in-parens": ["error", "never"],
|
|
67
|
+
"@stylistic/space-infix-ops": ["error", { int32Hint: false }],
|
|
68
|
+
"@stylistic/no-mixed-spaces-and-tabs": ["error"],
|
|
69
|
+
"@stylistic/space-before-blocks": ["error", "always"],
|
|
70
|
+
"@stylistic/function-call-spacing": ["error", "never"],
|
|
71
|
+
"@stylistic/key-spacing": ["error", { "beforeColon": false, "afterColon": true }],
|
|
72
|
+
"@stylistic/array-bracket-spacing": ["error", "never"],
|
|
73
|
+
"@stylistic/arrow-spacing": ["error", { "before": true, "after": true }],
|
|
74
|
+
"@stylistic/block-spacing": ["error", "always"],
|
|
75
|
+
"@stylistic/brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
|
76
|
+
"@stylistic/semi-spacing": ["error", { "before": false, "after": true }],
|
|
77
|
+
"@stylistic/space-before-function-paren": ["error", "never"],
|
|
78
|
+
"@stylistic/switch-colon-spacing": ["error", { "after": true, "before": false }],
|
|
79
|
+
"@stylistic/template-curly-spacing": ["error", "never"],
|
|
80
|
+
"@stylistic/type-annotation-spacing": ["error", { "after": true }],
|
|
81
|
+
"@stylistic/object-curly-spacing": ["error", "always"],
|
|
82
|
+
"@stylistic/keyword-spacing": ["error", { "before": true, "after": true }],
|
|
83
|
+
"no-undef": "error",
|
|
84
|
+
"consistent-return": "error",
|
|
85
|
+
"no-invalid-this": "error",
|
|
86
|
+
"arrow-parens": ["error", "as-needed"],
|
|
87
|
+
"eol-last": ["error", "never"],
|
|
88
|
+
"@typescript-eslint/no-inferrable-types": "off",
|
|
89
|
+
"@typescript-eslint/no-empty-interface": "off",
|
|
90
|
+
"@typescript-eslint/no-this-alias": "off",
|
|
91
|
+
"no-inv": "off",
|
|
92
|
+
"no-prototype-builtins": "off",
|
|
93
|
+
"react/react-in-jsx-scope": "off",
|
|
94
|
+
"react/no-unknown-property": "off",
|
|
95
|
+
"react/no-unescaped-entities": "off",
|
|
96
|
+
"react/jsx-key": "off",
|
|
97
|
+
"react/prop-types": "off",
|
|
98
|
+
"react/no-is-mounted": "off",
|
|
99
|
+
"@typescript-eslint/explicit-member-accessibility": ["error", {
|
|
100
|
+
"accessibility": "explicit",
|
|
101
|
+
"overrides": {
|
|
102
|
+
"constructors": "no-public"
|
|
103
|
+
}
|
|
104
|
+
}],
|
|
105
|
+
"react/self-closing-comp": ["warn", {
|
|
106
|
+
"component": true,
|
|
107
|
+
"html": true
|
|
108
|
+
}],
|
|
109
|
+
"@typescript-eslint/explicit-module-boundary-types": "error",
|
|
110
|
+
"eqeqeq": ["error", "always"]
|
|
111
|
+
},
|
|
112
112
|
}];
|
package/esm/Line2D.js
CHANGED
|
@@ -261,14 +261,63 @@ export class Line2D {
|
|
|
261
261
|
}
|
|
262
262
|
/**
|
|
263
263
|
* Returns true if other line is collinear and overlaps or at least touching this line.
|
|
264
|
+
* Uses tolerances to allow for small gaps and angle differences.
|
|
264
265
|
* @param other
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
266
|
+
* @param distanceTolerance Maximum distance between lines or points to be considered touching/overlapping
|
|
267
|
+
* @param parallelTolerance Maximum angle difference in radians for lines to be considered parallel
|
|
268
|
+
*/
|
|
269
|
+
isCollinearWithTouchOrOverlap(other, distanceTolerance = 0, parallelTolerance = 0) {
|
|
270
|
+
// Exact logic (no tolerances)
|
|
271
|
+
if (!distanceTolerance && !parallelTolerance) {
|
|
272
|
+
if (!this.isPointOnInfiniteLine(other.start) || !this.isPointOnInfiniteLine(other.end)) {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
return this.isPointOnLineSection(other.start) || this.isPointOnLineSection(other.end) ||
|
|
276
|
+
other.isPointOnLineSection(this.start) || other.isPointOnLineSection(this.end);
|
|
277
|
+
}
|
|
278
|
+
// If tolerances are provided, use tolerance-aware logic
|
|
279
|
+
// Check if lines are parallel
|
|
280
|
+
if (!this.isParallelTo(other, parallelTolerance)) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
// Check if points are close enough to the infinite line
|
|
284
|
+
const otherStartDistance = this.distanceToPointOnInfiniteLine(other.start);
|
|
285
|
+
const otherEndDistance = this.distanceToPointOnInfiniteLine(other.end);
|
|
286
|
+
const thisStartDistance = other.distanceToPointOnInfiniteLine(this.start);
|
|
287
|
+
const thisEndDistance = other.distanceToPointOnInfiniteLine(this.end);
|
|
288
|
+
if (otherStartDistance > distanceTolerance || otherEndDistance > distanceTolerance ||
|
|
289
|
+
thisStartDistance > distanceTolerance || thisEndDistance > distanceTolerance) {
|
|
268
290
|
return false;
|
|
269
291
|
}
|
|
270
|
-
|
|
271
|
-
|
|
292
|
+
// Check if any endpoint is close to and beside the other line section
|
|
293
|
+
// OR if the lines are close enough to each other (for gap handling)
|
|
294
|
+
const hasOverlap = this.isPointCloseToAndBesideLineSection(other.start, distanceTolerance) ||
|
|
295
|
+
this.isPointCloseToAndBesideLineSection(other.end, distanceTolerance) ||
|
|
296
|
+
other.isPointCloseToAndBesideLineSection(this.start, distanceTolerance) ||
|
|
297
|
+
other.isPointCloseToAndBesideLineSection(this.end, distanceTolerance);
|
|
298
|
+
if (hasOverlap) {
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
// Check if lines are close enough to bridge a gap
|
|
302
|
+
// Project all endpoints onto the line's direction and check if projections are within tolerance
|
|
303
|
+
const direction = this.direction;
|
|
304
|
+
const startPoint = this.start;
|
|
305
|
+
// Project all points onto the line's direction vector
|
|
306
|
+
const projectPoint = (p) => {
|
|
307
|
+
const toPoint = new Vec2().subVectors(p, startPoint);
|
|
308
|
+
return toPoint.dot(direction);
|
|
309
|
+
};
|
|
310
|
+
const thisStartProj = projectPoint(this.start);
|
|
311
|
+
const thisEndProj = projectPoint(this.end);
|
|
312
|
+
const otherStartProj = projectPoint(other.start);
|
|
313
|
+
const otherEndProj = projectPoint(other.end);
|
|
314
|
+
const minThis = Math.min(thisStartProj, thisEndProj);
|
|
315
|
+
const maxThis = Math.max(thisStartProj, thisEndProj);
|
|
316
|
+
const minOther = Math.min(otherStartProj, otherEndProj);
|
|
317
|
+
const maxOther = Math.max(otherStartProj, otherEndProj);
|
|
318
|
+
// Check if projections overlap or are within tolerance
|
|
319
|
+
const gap = Math.max(minThis, minOther) - Math.min(maxThis, maxOther);
|
|
320
|
+
return gap <= distanceTolerance;
|
|
272
321
|
}
|
|
273
322
|
/**
|
|
274
323
|
* Returns true if there is any overlap between this line and the @other line section.
|
|
@@ -326,27 +375,55 @@ export class Line2D {
|
|
|
326
375
|
}
|
|
327
376
|
/**
|
|
328
377
|
* Joins a copy of @line with the @other line.
|
|
329
|
-
* Other must be parallel to this line.
|
|
378
|
+
* Other must be parallel to this line (within tolerance).
|
|
330
379
|
* Returns null if there is no overlap
|
|
331
380
|
* Clones the line, does not modify.
|
|
332
381
|
* @param line
|
|
333
382
|
* @param other
|
|
383
|
+
* @param distanceTolerance Maximum distance between lines or points to be considered touching/overlapping
|
|
384
|
+
* @param parallelTolerance Maximum angle difference in radians for lines to be considered parallel
|
|
334
385
|
*/
|
|
335
|
-
static joinLine(line, other) {
|
|
336
|
-
if (!line.isCollinearWithTouchOrOverlap(other)) {
|
|
386
|
+
static joinLine(line, other, distanceTolerance = 0, parallelTolerance = 0) {
|
|
387
|
+
if (!line.isCollinearWithTouchOrOverlap(other, distanceTolerance, parallelTolerance)) {
|
|
337
388
|
return null;
|
|
338
389
|
}
|
|
339
|
-
|
|
340
|
-
const
|
|
390
|
+
// When using tolerances, we need to check if points are close enough to the line section
|
|
391
|
+
const useTolerance = distanceTolerance > 0 || parallelTolerance > 0;
|
|
392
|
+
if (!useTolerance) {
|
|
393
|
+
const p1 = !line.isPointOnLineSection(other.start) ? other.start : line.start;
|
|
394
|
+
const p2 = !line.isPointOnLineSection(other.end) ? other.end : line.end;
|
|
395
|
+
return new Line2D(p1.clone(), p2.clone(), line.index);
|
|
396
|
+
}
|
|
397
|
+
// Determine the endpoints of the joined line
|
|
398
|
+
// We want the outermost points that encompass both lines
|
|
399
|
+
const points = [line.start, line.end, other.start, other.end];
|
|
400
|
+
// Project all points onto the line's direction to find min/max
|
|
401
|
+
const direction = line.direction;
|
|
402
|
+
const startPoint = line.start;
|
|
403
|
+
// Project each point onto the line's direction vector
|
|
404
|
+
const projections = points.map(p => {
|
|
405
|
+
const toPoint = new Vec2().subVectors(p, startPoint);
|
|
406
|
+
const t = toPoint.dot(direction);
|
|
407
|
+
return { point: p, t };
|
|
408
|
+
});
|
|
409
|
+
// Find the points with min and max projections
|
|
410
|
+
const minProj = projections.reduce((min, curr) => curr.t < min.t ? curr : min);
|
|
411
|
+
const maxProj = projections.reduce((max, curr) => curr.t > max.t ? curr : max);
|
|
412
|
+
const p1 = minProj.point;
|
|
413
|
+
const p2 = maxProj.point;
|
|
341
414
|
return new Line2D(p1.clone(), p2.clone(), line.index);
|
|
342
415
|
}
|
|
343
416
|
/**
|
|
344
417
|
* Joins provided lines into several joined lines.
|
|
345
|
-
* Lines must be parallel for joining.
|
|
418
|
+
* Lines must be parallel for joining (within tolerance).
|
|
346
419
|
* Clone the lines, does not modify.
|
|
347
420
|
* @param lines
|
|
421
|
+
* @param distanceTolerance Maximum distance between lines or points to be considered touching/overlapping
|
|
422
|
+
* @param parallelTolerance Maximum angle difference in radians for lines to be considered parallel
|
|
348
423
|
*/
|
|
349
|
-
static joinLines(lines) {
|
|
424
|
+
static joinLines(lines, distanceTolerance, parallelTolerance) {
|
|
425
|
+
const distTol = distanceTolerance ?? 0;
|
|
426
|
+
const parTol = parallelTolerance ?? 0;
|
|
350
427
|
if (lines.length < 2) {
|
|
351
428
|
return lines.map(x => x.clone());
|
|
352
429
|
}
|
|
@@ -359,7 +436,7 @@ export class Line2D {
|
|
|
359
436
|
// Try to join each pair of lines
|
|
360
437
|
for (let i = 0; i < result.length; i++) {
|
|
361
438
|
for (let j = i + 1; j < result.length; j++) {
|
|
362
|
-
const joinedLine = Line2D.joinLine(result[i], result[j]);
|
|
439
|
+
const joinedLine = Line2D.joinLine(result[i], result[j], distTol, parTol);
|
|
363
440
|
if (joinedLine) {
|
|
364
441
|
// Replace the first line with the joined line and remove the second
|
|
365
442
|
result[i] = joinedLine;
|
package/esm/Polygon.js
CHANGED
|
@@ -77,6 +77,9 @@ export class Polygon {
|
|
|
77
77
|
return getPolygonArea(this.contour);
|
|
78
78
|
}
|
|
79
79
|
boundingBox() {
|
|
80
|
+
if (!this.contour.length) {
|
|
81
|
+
return new BoundingBox(0, 0, 0, 0);
|
|
82
|
+
}
|
|
80
83
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
81
84
|
for (const p of this.contour) {
|
|
82
85
|
if (minX > p.x)
|
package/package.json
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@immugio/three-math-extensions",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Set of utilities for 2d and 3d line math built on top of three.js",
|
|
5
|
-
"author": "Jan Mikeska <janmikeska@gmail.com>",
|
|
6
|
-
"license": "ISC",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"threejs",
|
|
9
|
-
"three",
|
|
10
|
-
"math"
|
|
11
|
-
],
|
|
12
|
-
"bugs": {
|
|
13
|
-
"url": "https://github.com/Immugio/three-math-extensions/issues"
|
|
14
|
-
},
|
|
15
|
-
"homepage": "https://github.com/Immugio/three-math-extensions#readme",
|
|
16
|
-
"sideEffects": false,
|
|
17
|
-
"source": "src/index.ts",
|
|
18
|
-
"main": "cjs/index.js",
|
|
19
|
-
"module": "esm/index.js",
|
|
20
|
-
"types": "types/index.d.ts",
|
|
21
|
-
"auto-changelog": {
|
|
22
|
-
"commitLimit": false,
|
|
23
|
-
"template": "keepachangelog"
|
|
24
|
-
},
|
|
25
|
-
"scripts": {
|
|
26
|
-
"test": "npx jest",
|
|
27
|
-
"build:esm": "tsc",
|
|
28
|
-
"build:cjs": "tsc -p tsconfig-cjs.json",
|
|
29
|
-
"clean": "rimraf types cjs esm",
|
|
30
|
-
"build": "npm run clean && npm run build:esm && npm run build:cjs",
|
|
31
|
-
"preversion": "npm run clean && npm run build && npm run test",
|
|
32
|
-
"version": "auto-changelog -p && git add CHANGELOG.md",
|
|
33
|
-
"postversion": "git push && git push --tags"
|
|
34
|
-
},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"@eslint/eslintrc": "^3.3.1",
|
|
37
|
-
"@eslint/js": "^9.39.1",
|
|
38
|
-
"@stylistic/eslint-plugin": "^5.6.1",
|
|
39
|
-
"@types/jest": "^29.5.11",
|
|
40
|
-
"@types/offscreencanvas": "2019.7.3",
|
|
41
|
-
"@types/three": "0.152.0",
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
|
43
|
-
"@typescript-eslint/parser": "^8.47.0",
|
|
44
|
-
"auto-changelog": "^2.5.0",
|
|
45
|
-
"eslint": "^9.39.1",
|
|
46
|
-
"eslint-plugin-react": "^7.37.5",
|
|
47
|
-
"globals": "^16.5.0",
|
|
48
|
-
"jest": "^30.2.0",
|
|
49
|
-
"rimraf": "^6.1.2",
|
|
50
|
-
"ts-jest": "^29.4.5",
|
|
51
|
-
"typedoc": "^0.28.14",
|
|
52
|
-
"typedoc-plugin-markdown": "^4.9.0",
|
|
53
|
-
"typescript": "5.3.3"
|
|
54
|
-
},
|
|
55
|
-
"peerDependencies": {
|
|
56
|
-
"three": ">=0.152.0"
|
|
57
|
-
},
|
|
58
|
-
"repository": {
|
|
59
|
-
"type": "git",
|
|
60
|
-
"url": "git+https://github.com/Immugio/three-math-extensions.git"
|
|
61
|
-
}
|
|
62
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@immugio/three-math-extensions",
|
|
3
|
+
"version": "0.3.7",
|
|
4
|
+
"description": "Set of utilities for 2d and 3d line math built on top of three.js",
|
|
5
|
+
"author": "Jan Mikeska <janmikeska@gmail.com>",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"threejs",
|
|
9
|
+
"three",
|
|
10
|
+
"math"
|
|
11
|
+
],
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/Immugio/three-math-extensions/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/Immugio/three-math-extensions#readme",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"source": "src/index.ts",
|
|
18
|
+
"main": "cjs/index.js",
|
|
19
|
+
"module": "esm/index.js",
|
|
20
|
+
"types": "types/index.d.ts",
|
|
21
|
+
"auto-changelog": {
|
|
22
|
+
"commitLimit": false,
|
|
23
|
+
"template": "keepachangelog"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "npx jest",
|
|
27
|
+
"build:esm": "tsc",
|
|
28
|
+
"build:cjs": "tsc -p tsconfig-cjs.json",
|
|
29
|
+
"clean": "rimraf types cjs esm",
|
|
30
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs",
|
|
31
|
+
"preversion": "npm run clean && npm run build && npm run test",
|
|
32
|
+
"version": "auto-changelog -p && git add CHANGELOG.md",
|
|
33
|
+
"postversion": "git push && git push --tags"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
37
|
+
"@eslint/js": "^9.39.1",
|
|
38
|
+
"@stylistic/eslint-plugin": "^5.6.1",
|
|
39
|
+
"@types/jest": "^29.5.11",
|
|
40
|
+
"@types/offscreencanvas": "2019.7.3",
|
|
41
|
+
"@types/three": "0.152.0",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
|
43
|
+
"@typescript-eslint/parser": "^8.47.0",
|
|
44
|
+
"auto-changelog": "^2.5.0",
|
|
45
|
+
"eslint": "^9.39.1",
|
|
46
|
+
"eslint-plugin-react": "^7.37.5",
|
|
47
|
+
"globals": "^16.5.0",
|
|
48
|
+
"jest": "^30.2.0",
|
|
49
|
+
"rimraf": "^6.1.2",
|
|
50
|
+
"ts-jest": "^29.4.5",
|
|
51
|
+
"typedoc": "^0.28.14",
|
|
52
|
+
"typedoc-plugin-markdown": "^4.9.0",
|
|
53
|
+
"typescript": "5.3.3"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"three": ">=0.152.0"
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/Immugio/three-math-extensions.git"
|
|
61
|
+
}
|
|
62
|
+
}
|
package/src/BoundingBox.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Vec2 } from "./Vec2";
|
|
2
|
-
|
|
3
|
-
export class BoundingBox {
|
|
4
|
-
constructor(public minX: number, public maxX: number, public minY: number, public maxY: number) {
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
public equals(other: BoundingBox): boolean {
|
|
8
|
-
return this.minX === other.minX && this.maxX === other.maxX && this.minY === other.minY && this.maxY === other.maxY;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
public get size(): Vec2 {
|
|
12
|
-
return new Vec2(this.maxX - this.minX, this.maxY - this.minY);
|
|
13
|
-
}
|
|
1
|
+
import { Vec2 } from "./Vec2";
|
|
2
|
+
|
|
3
|
+
export class BoundingBox {
|
|
4
|
+
constructor(public minX: number, public maxX: number, public minY: number, public maxY: number) {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
public equals(other: BoundingBox): boolean {
|
|
8
|
+
return this.minX === other.minX && this.maxX === other.maxX && this.minY === other.minY && this.maxY === other.maxY;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public get size(): Vec2 {
|
|
12
|
+
return new Vec2(this.maxX - this.minX, this.maxY - this.minY);
|
|
13
|
+
}
|
|
14
14
|
}
|