Лучший способ повернуть (и перевести) набор точек в python

У меня есть два набора точек (x,y), которые я построил с помощью matplotlib.

Просто визуально я вижу, что между ними есть какая-то ротация.

Я хотел бы повернуть один набор точек вокруг определенной точки (хотел бы попробовать несколько точек вращения) и снова построить их.

Как лучше всего повернуть указанный набор точек с помощью python?

Я читал, что, возможно, можно использовать shapely, но простой пример поможет мне понять, как это сделать.

Обратите внимание, что «применить заданный поворот к заданному облаку точек» и «найти поворот, который лучше всего отображает заданное облако точек в другое заданное облако точек» — это две разные задачи.

Stef 21.11.2022 15:18

Чтобы найти наилучшее преобразование между двумя облаками точек, одним из способов является использование алгоритма Iterative Closest Point . Например, используя open3d.registration.registration_icp

Stef 21.11.2022 15:28

Один важный вопрос: вы уже знаете, какая точка из первого набора должна быть сопоставлена ​​с какой точкой второго набора? То есть, у вас есть точки A, B, C, D в первом наборе и A', B', C', D' во втором наборе, и вы хотите найти вращение, которое отображает A в A', B в B', C к C', D к D' и т.д.? Или у вас есть точки A, B, C, D в первом наборе и точки E, F, G, H во втором наборе, и вы не знаете, соответствует ли A E, F, G или H?

Stef 21.11.2022 15:30

@Stef К сожалению, две строки не имеют соответствия 1-1. На самом деле, повернув их, я хотел бы увидеть, насколько они разные.

KansaiRobot 21.11.2022 16:19

В общем, если вы не знаете соответствие или нет точного соответствия, ICP (итеративная ближайшая точка) может быть простым алгоритмом, который может работать. Но если вы уже знаете, что ваши облака точек представляют определенную форму, например линию, то, возможно, будет лучше найти преобразование, работая с представлением формы, а не с облаками точек. Возможно, RanSaC (консенсус случайной выборки) может быть полезен.

Stef 21.11.2022 16:21

@Stef ICP кажется действительно интересным. Завтра я попытаюсь найти простой пример этого, чтобы попробовать.

KansaiRobot 21.11.2022 16:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
6
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте numpy для хранения ваших очков

Например, если у вас есть массив nx2, каждая строка которого представляет собой точку, например

xy=np.array([[50, 60],
             [10, 30],
             [30, 10]])

Вы можете построить их так

plt.scatter(xy[:,0], xy[:,1])

А чтобы их повернуть, нужна матрица вращения

def rotateMatrix(a):
    return np.array([[np.cos(a), -np.sin(a)], [np.sin(a), np.cos(a)]])

Вы можете применить эту матрицу к своему xy набору очков, подобному этому

newxy = xy @ rotateMatrix(a).T

Обратите внимание, что я транспонирую матрицу вращения, чтобы сохранить точность. Но в этом случае из-за особой формы матрицы поворота вы можете сгенерировать непосредственно транспонированную матрицу, просто передав -a

newxy = xy @ rotateMatrix(-a)

Если вам не нужно вращать вокруг центра (x0,y0), отличного от (0,0), просто поверните не xy, а xy-(x0,y0) (то есть вектор смещения от центра к точкам), а затем добавьте это повернутое вектор к центру.

newxy = (xy-[x0,y0]) @ rotateMatrix(-a) + [x0,y0]

заявка

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib
import time

def rotateMatrix(a):
    return np.array([[np.cos(a), -np.sin(a)], [np.sin(a), np.cos(a)]])

xy=np.random.randint(0,100, (200,2))

fig=plt.figure()
plt.plot(xy[:,0], xy[:,1], 'o')
plt.xlim(-30,130)
plt.ylim(-50,110)

plotdata,=plt.plot(xy[:,0], xy[:,1],'o')

x0=20
y0=50

def anim(i):
   newxy=(xy-[x0,y0]) @ rotateMatrix(-2*i*np.pi/180) + [x0,y0]
   plotdata.set_data(newxy[:,0], newxy[:,1])
   return [plotdata]

theAnim=animation.FuncAnimation(fig, anim, interval=40, blit=False, frames=360, repeat=False)
#theAnim.save('rotate.nosync.gif')
plt.show()

Спасибо!. Быстрый вопрос. Это вращает точки вокруг (0,0), верно? Есть ли способ включить вращение вокруг другой точки? Я полагаю, что матрица вращения также должна включать эту информацию...

KansaiRobot 21.11.2022 16:35

@KansaiRobot Либо в матрице вращения. Но это означает наличие матрицы вращения 3x3 в однородных координатах, а также списка точек n×3 xy1. В вашем случае самый простой способ, вероятно, просто удалить центр из xy перед вращением и добавить его обратно после вращения. Я редактирую свой ответ соответственно

chrslg 21.11.2022 18:41

Другие вопросы по теме