Двухступенчатое трехмерное вращение тензоров x, y, z - PullRequest
0 голосов
/ 20 февраля 2020

В Python, используя PyTorch , я пытаюсь повернуть 3 куба x, y и z, сначала вокруг оси x, а затем около z- ось. Однако вращение вокруг оси z ведет себя не так, как я ожидал.

Я создаю 3 куба, чтобы повернуть их ниже, а затем поворачиваю их на 90 градусов вокруг оси x, а затем на 90 градусов. о оси Z.

import torch 
from numpy import pi 
import matplotlib.pyplot as plt

def rotation(x,y,z,theta,phi):
    ### A function for rotating about the x and then z axes ###
    xx = (x*torch.cos(theta)) - (((y*torch.cos(phi)) - (z*torch.sin(phi)))*torch.sin(theta))
    yy = (x*torch.sin(theta)) + (((y*torch.cos(phi)) - (z*torch.sin(phi)))*torch.cos(theta))
    zz = (y*torch.sin(phi)) + (z*torch.cos(phi))
    return xx,yy,zz

### Creating the 3 cubes: x, y, z ###
l = torch.arange(-2,3,1)
x,y,z=torch.meshgrid(l,l,l)

###  Scaling the cubes so they can be differentiated from one another ###
x = x.clone().T
y = y.clone().T*2
z = z.clone().T*3

### Defining the amount of rotation about the x and z axes
phi = torch.tensor([pi/2]).to(torch.float) # about the x axis
theta = torch.tensor([pi/2]).to(torch.float) # about the z axis

### Performing the rotation
x_r,y_r,z_r = rotation(x, y, z, theta, phi)

Визуализируя первый срез каждого куба, я вижу, что вращение не было успешным, так как на первый взгляд кажется, что кубы действительно вращаются вокруг оси x, а затем следует y- ось вместо

enter image description here

Есть ли определенный c способ, которым Python обрабатывает такие повороты, которые я пропускаю, такие как оси, меняющиеся вместе с вращения, означающие начальную операцию матрицы вращения больше не применяется?


Дополнительная информация

Если заменить theta на 0 вместо pi/2, можно увидеть, что первое вращение ведет себя как ожидалось, посмотрев на первый срез каждого вращающегося куба:

Код для визуализации:

plt.figure()
plt.subplot(231)
x_before = plt.imshow(x[0,:,:])
plt.xlabel('x-before'); plt.colorbar(x_before,fraction=0.046, pad=0.04)
plt.subplot(232)
y_before = plt.imshow(y[0,:,:])
plt.xlabel('y-before'); plt.colorbar(y_before,fraction=0.046, pad=0.04)
plt.subplot(233)
z_before = plt.imshow(z[0,:,:])
plt.xlabel('z-before'); plt.colorbar(z_before,fraction=0.046, pad=0.04)
plt.subplot(234)
x_after = plt.imshow(x_r[0,:,:])
plt.xlabel('x-after'); plt.colorbar(x_after,fraction=0.046, pad=0.04)
plt.subplot(235)
y_after = plt.imshow(y_r[0,:,:])
plt.xlabel('y-after'); plt.colorbar(y_after,fraction=0.046, pad=0.04)
plt.subplot(236)
z_after = plt.imshow(z_r[0,:,:])
plt.xlabel('z-after'); plt.colorbar(z_after,fraction=0.046, pad=0.04)
plt.tight_layout()

enter image description here

1 Ответ

1 голос
/ 20 февраля 2020

Это звучит как глобальная проблема против локальной оси - вы начинаете вращаться на 90 градусов вокруг оси X, что приводит к перемещению куба так, что его локальная ось Y заканчивается направленной вдоль глобальной оси Z. Применение следующего поворота на 90 градусов вокруг глобального Z выглядит как вращение вокруг локальной оси Y.

Чтобы решить эту проблему, вам нужно применить разные повороты для достижения желаемой ориентации (в данном случае поверните на -90 градусов). вокруг глобального Y, поскольку локальная ось Z теперь обращена вниз к отрицательной глобальной оси Y), или напишите другую функцию вращения, которая может вращаться вокруг любого вектора и отслеживать локальные оси куба (пропуская их через те же вращения, что и сам куб).

Вы также можете работать в локальных координатах, применяя повороты в обратном порядке, ie глобальное вращение вокруг Y на 90, а затем глобальное вращение вокруг X на 90 будет быть эквивалентным локальным поворотам в X и Y.

...