Вращение#
- класс scipy.spatial.transform.Вращение#
Вращение в 3-х измерениях.
Этот класс предоставляет интерфейс для инициализации и представления вращений с помощью:
Кватернионы
Матрицы вращения
Векторы вращения
Модифицированные параметры Родригеса
Углы Эйлера
Углы Дэвенпорта (Обобщённые углы Эйлера)
Следующие операции с вращениями поддерживаются:
Применение к векторам
Композиция вращений
Инверсия вращения
Индексация вращения
Индексирование внутри вращения поддерживается, так как несколько преобразований вращения могут храниться в одном
Rotationэкземпляр.Чтобы создать
Rotationобъекты используютfrom_...методы (см. примеры ниже).Rotation(...)не предназначен для непосредственного создания экземпляра.- Атрибуты:
singleПредставляет ли этот экземпляр одно вращение.
Методы
__len__(self)Количество вращений, содержащихся в этом объекте.
from_quat(cls, quat, *[, scalar_first])Инициализация из кватернионов.
from_matrix(cls, matrix)Инициализировать из матрицы вращения.
from_rotvec(cls, rotvec[, degrees])Инициализация из векторов вращения.
from_mrp(cls, mrp)Инициализация из модифицированных параметров Родригеса (MRPs).
from_euler(cls, seq, angles[, degrees])Инициализация из углов Эйлера.
from_davenport(cls, axes, order, angles[, ...])Инициализировать из углов Дэвенпорта.
as_quat(self[, canonical, scalar_first])Представить в виде кватернионов.
as_matrix(self)Представить как матрицу вращения.
as_rotvec(self[, degrees])Представить как векторы вращения.
as_mrp(self)Представить как модифицированные параметры Родригеса (MRPs).
as_euler(self, seq[, degrees])Представить в виде углов Эйлера.
as_davenport(self, axes, order[, degrees])Представить как углы Дэвенпорта.
concatenate(cls, rotations)Объединить последовательность
Rotationобъектов в единый объект.apply(self, vectors[, inverse])Применить это вращение к набору векторов.
__mul__(self, Rotation other)Скомбинируйте это вращение с другим.
__pow__(self, float n, modulus)Скомбинировать это вращение с самим собой n раз.
inv(self)Инвертировать это вращение.
magnitude(self)Получить величину(ы) вращения(ий).
approx_equal(self, Rotation other[, atol, ...])Определить, приблизительно ли равен другой поворот данному.
mean(self[, weights])Получить среднее значение вращений.
reduce(self[, left, right, return_indices])Уменьшите это вращение с помощью предоставленных групп вращений.
create_group(cls, group[, axis])Создать группу 3D-вращений.
__getitem__(self, indexer)Извлечение вращения(ий) по заданному(ым) индексу(ам) из объекта.
identity(cls[, num])Получить тождественное вращение(я).
random(cls[, num, rng])Генерировать равномерно распределенные вращения.
align_vectors(cls, a, b[, weights, ...])Оценить вращение для оптимального выравнивания двух наборов векторов.
Смотрите также
Примечания
Добавлено в версии 1.2.0.
Примеры
>>> from scipy.spatial.transform import Rotation as R >>> import numpy as np
A
RotationЭкземпляр может быть инициализирован в любом из вышеуказанных форматов и преобразован в любой другой. Базовый объект не зависит от представления, используемого для инициализации.Рассмотрим вращение на 90 градусов против часовой стрелки вокруг оси z. Это соответствует следующему кватерниону (в формате скаляр-последний):
>>> r = R.from_quat([0, 0, np.sin(np.pi/4), np.cos(np.pi/4)])
Вращение может быть выражено в любом из других форматов:
>>> r.as_matrix() array([[ 2.22044605e-16, -1.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 2.22044605e-16, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) >>> r.as_rotvec() array([0. , 0. , 1.57079633]) >>> r.as_euler('zyx', degrees=True) array([90., 0., 0.])
Та же самая ротация может быть инициализирована с использованием матрицы вращения:
>>> r = R.from_matrix([[0, -1, 0], ... [1, 0, 0], ... [0, 0, 1]])
Представление в других форматах:
>>> r.as_quat() array([0. , 0. , 0.70710678, 0.70710678]) >>> r.as_rotvec() array([0. , 0. , 1.57079633]) >>> r.as_euler('zyx', degrees=True) array([90., 0., 0.])
Вектор вращения, соответствующий этому вращению, задается как:
>>> r = R.from_rotvec(np.pi/2 * np.array([0, 0, 1]))
Представление в других форматах:
>>> r.as_quat() array([0. , 0. , 0.70710678, 0.70710678]) >>> r.as_matrix() array([[ 2.22044605e-16, -1.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 2.22044605e-16, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) >>> r.as_euler('zyx', degrees=True) array([90., 0., 0.])
The
from_eulerметод довольно гибкий в диапазоне поддерживаемых форматов входных данных. Здесь мы инициализируем одно вращение вокруг одной оси:>>> r = R.from_euler('z', 90, degrees=True)
Опять же, объект не зависит от представления и может быть преобразован в любой другой формат:
>>> r.as_quat() array([0. , 0. , 0.70710678, 0.70710678]) >>> r.as_matrix() array([[ 2.22044605e-16, -1.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 2.22044605e-16, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) >>> r.as_rotvec() array([0. , 0. , 1.57079633])
Также возможно инициализировать несколько вращений в одном экземпляре с использованием любого из
from_...функций. Здесь мы инициализируем стек из 3 вращений, используяfrom_eulermethod:>>> r = R.from_euler('zyx', [ ... [90, 0, 0], ... [0, 45, 0], ... [45, 60, 30]], degrees=True)
Другие представления теперь также возвращают стек из 3 вращений. Например:
>>> r.as_quat() array([[0. , 0. , 0.70710678, 0.70710678], [0. , 0.38268343, 0. , 0.92387953], [0.39190384, 0.36042341, 0.43967974, 0.72331741]])
Применение указанных вращений к вектору:
>>> v = [1, 2, 3] >>> r.apply(v) array([[-2. , 1. , 3. ], [ 2.82842712, 2. , 1.41421356], [ 2.24452282, 0.78093109, 2.89002836]])
A
Rotationэкземпляр может быть проиндексирован и нарезан, как если бы это был один 1D массив или список:>>> r.as_quat() array([[0. , 0. , 0.70710678, 0.70710678], [0. , 0.38268343, 0. , 0.92387953], [0.39190384, 0.36042341, 0.43967974, 0.72331741]]) >>> p = r[0] >>> p.as_matrix() array([[ 2.22044605e-16, -1.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 2.22044605e-16, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) >>> q = r[1:3] >>> q.as_quat() array([[0. , 0.38268343, 0. , 0.92387953], [0.39190384, 0.36042341, 0.43967974, 0.72331741]])
Фактически его можно преобразовать в numpy.array:
>>> r_array = np.asarray(r) >>> r_array.shape (3,) >>> r_array[0].as_matrix() array([[ 2.22044605e-16, -1.00000000e+00, 0.00000000e+00], [ 1.00000000e+00, 2.22044605e-16, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
Несколько вращений могут быть скомпонованы с использованием
*оператор:>>> r1 = R.from_euler('z', 90, degrees=True) >>> r2 = R.from_rotvec([np.pi/4, 0, 0]) >>> v = [1, 2, 3] >>> r2.apply(r1.apply(v)) array([-2. , -1.41421356, 2.82842712]) >>> r3 = r2 * r1 # Note the order >>> r3.apply(v) array([-2. , -1.41421356, 2.82842712])
Вращение может быть составлено с самим собой с помощью
**оператор:>>> p = R.from_rotvec([1, 0, 0]) >>> q = p ** 2 >>> q.as_rotvec() array([2., 0., 0.])
Наконец, также возможно инвертировать вращения:
>>> r1 = R.from_euler('z', [90, 45], degrees=True) >>> r2 = r1.inv() >>> r2.as_euler('zyx', degrees=True) array([[-90., 0., 0.], [-45., 0., 0.]])
Следующая функция может использоваться для построения вращений с помощью Matplotlib, показывая, как они преобразуют стандартные оси координат x, y, z:
>>> import matplotlib.pyplot as plt
>>> def plot_rotated_axes(ax, r, name=None, offset=(0, 0, 0), scale=1): ... colors = ("#FF6666", "#005533", "#1199EE") # Colorblind-safe RGB ... loc = np.array([offset, offset]) ... for i, (axis, c) in enumerate(zip((ax.xaxis, ax.yaxis, ax.zaxis), ... colors)): ... axlabel = axis.axis_name ... axis.set_label_text(axlabel) ... axis.label.set_color(c) ... axis.line.set_color(c) ... axis.set_tick_params(colors=c) ... line = np.zeros((2, 3)) ... line[1, i] = scale ... line_rot = r.apply(line) ... line_plot = line_rot + loc ... ax.plot(line_plot[:, 0], line_plot[:, 1], line_plot[:, 2], c) ... text_loc = line[1]*1.2 ... text_loc_rot = r.apply(text_loc) ... text_plot = text_loc_rot + loc[0] ... ax.text(*text_plot, axlabel.upper(), color=c, ... va="center", ha="center") ... ax.text(*offset, name, color="k", va="center", ha="center", ... bbox={"fc": "w", "alpha": 0.8, "boxstyle": "circle"})
Создать три вращения — тождественное и два вращения Эйлера с использованием внутренних и внешних соглашений:
>>> r0 = R.identity() >>> r1 = R.from_euler("ZYX", [90, -30, 0], degrees=True) # intrinsic >>> r2 = R.from_euler("zyx", [90, -30, 0], degrees=True) # extrinsic
Добавьте все три вращения на один график:
>>> ax = plt.figure().add_subplot(projection="3d", proj_type="ortho") >>> plot_rotated_axes(ax, r0, name="r0", offset=(0, 0, 0)) >>> plot_rotated_axes(ax, r1, name="r1", offset=(3, 0, 0)) >>> plot_rotated_axes(ax, r2, name="r2", offset=(6, 0, 0)) >>> _ = ax.annotate( ... "r0: Identity Rotation\n" ... "r1: Intrinsic Euler Rotation (ZYX)\n" ... "r2: Extrinsic Euler Rotation (zyx)", ... xy=(0.6, 0.7), xycoords="axes fraction", ha="left" ... ) >>> ax.set(xlim=(-1.25, 7.25), ylim=(-1.25, 1.25), zlim=(-1.25, 1.25)) >>> ax.set(xticks=range(-1, 8), yticks=[-1, 0, 1], zticks=[-1, 0, 1]) >>> ax.set_aspect("equal", adjustable="box") >>> ax.figure.set_size_inches(6, 5) >>> plt.tight_layout()
Показать график:
>>> plt.show()
Эти примеры служат обзором
Rotationкласс и выделить основные функциональные возможности. Для более подробных примеров диапазона поддерживаемых входных и выходных форматов обратитесь к примерам отдельных методов.