@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_maths",
3
- "version": "8.16.1",
3
+ "version": "8.19.0",
4
4
  "author": "Eturnity Team",
5
5
  "main": "src/index.js",
6
6
  "private": false,
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
+ })