@eturnity/eturnity_maths 9.19.0-qa-03-9.22.0 → 9.25.0
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eturnity/eturnity_maths",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.25.0",
|
|
4
4
|
"author": "Eturnity Team",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"private": false,
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"uuid": "9.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "7.
|
|
32
|
-
"@babel/preset-env": "7.
|
|
31
|
+
"@babel/core": "7.21.4",
|
|
32
|
+
"@babel/preset-env": "7.21.4",
|
|
33
33
|
"babel-jest": "29.5.0",
|
|
34
34
|
"husky": "^9.1.5",
|
|
35
35
|
"@vue/eslint-config-standard": "8.0.1",
|
package/src/geometry.js
CHANGED
|
@@ -897,9 +897,7 @@ export function projectionOnPlaneFollowingVector(p, n, o, v) {
|
|
|
897
897
|
const nv = dotProduct(n, v)
|
|
898
898
|
if (nv == 0) {
|
|
899
899
|
console.warn('projection plane and vector are coplanar')
|
|
900
|
-
throw new Error(
|
|
901
|
-
'Cannot project: normal vector and direction vector are perpendicular'
|
|
902
|
-
)
|
|
900
|
+
throw new Error('Cannot project: normal vector and direction vector are perpendicular')
|
|
903
901
|
}
|
|
904
902
|
const lambda = -opn / nv
|
|
905
903
|
const projectedPoint = addVector(p, multiplyVector(lambda, v))
|
|
@@ -1088,8 +1086,8 @@ export function getMarginPoint(
|
|
|
1088
1086
|
dotProduct(m, m) != 0
|
|
1089
1087
|
? addVector(B, m)
|
|
1090
1088
|
: dotProduct(n, n) != 0
|
|
1091
|
-
|
|
1092
|
-
|
|
1089
|
+
? addVector(B, n)
|
|
1090
|
+
: B
|
|
1093
1091
|
} else {
|
|
1094
1092
|
const mm = dotProduct(m, m)
|
|
1095
1093
|
const nm = dotProduct(n, m)
|
|
@@ -1291,26 +1289,3 @@ export function getIndexesOfBiggestTriangleWithTwoFixedIndexes(
|
|
|
1291
1289
|
}
|
|
1292
1290
|
return maxTriangle
|
|
1293
1291
|
}
|
|
1294
|
-
|
|
1295
|
-
export function getRotatedRectBounds(width, height, angleDeg) {
|
|
1296
|
-
const rad = (angleDeg * Math.PI) / 180
|
|
1297
|
-
const c = Math.abs(Math.cos(rad))
|
|
1298
|
-
const s = Math.abs(Math.sin(rad))
|
|
1299
|
-
return {
|
|
1300
|
-
width: width * c + height * s,
|
|
1301
|
-
height: width * s + height * c,
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
export function getUnrotatedSizeFromAABB(aabbWidth, aabbHeight, angleDeg) {
|
|
1305
|
-
const rad = (angleDeg * Math.PI) / 180
|
|
1306
|
-
const c = Math.abs(Math.cos(rad))
|
|
1307
|
-
const s = Math.abs(Math.sin(rad))
|
|
1308
|
-
const det = c * c - s * s
|
|
1309
|
-
if (Math.abs(det) < 1e-10) {
|
|
1310
|
-
const side = Math.min(aabbWidth, aabbHeight) / Math.sqrt(2)
|
|
1311
|
-
return { width: side, height: side }
|
|
1312
|
-
}
|
|
1313
|
-
const width = (aabbWidth * c - aabbHeight * s) / det
|
|
1314
|
-
const height = (aabbHeight * c - aabbWidth * s) / det
|
|
1315
|
-
return { width: Math.abs(width), height: Math.abs(height) }
|
|
1316
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { getRotatedRectBounds, getUnrotatedSizeFromAABB } from '../../index'
|
|
2
|
-
|
|
3
|
-
function expectSizeClose(actual, expected, digits = 8) {
|
|
4
|
-
expect(actual.width).toBeCloseTo(expected.width, digits)
|
|
5
|
-
expect(actual.height).toBeCloseTo(expected.height, digits)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
describe('rectangle rotation helpers', () => {
|
|
9
|
-
describe('getRotatedRectBounds', () => {
|
|
10
|
-
test('returns same size at 0° (and equivalent angles)', () => {
|
|
11
|
-
expectSizeClose(getRotatedRectBounds(120, 45, 0), {
|
|
12
|
-
width: 120,
|
|
13
|
-
height: 45,
|
|
14
|
-
})
|
|
15
|
-
expectSizeClose(getRotatedRectBounds(120, 45, -180), {
|
|
16
|
-
width: 120,
|
|
17
|
-
height: 45,
|
|
18
|
-
})
|
|
19
|
-
expectSizeClose(getRotatedRectBounds(120, 45, 180), {
|
|
20
|
-
width: 120,
|
|
21
|
-
height: 45,
|
|
22
|
-
})
|
|
23
|
-
expectSizeClose(getRotatedRectBounds(120, 45, 360), {
|
|
24
|
-
width: 120,
|
|
25
|
-
height: 45,
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
test('swaps width/height at 90°', () => {
|
|
30
|
-
expectSizeClose(getRotatedRectBounds(120, 45, 90), {
|
|
31
|
-
width: 45,
|
|
32
|
-
height: 120,
|
|
33
|
-
})
|
|
34
|
-
expectSizeClose(getRotatedRectBounds(120, 45, -90), {
|
|
35
|
-
width: 45,
|
|
36
|
-
height: 120,
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
test('matches expected formula for an arbitrary angle', () => {
|
|
41
|
-
const width = 100
|
|
42
|
-
const height = 50
|
|
43
|
-
const angleDeg = 30
|
|
44
|
-
const rad = (angleDeg * Math.PI) / 180
|
|
45
|
-
const c = Math.abs(Math.cos(rad))
|
|
46
|
-
const s = Math.abs(Math.sin(rad))
|
|
47
|
-
expectSizeClose(getRotatedRectBounds(width, height, angleDeg), {
|
|
48
|
-
width: width * c + height * s,
|
|
49
|
-
height: width * s + height * c,
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
test('match for thin rectangle for an arbitrary angle', () => {
|
|
53
|
-
const width = 100
|
|
54
|
-
const height = 0.01
|
|
55
|
-
const angleDeg = 30
|
|
56
|
-
|
|
57
|
-
expectSizeClose(
|
|
58
|
-
getRotatedRectBounds(width, height, angleDeg),
|
|
59
|
-
{
|
|
60
|
-
width: (Math.sqrt(3) * 100) / 2,
|
|
61
|
-
height: 50,
|
|
62
|
-
},
|
|
63
|
-
1
|
|
64
|
-
)
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
describe('getUnrotatedSizeFromAABB', () => {
|
|
69
|
-
test('approximately inverts getRotatedRectBounds (non-degenerate angle)', () => {
|
|
70
|
-
const original = { width: 123.4, height: 56.7 }
|
|
71
|
-
const angleDeg = 27
|
|
72
|
-
|
|
73
|
-
const aabb = getRotatedRectBounds(
|
|
74
|
-
original.width,
|
|
75
|
-
original.height,
|
|
76
|
-
angleDeg
|
|
77
|
-
)
|
|
78
|
-
const unrotated = getUnrotatedSizeFromAABB(
|
|
79
|
-
aabb.width,
|
|
80
|
-
aabb.height,
|
|
81
|
-
angleDeg
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
expectSizeClose(unrotated, original, 6)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
test('handles the 45° determinant edge-case by returning a square', () => {
|
|
88
|
-
const aabbWidth = 200
|
|
89
|
-
const aabbHeight = 150
|
|
90
|
-
const angleDeg = 45
|
|
91
|
-
|
|
92
|
-
const result = getUnrotatedSizeFromAABB(aabbWidth, aabbHeight, angleDeg)
|
|
93
|
-
const side = Math.min(aabbWidth, aabbHeight) / Math.sqrt(2)
|
|
94
|
-
|
|
95
|
-
expectSizeClose(result, { width: side, height: side }, 10)
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
})
|