Вычислить угол (градус) прямой линии

Я пытаюсь определить угол в градусах прямой линии из двух точек, я нашел много решений в Интернете, но ни одно из них не сработало для меня, рассмотрим этот фрагмент кода

import matplotlib.pyplot as plt
data = np.array([7405.,7447.4,7433.99,7410.,7443.15,7429.4,7590.03,7550.,7566.32,7619.62,7549.71,7551.8,7530,7522.99,7499.75,7453.99,7542.16,7564.,7552.77,7552])
y = [7606.672474,7570.240928]
plt.plot(data)
plt.plot([6,17], y)
plt.show()

введите здесь описание изображения

Целевая линия y должна быть около -5 градусов, просто глядя на нее. Похоже, что большинство онлайн-решений предполагают, что мы можем найти угол, выполнив

degree = np.math.atan2(y[-1] - y[0], x[-1] - x[0])
degree = np.degrees(degree)

Я опустил другие значения y только до первой и последней точки для простоты, поэтому часть x[-1] - x[0] здесь будет 11 = 17-6, что является длиной линии y по оси x, это то, что предлагает большинство онлайн-решений, однако все подходы не смогли получить правильный угол для этого, я должен отметить, что во время моих тестов некоторые подходы, казалось, давали правильный угол для данного блока данных, например, в то время как полностью терпели неудачу в другом блоке данных, таком как

data = [52.3384984,53.04757978,52.04276249,51.77348257,49.93056673,52.24062341,55.74022485,60.77761392,60.89290148,60.1995072,60.40524964,59.00590344,59.67589831,56.49266698,49.02464746,51.53876823,57.77368203,59.48092106,56.63155446,56.0648491 ]
y = [51.337288,50.331895]
plt.plot(data)
plt.plot([3,15], y)
plt.show()

Я также пытался нормализовать данные по минимуму и максимуму, но безуспешно, поэтому, учитывая, что у нас есть первая и последняя точки линии и ее длина, как мы можем или возможно определить ее угол в градусах?


person 0x3h    schedule 15.02.2020    source источник
comment
soh-cah-toa... sin = противоположный/гипотенуза, cos = смежный/гипотенуза, tan = противоположный/прилегающий. . . а так как длина это гипотенуза, то у вас есть и противоположная и прилежащая. . . любой метод будет работать, я думаю? См.: hyperphysics.phy-astr.gsu.edu/hbase/ttrig.html< /а>   -  person neutrino_logic    schedule 15.02.2020


Ответы (1)


Есть два аспекта, которые вам нужно понять. Первый рассчитывается на основе данных, второй рассчитывается на основе рисунка.

Первый

Код, который вы написали, вычисляет первый:

degree = np.math.atan2(y[-1] - y[0], x[-1] - x[0])
degree = np.degrees(degree)

It's delta_y = y[-1] - y[0] = -36.43, delta_x = x[-1] - x[0] = 11

degree = -73.20 которые имеют смысл, если вы нарисуете в уме треугольник.

Второй

Однако вы можете спросить меня, что вы наблюдаете линию около -5 градусов. Это второй, который включает в себя вычисление коэффициента отображения (обратите внимание, что ось y и ось x имеют разную длину единицы измерения в дюймах). Здесь я нашел отдельный вопрос, чтобы помочь вам рассчитать это.

from operator import sub
def get_aspect(ax):
    # Total figure size
    figW, figH = ax.get_figure().get_size_inches()
    # Axis size on figure
    _, _, w, h = ax.get_position().bounds
    # Ratio of display units
    disp_ratio = (figH * h) / (figW * w)
    # Ratio of data units
    # Negative over negative because of the order of subtraction
    data_ratio = sub(*ax.get_ylim()) / sub(*ax.get_xlim())

    return disp_ratio / data_ratio

Таким образом, вам нужно умножить это соотношение, чтобы получить манхэттенское расстояние от конечных точек линии.

ax = plt.gca()
ratio = get_aspect(ax)
degree = np.math.atan2((y[-1] - y[0])*ratio, x[-1] - x[0])
degree = np.degrees(degree)

Результат равен -4,760350735146195, что примерно равно -5.

person Ke Zhang    schedule 15.02.2020
comment
Интересно, я пробовал с разными данными, но, похоже, не получается, например: y = [7533, 7638] с длиной 7=[5,12] изображение дает 5,3°, а выглядит почти 45° - person 0x3h; 16.02.2020
comment
Нормализация y к диапазону x (0-19), делая их одной и той же единицы измерения/длины, дает прямой угол, используя только стандартное уравнение degrees(atan2(y2-y1,x2-x1)) - person 0x3h; 16.02.2020
comment
@ 0x3h Я не совсем согласен с тем, что ваше соотношение является таким же образцом, как единица / длина. Но я думаю, что вы правы. Что-то я упомянул неправильно. atan2 не является линейным, поэтому перед вычислением atan2 необходимо использовать отношение. Я обновил код. Теперь это должно иметь смысл в обоих случаях. - person Ke Zhang; 16.02.2020
comment
Отлично, большое спасибо, теперь он дает 11,23, что является реальным углом, как мы его видим ссылка - person 0x3h; 17.02.2020