У меня есть координаты некоторых точек. Моя задача — получить направление этих точек и найти, где будущие возможные точки будут расположены в рассчитанном направлении. Для этого я запланировал следующее:
Я использую следующие коды, чтобы соответствовать строке
from matplotlib import pyplot as plt
from scipy import stats
x = [1,2,3,2,5,6,7,8,9,10]
y = [2,4,11,8,8,18,14,11,18,20]
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
line = [slope*i+intercept for i in x]
plt.plot(x, line)
Предположим, две точки на подобранной линии — это (9,17) и (10,19). Как я могу нарисовать четверть круга в (10,19) с радиусом 5 в направлении линии?
В конечном итоге у меня будет местоположение точки, и я должен проверить, попадает ли точка в четверть круга или нет, я предполагаю, что это можно сделать с помощью shapely.






Чтобы проверить, попадает ли точка п в четверть круга, вы можете найти расстояние от конца линии Б (длина АД) и косинус угла между вектором направления единичной линии г и вектором АД.
distance = sqrt(BP.x * BP.x + BP.y * BP.y)
cosine = (d.x * BP.x + d.y * BP.y) / (distance)
if (distance < radius) and (cosine >= sqrt(2)/2)
P in sector
Единичный вектор г может быть рассчитан на основе данных, которые у вас уже есть:
d.x = sign(slope) * sqrt(1/(1+slope**2))
d.y = sqrt(slope**2/1+slope**2)
Обратите внимание, что знак компонентов четко не определен (поскольку два противоположных вектора имеют одинаковый наклон)
Для решения основного вопроса - конечные точки дуги могут быть рассчитаны с использованием повернутого (на Пи / 4) вектора направления.
cf = sqrt(2)/2
arcbegin.x = b.x + radius * d.x * cf - radius * d.y * cf
arcbegin.y = b.y + radius * d.x * cf + radius * d.y * cf
arcend.x = b.x + radius * d.x * cf + radius * d.y * cf
arcend.y = b.y - radius * d.x * cf + radius * d.y * cf
Я думаю, что вам следует реализовать арку следующим образом. (Я только что показал вашу недостающую логику, вам нужно добавить свой сюжет). Удачи
from matplotlib import pyplot as plt
from scipy import stats
x = [1,2,3,2,5,6,7,8,9,10]
y = [2,4,11,8,8,18,14,11,18,20]
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
line = [slope*i + intercept for i in x]
# Logic Part *****************************************************
from matplotlib.patches import Arc
import math
# circuile parameters
R = 5
xEnd,yEnd = 10 , 20 #Your end point cords, in your case Point B
LowerThita = math.degrees(math.atan(slope)) - 45
UpperThita = math.degrees(math.atan(slope)) + 45
# Figure setup
fig, ax = plt.subplots()
ax.set_xlim(-R , (R+xEnd) * 1.05)
ax.set_ylim(-R , (R+yEnd) * 1.05)
# Arcs
ax.add_patch(Arc((xEnd, yEnd), R, R,
theta1=LowerThita, theta2=UpperThita, edgecolor='k'))
plt.show()
#NOTE : You Haft to add your line to the plot
Вместо того, чтобы вычислять всю математику самостоятельно, вы можете делегировать ее Shapely.
Сначала создайте круг в конце строки с помощью buffer:
from shapely.affinity import rotate
from shapely.geometry import LineString, Point
from shapely.ops import split
a = (10, 20)
b = (15, 30)
ab = LineString([a, b]) # the line you got from linear regression
circle = Point(b).buffer(5)
Теперь давайте создадим две новые линии, которые будут разграничивать область нужного нам сектора. Мы сделаем это, повернув линию с помощью rotate на 135º в каждом направлении, так что центральный угол сектора будет 360º - 135º * 2 = 90º, что составляет четверть окружности:
left_border = rotate(ab, -135, origin=b)
right_border = rotate(ab, 135, origin=b)
Наконец, используйте split, чтобы получить сектор:
splitter = LineString([*left_border.coords, *right_border.coords[::-1]])
sector = split(circle, splitter)[1]
Отсюда вы можете легко узнать, лежит ли точка внутри сектора, используя метод contains. Например:
points_of_interest = [Point(16, 32), Point(12, 30)]
for point in points_of_interest:
print(sector.contains(point))
# True
# False
Рад, что это помогло. Оба JupyterLab и Jupyter Notebook автоматически создают эти изображения по мере вывода ячеек. Чтобы рисовать сложные фигуры, я объединяю их в недокументированном GeometryCollection классе, например: from shapely.geometry import GeometryCollection; GeometryCollection([some_line, some_polygon, etc...]), и он просто дает эти красивые фигуры.
Метод, который вы показали здесь, на самом деле помогает мне избежать всех дополнительных математических уравнений, которые я пишу сам. Ваш ответ феноменален. Мне было интересно, как вы рисуете красивый объект как фигуру. Я могу сделать это только для многоугольника, взяв их внешние точки.