@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/cjs/Line2D.js +90 -13
  3. package/cjs/Polygon.js +3 -0
  4. package/docs/classes/BoundingBox.md +121 -121
  5. package/docs/classes/Line2D.md +1366 -1366
  6. package/docs/classes/Line3D.md +831 -831
  7. package/docs/classes/Polygon.md +297 -297
  8. package/docs/classes/Rectangle.md +291 -291
  9. package/docs/classes/Size2.md +55 -55
  10. package/docs/classes/Vec2.md +282 -282
  11. package/docs/classes/Vec3.md +338 -338
  12. package/docs/interfaces/Point2.md +30 -30
  13. package/docs/interfaces/Point3.md +41 -41
  14. package/docs/modules.md +209 -209
  15. package/eslint.config.mjs +111 -111
  16. package/esm/Line2D.js +90 -13
  17. package/esm/Polygon.js +3 -0
  18. package/package.json +62 -62
  19. package/src/BoundingBox.ts +13 -13
  20. package/src/Line2D.ts +951 -857
  21. package/src/Line3D.ts +586 -586
  22. package/src/MathConstants.ts +1 -1
  23. package/src/Point2.ts +3 -3
  24. package/src/Point3.ts +4 -4
  25. package/src/Polygon.ts +290 -286
  26. package/src/Rectangle.ts +92 -92
  27. package/src/Size2.ts +3 -3
  28. package/src/Vec2.ts +124 -124
  29. package/src/Vec3.ts +167 -167
  30. package/src/containsPoint.ts +65 -65
  31. package/src/directions.ts +9 -9
  32. package/src/directions2d.ts +7 -7
  33. package/src/ensurePolygonClockwise.ts +9 -9
  34. package/src/extendOrTrimPolylinesAtIntersections.ts +10 -10
  35. package/src/getPolygonArea.ts +21 -21
  36. package/src/index.ts +24 -24
  37. package/src/isContinuousClosedShape.ts +24 -24
  38. package/src/isPointInPolygon.ts +23 -23
  39. package/src/isPolygonClockwise.ts +15 -15
  40. package/src/normalizeAngleDegrees.ts +6 -6
  41. package/src/normalizeAngleRadians.ts +14 -14
  42. package/src/offsetPolyline.ts +26 -26
  43. package/src/polygonPerimeter.ts +13 -13
  44. package/src/sortLinesByConnections.ts +45 -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
- isCollinearWithTouchOrOverlap(other) {
267
- if (!this.isPointOnInfiniteLine(other.start) || !this.isPointOnInfiniteLine(other.end)) {
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
- return this.isPointOnLineSection(other.start) || this.isPointOnLineSection(other.end) ||
271
- other.isPointOnLineSection(this.start) || other.isPointOnLineSection(this.end);
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
- const p1 = !line.isPointOnLineSection(other.start) ? other.start : line.start;
340
- const p2 = !line.isPointOnLineSection(other.end) ? other.end : line.end;
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",
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
+ }
@@ -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
  }