Страница 1 из 1

Определить точку разворота

Добавлено: 03 май 2021, 23:30
Skywalker
Коллеги, подскажите пожалуйста, каким образом можно определить подобные точки разворота (перегиба), желательно на питоне.

Re: Определить точку разворота

Добавлено: 04 май 2021, 00:08
gamm
Посчитать угол между последовательными сегментами. В простейшем случае - знак скалярного произведения, чтобы определить угол тупой или острый. Можно даже в Ёкселе.

Re: Определить точку разворота

Добавлено: 04 май 2021, 13:24
gamm
если дрон дрыгается, то для повышения устойчивости может понадобится экспоненциальное сглаживание векторов (или просто сравнение среднего из 5-7 векторов до анализируемой точки, и столько же после).

Re: Определить точку разворота

Добавлено: 05 май 2021, 12:59
Skywalker
gamm, дрон действительно дрыгается.
Выкладываю работающий в моём случае способ, может быть кому-нибудь пригодится при решении сходных задач. Исходные данные читаются из файла coord.xlsx. Использовал алгоритм Рамера–Дугласа–Пекера и вычисление разницы азимутов между двумя отрезками.

Код: Выделить всё

import pyproj
from rdp import rdp
from openpyxl import load_workbook

xlssourse = 'coord.xlsx'
wbsource = load_workbook(xlssourse)
sheetsource = wbsource['Лист1']

PointList = []
geodesic = pyproj.Geod(ellps='WGS84')

row = 2
fileId = sheetsource.cell(column=1, row=row).value

while fileId is not None:
    long = sheetsource.cell(column=1, row=row).value
    lat = sheetsource.cell(column=2, row=row).value
    if (type(long) == float) and (type(lat) == float):
        if [long, lat] not in PointList:
            PointList.append([long, lat])
    row += 1
    fileId = sheetsource.cell(column=1, row=row).value

PointListRdp = rdp(PointList, epsilon=0.0000005)

row = 1
for element in PointListRdp:
    pntOneX = element[0]
    pntOneY = element[1]
    if ('pntTwoX' in locals()) and ('pntTwoY' in locals()):
        cur_azimuth, back_azimuth, distance = geodesic.inv(pntOneX, pntOneY, pntTwoX, pntTwoY)
        if 'new_azimuth' in locals():
            dif_azimuth = new_azimuth - cur_azimuth
            if (abs(dif_azimuth) > 120) and (abs(dif_azimuth) < 240):
                print(pntTwoX, pntTwoY)
        new_azimuth = cur_azimuth
    pntTwoX = pntOneX
    pntTwoY = pntOneY
    row += 1