@eturnity/eturnity_maths 8.16.1 → 8.19.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
package/src/geometry.js
CHANGED
|
@@ -413,6 +413,45 @@ export function getPointInsideOutline(vs, firstLevelHoles = []) {
|
|
|
413
413
|
}
|
|
414
414
|
return result
|
|
415
415
|
}
|
|
416
|
+
export function distanceTo2DPolyline(point, polyline) {
|
|
417
|
+
let minDistance = Infinity
|
|
418
|
+
if (polyline.length < 2) {
|
|
419
|
+
throw new Error('not enough points in polyline')
|
|
420
|
+
}
|
|
421
|
+
for (let i = 0; i < polyline.length - 1; i++) {
|
|
422
|
+
let A = polyline[i]
|
|
423
|
+
let B = polyline[i + 1]
|
|
424
|
+
const distance = distanceTo2DSegment(point, A, B)
|
|
425
|
+
if (distance < minDistance) {
|
|
426
|
+
minDistance = distance
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return minDistance
|
|
430
|
+
}
|
|
431
|
+
export function distanceTo2DSegment(point, A, B) {
|
|
432
|
+
const vectorAB = { x: B.x - A.x, y: B.y - A.y }
|
|
433
|
+
const vectorAP = { x: point.x - A.x, y: point.y - A.y }
|
|
434
|
+
const lengthABSquared = vectorAB.x * vectorAB.x + vectorAB.y * vectorAB.y
|
|
435
|
+
if (lengthABSquared === 0) {
|
|
436
|
+
return Math.sqrt(vectorAP.x * vectorAP.x + vectorAP.y * vectorAP.y)
|
|
437
|
+
}
|
|
438
|
+
const t =
|
|
439
|
+
(vectorAP.x * vectorAB.x + vectorAP.y * vectorAB.y) / lengthABSquared
|
|
440
|
+
if (t < 0) {
|
|
441
|
+
return Math.sqrt(vectorAP.x * vectorAP.x + vectorAP.y * vectorAP.y)
|
|
442
|
+
}
|
|
443
|
+
if (t > 1) {
|
|
444
|
+
const vectorBP = { x: point.x - B.x, y: point.y - B.y }
|
|
445
|
+
return Math.sqrt(vectorBP.x * vectorBP.x + vectorBP.y * vectorBP.y)
|
|
446
|
+
}
|
|
447
|
+
const projection = {
|
|
448
|
+
x: A.x + t * vectorAB.x,
|
|
449
|
+
y: A.y + t * vectorAB.y,
|
|
450
|
+
}
|
|
451
|
+
const dx = point.x - projection.x
|
|
452
|
+
const dy = point.y - projection.y
|
|
453
|
+
return Math.sqrt(dx * dx + dy * dy)
|
|
454
|
+
}
|
|
416
455
|
|
|
417
456
|
export function distanceToEdge2D(M, A, B) {
|
|
418
457
|
const pA = { x: A.x, y: A.y, z: 0 }
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { distanceTo2DSegment } from '../../index'
|
|
2
|
+
|
|
3
|
+
describe('distanceTo2DSegment function', () => {
|
|
4
|
+
test('top middle', () => {
|
|
5
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
6
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
7
|
+
const point = { x: 5, y: 10, z: 0 }
|
|
8
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(10, 4)
|
|
9
|
+
})
|
|
10
|
+
test('bottom', () => {
|
|
11
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
12
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
13
|
+
const point = { x: 5, y: -10, z: 0 }
|
|
14
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(10, 4)
|
|
15
|
+
})
|
|
16
|
+
test('diagonal', () => {
|
|
17
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
18
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
19
|
+
const point = { x: -3, y: 4, z: 0 }
|
|
20
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(5, 4)
|
|
21
|
+
})
|
|
22
|
+
test('point aligned with A and B', () => {
|
|
23
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
24
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
25
|
+
const point = { x: -10, y: 0, z: 0 }
|
|
26
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(10, 4)
|
|
27
|
+
})
|
|
28
|
+
test('point aligned with A and B right', () => {
|
|
29
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
30
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
31
|
+
const point = { x: 20, y: 0, z: 0 }
|
|
32
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(10, 4)
|
|
33
|
+
})
|
|
34
|
+
test('AB in diagonal', () => {
|
|
35
|
+
const A = { x: 0, y: 10, z: 0 }
|
|
36
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
37
|
+
const point = { x: 0, y: 0, z: 0 }
|
|
38
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(7.07106, 4)
|
|
39
|
+
})
|
|
40
|
+
test('point and A and A', () => {
|
|
41
|
+
const A = { x: 0, y: 10, z: 0 }
|
|
42
|
+
const point = { x: 0, y: 0, z: 0 }
|
|
43
|
+
expect(distanceTo2DSegment(point, A, A)).toBeCloseTo(10, 4)
|
|
44
|
+
})
|
|
45
|
+
test('point vertical to B', () => {
|
|
46
|
+
const A = { x: 0, y: 0, z: 0 }
|
|
47
|
+
const B = { x: 10, y: 0, z: 0 }
|
|
48
|
+
const point = { x: 10, y: 10, z: 0 }
|
|
49
|
+
expect(distanceTo2DSegment(point, A, B)).toBeCloseTo(10, 4)
|
|
50
|
+
})
|
|
51
|
+
})
|