#python #numpy #геометрия #matplotlib #python_27
Пользуясь данный вопросом: https://stackoverflow.com/questions/57312462/how-to-find-and-draw-the-intersection-points-of-contour-shapes В случае, когда коника представима в виде гиперболы (p,q,v,k,b=5,7,2,3,4 #hyperbole) программа выдает точку пересечения между прямой, проходящей через точку V и коникой. Результат работы программы для гиперболы: Однако, в случае, когда коника представлена в виде эллипса (p,q,v,k,b=5,0.7,2,3,4 # ellipse) кроме точек, находящихся на границе коники отображаются точки, находящиеся внутри эллипса. Результат работы программы для эллипса: Мой код: import numpy as np import matplotlib.pyplot as plt def find_roots(x, y): s = np.abs(np.diff(np.sign(y))).astype(bool) return x[:-1][s] + np.diff(x)[s] / (np.abs(y[1:][s] / y[:-1][s]) + 1) # p,q,v,k,b=5,7,2,3,4 #hyperbole p,q,v,k,b=5,0.7,2,3,4 # ellipse if(((2 * b * k * p) - (2 * b * k * q) + (k * k) - (b * b * q * q)) > 0): print("conic is an ellipse") elif (((2 * b * k * p) - (2 * b * k * q) + (k * k) - (b * b * q * q)) == 0): print("conic is a parabola") else: print("conic is a hyperbole") X = np.arange(-50, 50, 0.05) plt.plot(-v, 0) plt.scatter(-v, 0, color='red', marker='o') plt.text(-v, 0.8, "V", horizontalalignment="center") xmin, xmax, ymin, ymax = -10, 10, -10, 10 ax = plt.gca() ax.get_xlim() ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) ax.spines['left'].set_position('center') ax.spines['bottom'].set_position('center') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) x, y = np.meshgrid(X, X) l = b * x + b * v - v * y vb = plt.contour(x, y, l, [0], colors='red') conic = x * x * b * 2 * p * k - x * x * b * 2 * q * k + x * x * k * k + y * y - b * 2 * y + 2 * b * q * x * y cnc = plt.contour(x, y, (conic), [0], colors='blue') c = cnc.collections[0].get_paths()[-1] v0 = c.vertices x1 = np.sort(v0[:, 0]) y1 = v0[np.argsort(v0[:, 0]), 1] vb1 = vb.collections[0].get_paths()[0] v1 = vb1.vertices x2 = np.sort(v1[:, 0]) y2 = v1[np.argsort(v1[:, 0]), 1] x = np.linspace(max(x1.min(), x2.min()), min(x1.max(), x2.max()), 1000) y1i = np.interp(x, x1, y1) y2i = np.interp(x, x2, y2) x_intersect = find_roots(x, y1i - y2i) y_intersect = np.interp(x_intersect, x, y1i) plt.plot(x_intersect, y_intersect, marker="X", ms=5, color="limegreen") plt.show() Как можно отобразить только точки пересечения прямой. проходящей через точку V и границы коники (эллипса)?
Ответы
Ответ 1
Задачу можно значительно упростить если работать с двумерными объектами: def graphs_intersection_pos(g1, g2): return np.argwhere(np.diff(np.sign(g1 - g2))).ravel() def line(x): return v*x + b X = np.arange(-50, 50, 0.05) plt.plot(-v, 0) plt.scatter(-v, 0, color='red', marker='o') plt.text(-v, 0.8, "V", horizontalalignment="center") xmin, xmax, ymin, ymax = -10, 10, -10, 10 ax = plt.gca() ax.get_xlim() ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) ax.spines['left'].set_position('center') ax.spines['bottom'].set_position('center') ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) x, y = np.meshgrid(X, X) l = b * x + b * v - v * y vb = plt.contour(x, y, l, [0], colors='red') conic = x * x * b * 2 * p * k - x * x * b * 2 * q * k + x * x * k * k + y * y - b * 2 * y + 2 * b * q * x * y cnc = plt.contour(x, y, (conic), [0], colors='blue') plt.plot(X, line(X), color="red") # X,Y координаты коники / эллипса / контура coords = cnc.allsegs[0][0] # точки прямой должны соответствовать X значениям эллипса x_line = coords[:, 0] y_line = line(x_line) # находим индексы точек пересечения idx = graphs_intersection_pos(coords[:, 1], y_line) plt.scatter(x_line[idx], y_line[idx], color="green", s=50)
Комментариев нет:
Отправить комментарий