@eturnity/eturnity_maths 7.42.1 → 7.42.2-qa-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 +1 -1
- package/src/geometry.js +4 -0
- package/src/index.js +1 -0
- package/src/objects/Polygon.js +9 -7
- package/src/spherical.js +54 -0
- package/src/tests/geometry/getNormalVectortoEdgeTowardPolygon.spec.js +64 -53
- package/src/tests/spherical/fromSphericalCoordinatesToENU.spec.js +62 -0
package/package.json
CHANGED
package/src/geometry.js
CHANGED
|
@@ -77,6 +77,10 @@ export function getSnapedValue(value, snaps, tolerance) {
|
|
|
77
77
|
)
|
|
78
78
|
return closeSnapsItem.value
|
|
79
79
|
}
|
|
80
|
+
export function getAngleInDegFrom2DENUVector(v) {
|
|
81
|
+
const angle = Math.atan2(v.y, -v.x)
|
|
82
|
+
return ((angle * 180) / Math.PI + 90 + 360) % 360
|
|
83
|
+
}
|
|
80
84
|
export function getAngleInDegFromCanvasVector(v) {
|
|
81
85
|
const angle = Math.atan2(v.y, v.x)
|
|
82
86
|
return ((angle * 180) / Math.PI + 90 + 360) % 360
|
package/src/index.js
CHANGED
package/src/objects/Polygon.js
CHANGED
|
@@ -170,20 +170,22 @@ export class Polygon {
|
|
|
170
170
|
this.outline = this.outline.map((point) => {
|
|
171
171
|
return translate2D(point, vectorInMm)
|
|
172
172
|
})
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
p[1] += vectorInMm.y
|
|
178
|
-
})
|
|
173
|
+
|
|
174
|
+
if (this.layer == 'moduleField') {
|
|
175
|
+
this.trimedOutline = this.trimedOutline.map((point) => {
|
|
176
|
+
return addVector(point, vectorInMm)
|
|
179
177
|
})
|
|
178
|
+
} else {
|
|
179
|
+
updateComputedGeometryPolygon(this)
|
|
180
180
|
}
|
|
181
|
-
updateComputedGeometryPolygon(this)
|
|
182
181
|
}
|
|
183
182
|
translateOffset(newPositionOffset, center = { x: 0, y: 0 }) {
|
|
184
183
|
const shift = substractVector(newPositionOffset, this.positionOffset)
|
|
185
184
|
this.translate(shift)
|
|
186
185
|
}
|
|
186
|
+
resetOffset() {
|
|
187
|
+
this.positionOffset = { x: 0, y: 0, z: 0 }
|
|
188
|
+
}
|
|
187
189
|
serialize() {
|
|
188
190
|
const baseSerialization = {
|
|
189
191
|
id: this.id,
|
package/src/spherical.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { get3DDistanceBetweenPoints, midPoint } from './geometry'
|
|
2
|
+
import {
|
|
3
|
+
normalizeVector,
|
|
4
|
+
substractVector,
|
|
5
|
+
addVector,
|
|
6
|
+
multiplyVector,
|
|
7
|
+
} from './vector'
|
|
8
|
+
|
|
9
|
+
export function fromSphericalCoordinatesToENU(radius, altitude, azimuth) {
|
|
10
|
+
return {
|
|
11
|
+
x: -radius * Math.cos(altitude) * Math.sin(azimuth),
|
|
12
|
+
y: -radius * Math.cos(altitude) * Math.cos(azimuth),
|
|
13
|
+
z: radius * Math.sin(altitude),
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function getBoundingSphere(cloudPoint) {
|
|
17
|
+
let radius = 0
|
|
18
|
+
let center = { x: 0, y: 0, z: 0 }
|
|
19
|
+
if (cloudPoint.length == 0) {
|
|
20
|
+
return { radius, center }
|
|
21
|
+
}
|
|
22
|
+
const P0 = cloudPoint[0]
|
|
23
|
+
let vMin = { x: P0.x, y: P0.y, z: P0.z }
|
|
24
|
+
let vMax = { x: P0.x, y: P0.y, z: P0.z }
|
|
25
|
+
for (let i = 1; i < cloudPoint.length; i++) {
|
|
26
|
+
let P = cloudPoint[i]
|
|
27
|
+
vMin.x = Math.min(P.x, vMin.x)
|
|
28
|
+
vMin.y = Math.min(P.y, vMin.y)
|
|
29
|
+
vMin.z = Math.min(P.z, vMin.z)
|
|
30
|
+
vMax.x = Math.min(P.x, vMax.x)
|
|
31
|
+
vMax.y = Math.min(P.y, vMax.y)
|
|
32
|
+
vMax.z = Math.min(P.z, vMax.z)
|
|
33
|
+
}
|
|
34
|
+
center = midPoint(vMin, vMax)
|
|
35
|
+
radius = get3DDistanceBetweenPoints(vMin, vMax) / 2
|
|
36
|
+
for (let i = 0; i < cloudPoint.length; i++) {
|
|
37
|
+
let P = cloudPoint[i]
|
|
38
|
+
let distanceToCenter = get3DDistanceBetweenPoints(P, center)
|
|
39
|
+
if (distanceToCenter > radius) {
|
|
40
|
+
let difference = distanceToCenter - radius
|
|
41
|
+
radius = (radius + distanceToCenter) / 2
|
|
42
|
+
center = addVector(
|
|
43
|
+
center,
|
|
44
|
+
multiplyVector(
|
|
45
|
+
difference / 2,
|
|
46
|
+
normalizeVector(substractVector(P, center))
|
|
47
|
+
)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
radius = distanceToCenter
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { radius, center }
|
|
54
|
+
}
|
|
@@ -1,75 +1,86 @@
|
|
|
1
|
-
import { getNormalVectortoEdgeTowardPolygon} from '../../index'
|
|
1
|
+
import { getNormalVectortoEdgeTowardPolygon } from '../../index'
|
|
2
2
|
|
|
3
3
|
function toBeCloseToVector(received, expected, tolerance = 0.01) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const recPoint = received
|
|
8
|
-
const expPoint = expected
|
|
4
|
+
const recPoint = received
|
|
5
|
+
const expPoint = expected
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
if (
|
|
8
|
+
Math.abs(recPoint.x - expPoint.x) > tolerance ||
|
|
9
|
+
Math.abs(recPoint.y - expPoint.y) > tolerance ||
|
|
10
|
+
Math.abs(recPoint.z - expPoint.z) > tolerance
|
|
11
|
+
) {
|
|
12
|
+
return {
|
|
13
|
+
message: () =>
|
|
14
|
+
`Expected points to be close, but found ${JSON.stringify(
|
|
15
|
+
recPoint
|
|
16
|
+
)} and ${JSON.stringify(expPoint)}`,
|
|
17
|
+
pass: false,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
return {
|
|
22
|
+
message: () => `Points are close within the given tolerance`,
|
|
23
|
+
pass: true,
|
|
24
|
+
}
|
|
28
25
|
}
|
|
29
26
|
expect.extend({ toBeCloseToVector })
|
|
30
27
|
|
|
31
|
-
const A = {x:0,y:0,z:0}
|
|
32
|
-
const B = {x:10,y:0,z:0}
|
|
33
|
-
const C = {x:10,y:10,z:0}
|
|
34
|
-
const D = {x:0,y:10,z:0}
|
|
35
|
-
const E = {x:5,y:5,z:0}
|
|
36
|
-
const F = {x:2,y:0,z:0}
|
|
37
|
-
const G = {x:3,y
|
|
38
|
-
const H = {x:4,y:0,z:0}
|
|
28
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
29
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
30
|
+
const C = { x: 10, y: 10, z: 0 }
|
|
31
|
+
const D = { x: 0, y: 10, z: 0 }
|
|
32
|
+
const E = { x: 5, y: 5, z: 0 }
|
|
33
|
+
const F = { x: 2, y: 0, z: 0 }
|
|
34
|
+
const G = { x: 3, y: -10, z: 0 }
|
|
35
|
+
const H = { x: 4, y: 0, z: 0 }
|
|
39
36
|
describe('getNormalVectortoEdgeTowardPolygon function', () => {
|
|
40
37
|
test('anti-clockwise outline ABCD', () => {
|
|
41
|
-
const outline = [A,B,C,D]
|
|
42
|
-
const expectedNormalVector={x:0,y:1,z:0}
|
|
43
|
-
expect(getNormalVectortoEdgeTowardPolygon(0,outline)).toBeCloseToVector(
|
|
38
|
+
const outline = [A, B, C, D]
|
|
39
|
+
const expectedNormalVector = { x: 0, y: 1, z: 0 }
|
|
40
|
+
expect(getNormalVectortoEdgeTowardPolygon(0, outline)).toBeCloseToVector(
|
|
41
|
+
expectedNormalVector
|
|
42
|
+
)
|
|
44
43
|
})
|
|
45
44
|
test('clockwise outline', () => {
|
|
46
|
-
const outline = [A,D,C,B]
|
|
47
|
-
const expectedNormalVector={x:1,y:0,z:0}
|
|
48
|
-
expect(getNormalVectortoEdgeTowardPolygon(0,outline)).toBeCloseToVector(
|
|
45
|
+
const outline = [A, D, C, B]
|
|
46
|
+
const expectedNormalVector = { x: 1, y: 0, z: 0 }
|
|
47
|
+
expect(getNormalVectortoEdgeTowardPolygon(0, outline)).toBeCloseToVector(
|
|
48
|
+
expectedNormalVector
|
|
49
|
+
)
|
|
49
50
|
})
|
|
50
51
|
test('anti clockwise concave outline', () => {
|
|
51
|
-
const outline = [A,E,D,C,B]
|
|
52
|
-
const expectedNormalVector={x:0,y
|
|
53
|
-
expect(getNormalVectortoEdgeTowardPolygon(2,outline)).toBeCloseToVector(
|
|
52
|
+
const outline = [A, E, D, C, B]
|
|
53
|
+
const expectedNormalVector = { x: 0, y: -1, z: 0 }
|
|
54
|
+
expect(getNormalVectortoEdgeTowardPolygon(2, outline)).toBeCloseToVector(
|
|
55
|
+
expectedNormalVector
|
|
56
|
+
)
|
|
54
57
|
})
|
|
55
58
|
test('clockwise concave outline', () => {
|
|
56
|
-
const outline = [A,E,B,C,D]
|
|
57
|
-
const expectedNormalVector={x
|
|
58
|
-
expect(getNormalVectortoEdgeTowardPolygon(2,outline)).toBeCloseToVector(
|
|
59
|
+
const outline = [A, E, B, C, D]
|
|
60
|
+
const expectedNormalVector = { x: -1, y: 0, z: 0 }
|
|
61
|
+
expect(getNormalVectortoEdgeTowardPolygon(2, outline)).toBeCloseToVector(
|
|
62
|
+
expectedNormalVector
|
|
63
|
+
)
|
|
59
64
|
})
|
|
60
65
|
test('anti-clockwise concave outline', () => {
|
|
61
|
-
const outline = [A,E,B,C,D]
|
|
62
|
-
const expectedNormalVector={x
|
|
63
|
-
expect(getNormalVectortoEdgeTowardPolygon(2,outline)).toBeCloseToVector(
|
|
66
|
+
const outline = [A, E, B, C, D]
|
|
67
|
+
const expectedNormalVector = { x: -1, y: 0, z: 0 }
|
|
68
|
+
expect(getNormalVectortoEdgeTowardPolygon(2, outline)).toBeCloseToVector(
|
|
69
|
+
expectedNormalVector
|
|
70
|
+
)
|
|
64
71
|
})
|
|
65
72
|
test('clockwise concave outline', () => {
|
|
66
|
-
const outline = [A,E,B,C,D]
|
|
67
|
-
const expectedNormalVector={x:1,y:0,z:0}
|
|
68
|
-
expect(getNormalVectortoEdgeTowardPolygon(4,outline)).toBeCloseToVector(
|
|
73
|
+
const outline = [A, E, B, C, D]
|
|
74
|
+
const expectedNormalVector = { x: 1, y: 0, z: 0 }
|
|
75
|
+
expect(getNormalVectortoEdgeTowardPolygon(4, outline)).toBeCloseToVector(
|
|
76
|
+
expectedNormalVector
|
|
77
|
+
)
|
|
69
78
|
})
|
|
70
79
|
test('anti-clockwise concave on first outline', () => {
|
|
71
|
-
const outline = [A,F,G,B,C,D]
|
|
72
|
-
const expectedNormalVector={x:0,y:1,z:0}
|
|
73
|
-
expect(getNormalVectortoEdgeTowardPolygon(0,outline)).toBeCloseToVector(
|
|
80
|
+
const outline = [A, F, G, B, C, D]
|
|
81
|
+
const expectedNormalVector = { x: 0, y: 1, z: 0 }
|
|
82
|
+
expect(getNormalVectortoEdgeTowardPolygon(0, outline)).toBeCloseToVector(
|
|
83
|
+
expectedNormalVector
|
|
84
|
+
)
|
|
74
85
|
})
|
|
75
|
-
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { fromSphericalCoordinatesToENU } from '../../index'
|
|
2
|
+
function toBeCloseToVector(received, expected, tolerance = 0.01) {
|
|
3
|
+
const recPoint = received
|
|
4
|
+
const expPoint = expected
|
|
5
|
+
|
|
6
|
+
if (
|
|
7
|
+
Math.abs(recPoint.x - expPoint.x) > tolerance ||
|
|
8
|
+
Math.abs(recPoint.y - expPoint.y) > tolerance ||
|
|
9
|
+
Math.abs(recPoint.z - expPoint.z) > tolerance
|
|
10
|
+
) {
|
|
11
|
+
return {
|
|
12
|
+
message: () =>
|
|
13
|
+
`Expected points to be close, but found ${JSON.stringify(
|
|
14
|
+
recPoint
|
|
15
|
+
)} and ${JSON.stringify(expPoint)}`,
|
|
16
|
+
pass: false,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
message: () => `Points are close within the given tolerance`,
|
|
22
|
+
pass: true,
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
expect.extend({ toBeCloseToVector })
|
|
26
|
+
describe('fromSphericalCoordinatesToENU function', () => {
|
|
27
|
+
test('rising on east', () => {
|
|
28
|
+
let radius = 100
|
|
29
|
+
let altitude = 0
|
|
30
|
+
let azimuth = (-90 * Math.PI) / 180
|
|
31
|
+
|
|
32
|
+
expect(
|
|
33
|
+
fromSphericalCoordinatesToENU(radius, altitude, azimuth)
|
|
34
|
+
).toBeCloseToVector({ x: 100, y: 0, z: 0 })
|
|
35
|
+
})
|
|
36
|
+
test('setting on west', () => {
|
|
37
|
+
let radius = 100
|
|
38
|
+
let altitude = 0
|
|
39
|
+
let azimuth = (90 * Math.PI) / 180
|
|
40
|
+
|
|
41
|
+
expect(
|
|
42
|
+
fromSphericalCoordinatesToENU(radius, altitude, azimuth)
|
|
43
|
+
).toBeCloseToVector({ x: -100, y: 0, z: 0 })
|
|
44
|
+
})
|
|
45
|
+
test('high noon', () => {
|
|
46
|
+
let radius = 100
|
|
47
|
+
let altitude = (90 * Math.PI) / 180
|
|
48
|
+
let azimuth = 0
|
|
49
|
+
expect(
|
|
50
|
+
fromSphericalCoordinatesToENU(radius, altitude, azimuth)
|
|
51
|
+
).toBeCloseToVector({ x: 0, y: 0, z: 100 })
|
|
52
|
+
})
|
|
53
|
+
test('winter noon', () => {
|
|
54
|
+
let radius = 100
|
|
55
|
+
let altitude = (45 * Math.PI) / 180
|
|
56
|
+
let azimuth = 0
|
|
57
|
+
|
|
58
|
+
expect(
|
|
59
|
+
fromSphericalCoordinatesToENU(radius, altitude, azimuth)
|
|
60
|
+
).toBeCloseToVector({ x: 0, y: -70.71, z: 70.71 })
|
|
61
|
+
})
|
|
62
|
+
})
|