python - 使用欧拉角/矩阵在 3d 空间中旋转?

标签 python numpy math 3d angle

我正在尝试在 3D 空间中旋转圆柱体,以将 3D 空间中的 2 个点连接在一起。在计算 3 个旋转角度后,我使用欧拉矩阵将旋转应用于圆柱点网格。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

class sphere(object):

    def __init__(self, center_x = 0.0, center_y = 0.0, center_z =0.0, radius = 1.0, resolution = 20):

        self.center_x = center_x
        self.center_y = center_y
        self.center_z = center_z
        self.radius = radius
        self.resolution = resolution   
        self.sphere = self._define_sphere()

    def _define_sphere(self):

        self.u, self.v = np.mgrid[0:2*np.pi: (self.resolution * 1j), 0:np.pi: (self.resolution * 1j)]
        self.x = self.radius * np.cos(self.u)*np.sin(self.v) + self.center_x
        self.y = self.radius * np.sin(self.u)*np.sin(self.v) + self.center_y
        self.z = self.radius * np.cos(self.v) + self.center_z

        return [self.x, self.y, self.z]

    def plot_self(self, ax):

        ax.plot_surface(self.x, self.y, self.z)

class cylinder(object):

    def __init__(self, center_x = 0.0, center_y = 0.0, center_z = 0.0, radius = 1.0, z = 1.0, resolution = 20):

        self.center_x = center_x
        self.center_y = center_y
        self.center_z = center_z
        self.radius = radius
        self.z = z
        self.resolution = resolution
        self.cylinder = self._define_cylinder()

    def _define_cylinder(self):

        self.z_values = np.linspace(0, self.z, self.resolution)
        self.theta = np.linspace(0, 2*np.pi, self.resolution)

        self.theta_mesh, self.z_grid = np.meshgrid(self.theta, self.z_values)

        self.x_grid = self.radius * np.cos(self.theta_mesh) + self.center_x
        self.y_grid = self.radius * np.sin(self.theta_mesh) + self.center_y

        return [self.x_grid, self.y_grid, self.z_grid]

    def join_points(self, x1, y1, z1, x2, y2, z2):

        dx = x1 - x2
        dy = y1 - y2
        dz = z1 - z2

        print dx,dy,dz

        distance = math.sqrt(dx**2 + dy**2 + dz**2)

        self.psi = math.atan2(dx, dy)
        self.theta = math.atan2(dx, dz)
        self.phi = 0

        self.euler = np.array([[(math.cos(self.psi)*math.cos(self.phi)) - math.cos(self.theta)*math.sin(self.phi)*math.sin(self.psi), math.cos(self.psi)*math.sin(self.phi) + math.cos(self.theta)*math.cos(self.phi)*math.sin(self.psi), math.sin(self.psi)*math.sin(self.theta)],
                               [-math.sin(self.psi)*math.cos(self.phi) - math.cos(self.theta)*math.sin(self.phi)*math.cos(self.psi), -math.sin(self.psi)*math.sin(self.phi) + math.cos(self.theta)*math.cos(self.phi)*math.cos(self.psi), math.cos(self.psi)*math.sin(self.theta)],
                               [math.sin(self.theta)*math.sin(self.phi), -math.sin(self.theta)*math.cos(self.phi), math.cos(self.theta)]])

        print self.euler

        rotation = np.dot(self.euler, np.array([self.x_grid.ravel(), self.y_grid.ravel(), self.z_grid.ravel()]))

        x,y,z = self.x_grid, self.y_grid, self.z_grid

        self.x_grid = rotation[0,:].reshape(x.shape)               
        self.y_grid = rotation[1,:].reshape(y.shape)               
        self.z_grid = rotation[2,:].reshape(z.shape)

    def plot_self(self, ax):

        ax.plot_surface(self.x_grid, self.y_grid, self.z_grid)

fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
ax.set_aspect('equal')
ax.set_xlim([-10,10])
ax.set_ylim([-10,10])
ax.set_zlim([-10,10])

cylinder_object = cylinder(0.0, 0.0, 0.0, 0.3, 12)
cylinder_object.join_points(0.0, 0.0, 0.0, 8.0, 10.0, 2.0)
cylinder_object.plot_self(ax)

sphere_object = sphere(0.0, 0.0, 0.0, 1.0, 100)
sphere_object2 = sphere(8.0, 10.0, 0.0, 1.0, 100)
sphere_object.plot_self(ax)
sphere_object2.plot_self(ax)

预期结果是创建一个圆柱体,将 A 点连接到 B 点(在我的示例中,为 sphere_object 和 sphere_object2)。

问题是旋转似乎是正确的,但方向错误,具体取决于球体出现的位置。

最佳答案

与 2D 形状有 2 个旋转矩阵一样,您需要选择 8 种可能的旋转矩阵组合中的一个来满足您的条件。

Rotation Matrix 1

Rotation Matrix 2

在 2D 情况下,您需要定义与您的坐标系和绘图库相匹配的旋转矩阵。

Rotation Matrix 3

实际上,您需要为上面的 3 个旋转矩阵选择使用 Theta 还是 -1*Theta,就像我们对 2D 情况所做的那样。

关于python - 使用欧拉角/矩阵在 3d 空间中旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54680843/

相关文章:

java - 基于对数的解决方案计算大整数中不正确的位数

python - 按 "column"的字母顺序对python中的列表列表进行排序

Python pip 安装错误 [SSL : CERTIFICATE_VERIFY_FAILED]

algorithm - 如何根据坐标对角填充二维数组

c++ - Runge-Kutta 四阶积分器出错

python - 类型错误 : only length-1 arrays can be converted to Python scalars with NUMPY

python - Docker:如何在构建过程中从文件设置环境变量?

python - 计算矩阵行之间的余弦距离

python-3.x - 模块未找到错误 : No module named 'numpy'

python - 用 Pandas 计算矩阵的逆