| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 |
1×
1×
7×
7×
7×
7×
7×
23×
7×
1×
11×
31×
4×
7×
7×
7×
7×
7×
2×
5×
5×
5×
11×
| import {
pointDistance
} from './Geometry';
import intersectPaths from 'path-intersection';
var round = Math.round,
max = Math.max;
function circlePath(center, r) {
var x = center.x,
y = center.y;
return [
['M', x, y],
['m', 0, -r],
['a', r, r, 0, 1, 1, 0, 2 * r],
['a', r, r, 0, 1, 1, 0, -2 * r],
['z']
];
}
function linePath(points) {
var segments = [];
points.forEach(function(p, idx) {
segments.push([ idx === 0 ? 'M' : 'L', p.x, p.y ]);
});
return segments;
}
var INTERSECTION_THRESHOLD = 10;
function getBendpointIntersection(waypoints, reference) {
var i, w;
for (i = 0; (w = waypoints[i]); i++) {
if (pointDistance(w, reference) <= INTERSECTION_THRESHOLD) {
return {
point: waypoints[i],
bendpoint: true,
index: i
};
}
}
return null;
}
function getPathIntersection(waypoints, reference) {
var intersections = intersectPaths(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints));
var a = intersections[0],
b = intersections[intersections.length - 1],
idx;
if (!a) {
// no intersection
return null;
}
Eif (a !== b) {
Iif (a.segment2 !== b.segment2) {
// we use the bendpoint in between both segments
// as the intersection point
idx = max(a.segment2, b.segment2) - 1;
return {
point: waypoints[idx],
bendpoint: true,
index: idx
};
}
return {
point: {
x: (round(a.x + b.x) / 2),
y: (round(a.y + b.y) / 2)
},
index: a.segment2
};
}
return {
point: {
x: round(a.x),
y: round(a.y)
},
index: a.segment2
};
}
/**
* Returns the closest point on the connection towards a given reference point.
*
* @param {Array<Point>} waypoints
* @param {Point} reference
*
* @return {Object} intersection data (segment, point)
*/
export function getApproxIntersection(waypoints, reference) {
return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference);
}
|