-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathintersection.py
83 lines (69 loc) · 2.15 KB
/
intersection.py
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
"""
Intersection of two curves
Source: https://github.com/sukhbinder/intersection
"""
import numpy as np
def _rect_inter_inner(x1, x2):
n1 = x1.shape[0]-1
n2 = x2.shape[0]-1
X1 = np.c_[x1[:-1], x1[1:]]
X2 = np.c_[x2[:-1], x2[1:]]
S1 = np.tile(X1.min(axis=1), (n2, 1)).T
S2 = np.tile(X2.max(axis=1), (n1, 1))
S3 = np.tile(X1.max(axis=1), (n2, 1)).T
S4 = np.tile(X2.min(axis=1), (n1, 1))
return S1, S2, S3, S4
def _rectangle_intersection_(x1, y1, x2, y2):
S1, S2, S3, S4 = _rect_inter_inner(x1, x2)
S5, S6, S7, S8 = _rect_inter_inner(y1, y2)
C1 = np.less_equal(S1, S2)
C2 = np.greater_equal(S3, S4)
C3 = np.less_equal(S5, S6)
C4 = np.greater_equal(S7, S8)
ii, jj = np.nonzero(C1 & C2 & C3 & C4)
return ii, jj
def intersection(x1, y1, x2, y2):
"""
Intersections of curves.
Computes the (x,y) locations where two curves intersect. The curves
can be broken with NaNs or have vertical segments.
usage:
x,y=intersection(x1,y1,x2,y2)
Example:
a, b = 1, 2
phi = np.linspace(3, 10, 100)
x1 = a*phi - b*np.sin(phi)
y1 = a - b*np.cos(phi)
x2=phi
y2=np.sin(phi)+2
x,y=intersection(x1,y1,x2,y2)
plt.plot(x1,y1,c='r')
plt.plot(x2,y2,c='g')
plt.plot(x,y,'*k')
plt.show()
"""
ii, jj = _rectangle_intersection_(x1, y1, x2, y2)
n = len(ii)
dxy1 = np.diff(np.c_[x1, y1], axis=0)
dxy2 = np.diff(np.c_[x2, y2], axis=0)
T = np.zeros((4, n))
AA = np.zeros((4, 4, n))
AA[0:2, 2, :] = -1
AA[2:4, 3, :] = -1
AA[0::2, 0, :] = dxy1[ii, :].T
AA[1::2, 1, :] = dxy2[jj, :].T
BB = np.zeros((4, n))
BB[0, :] = -x1[ii].ravel()
BB[1, :] = -x2[jj].ravel()
BB[2, :] = -y1[ii].ravel()
BB[3, :] = -y2[jj].ravel()
for i in range(n):
try:
T[:, i] = np.linalg.solve(AA[:, :, i], BB[:, i])
except Exception:
T[:, i] = np.NaN
in_range = (T[0, :] >= 0) & (T[1, :] >= 0) & (T[0, :] <= 1) & (
T[1, :] <= 1)
xy0 = T[2:, in_range]
xy0 = xy0.T
return xy0[:, 0], xy0[:, 1]