이 조금 과잉, 그러나 당신의 교차점을 찾을 수있는 적절한 방법이 될 수있다, 첫 번째 덩어리에서 어떤 세그먼트가 어떤 세그먼트와 교차하는지 확인하는 것입니다 두 번째 청크에서.
나 자신에게 약간의 데이터를 쉽게하는 prolate cycloid의 조각을 만들려고하고, 그리고 here 유사하게 감소로 증가하는 넘겼습니다 Y 좌표 곳에 장소를 찾을 것입니다 :
a, b = 1, 2
phi = np.linspace(3, 10, 100)
x = a*phi - b*np.sin(phi)
y = a - b*np.cos(phi)
y_growth_flips = np.where(np.diff(np.diff(y) > 0))[0] + 1
plt.plot(x, y, 'rx')
plt.plot(x[y_growth_flips], y[y_growth_flips], 'bo')
plt.axis([2, 12, -1.5, 3.5])
plt.show()
![enter image description here](https://i.stack.imgur.com/3vUrI.png)
을
P0
에서 P1
까지가는 세그먼트와 Q0
에서 Q1
까지가는 세그먼트가있는 경우 벡터 수식을 해결하면 교차점을 찾을 수 있습니다3210이고, 두 세그먼트는 실제로 s
과 t
이 모두 [0, 1]
인 경우 교차합니다.모든 세그먼트이 밖으로 시도 : 내 시스템에서
x_down = x[y_growth_flips[0]:y_growth_flips[1]+1]
y_down = y[y_growth_flips[0]:y_growth_flips[1]+1]
x_up = x[y_growth_flips[1]:y_growth_flips[2]+1]
y_up = y[y_growth_flips[1]:y_growth_flips[2]+1]
def find_intersect(x_down, y_down, x_up, y_up):
for j in xrange(len(x_down)-1):
p0 = np.array([x_down[j], y_down[j]])
p1 = np.array([x_down[j+1], y_down[j+1]])
for k in xrange(len(x_up)-1):
q0 = np.array([x_up[k], y_up[k]])
q1 = np.array([x_up[k+1], y_up[k+1]])
params = np.linalg.solve(np.column_stack((p1-p0, q0-q1)),
q0-p0)
if np.all((params >= 0) & (params <= 1)):
return p0 + params[0]*(p1 - p0)
>>> find_intersect(x_down, y_down, x_up, y_up)
array([ 6.28302264, 1.63658676])
crossing_point = find_intersect(x_down, y_down, x_up, y_up)
plt.plot(crossing_point[0], crossing_point[1], 'ro')
plt.show()
![enter image description here](https://i.stack.imgur.com/Pdsq1.png)
, 이것은 아마도 충분한 약 20 초고속없는 초당 교차로,하지만를 처리 할 수있는 것은 모든 이제 다음 그래프를 분석합니다. 당신은 2 × 2 선형 시스템의 솔루션을 벡터화하여 일을 spped 할 수 있습니다 :
def find_intersect_vec(x_down, y_down, x_up, y_up):
p = np.column_stack((x_down, y_down))
q = np.column_stack((x_up, y_up))
p0, p1, q0, q1 = p[:-1], p[1:], q[:-1], q[1:]
rhs = q0 - p0[:, np.newaxis, :]
mat = np.empty((len(p0), len(q0), 2, 2))
mat[..., 0] = (p1 - p0)[:, np.newaxis]
mat[..., 1] = q0 - q1
mat_inv = -mat.copy()
mat_inv[..., 0, 0] = mat[..., 1, 1]
mat_inv[..., 1, 1] = mat[..., 0, 0]
det = mat[..., 0, 0] * mat[..., 1, 1] - mat[..., 0, 1] * mat[..., 1, 0]
mat_inv /= det[..., np.newaxis, np.newaxis]
import numpy.core.umath_tests as ut
params = ut.matrix_multiply(mat_inv, rhs[..., np.newaxis])
intersection = np.all((params >= 0) & (params <= 1), axis=(-1, -2))
p0_s = params[intersection, 0, :] * mat[intersection, :, 0]
return p0_s + p0[np.where(intersection)[0]]
네, 지저분한, 그러나 그것은 작동, 그래서 × 100 배 빠르게 수행합니다 당신의 연결의 어느
find_intersect(x_down, y_down, x_up, y_up)
Out[67]: array([ 6.28302264, 1.63658676])
find_intersect_vec(x_down, y_down, x_up, y_up)
Out[68]: array([[ 6.28302264, 1.63658676]])
%timeit find_intersect(x_down, y_down, x_up, y_up)
10 loops, best of 3: 66.1 ms per loop
%timeit find_intersect_vec(x_down, y_down, x_up, y_up)
1000 loops, best of 3: 375 us per loop
을 나를 위해 일하고있다. – gggg
matplotlib로 확대 효과를 얻은 방법이 궁금합니다 –