Đây có thể là quá mức cần thiết chút, nhưng cách thích hợp để tìm giao điểm của bạn, một khi bạn đã chia tay đường cong của bạn vào khối, là để xem nếu bất kỳ phân đoạn từ đoạn đầu tiên giao cắt với bất kỳ phân đoạn từ đoạn thứ hai.
Tôi sẽ làm cho bản thân mình một số dữ liệu dễ dàng, một mảnh của một prolate cycloid, và đang đi tìm những nơi mà y phối hợp flips từ tăng để giảm tương tự như here:
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()
Nếu bạn có hai đoạn, một đoạn đi từ điểm P0
đến P1
và một đoạn khác đi từ điểm Q0
đến Q1
, bạn có thể tìm điểm giao nhau của chúng bằng cách giải phương trình vectơ P0 + s*(P1-P0) = Q0 + t*(Q1-Q0)
và hai phân đoạn thực sự giao nhau nếu cả hai s
và t
đều ở trong [0, 1]
.Cố gắng này ra cho tất cả các phân đoạn:
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()
Trên hệ thống của tôi, điều này có thể xử lý khoảng 20 nút giao thông mỗi giây, mà không phải là siêu nhanh, nhưng có lẽ đủ để phân tích đồ thị tất cả bây giờ và sau đó. Bạn có thể spped số bằng những giải pháp của các hệ thống 2x2 tuyến tính vectorizing:
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]]
Vâng, nó lộn xộn, nhưng nó hoạt động, và làm nhanh hơn lần để x100:
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
Không liên kết của bạn đang làm việc cho tôi. – gggg
Tôi tự hỏi làm thế nào bạn đạt được hiệu ứng zoom-in với matplotlib –