Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python坐标矩阵表示椭球的Euler旋转_Python_Numpy_Matplotlib_Rotation - Fatal编程技术网

python坐标矩阵表示椭球的Euler旋转

python坐标矩阵表示椭球的Euler旋转,python,numpy,matplotlib,rotation,Python,Numpy,Matplotlib,Rotation,目标:将Euler旋转应用于椭球体,然后使用matplotlib和mplot3d绘制它 我发现了一个函数,它将欧拉旋转应用于向量或向量数组: import numpy as np from scipy.linalg import expm def rot_euler(v, xyz): ''' Rotate vector v (or array of vectors) by the euler angles xyz ''' # https://stackoverflow.com/question

目标:将Euler旋转应用于椭球体,然后使用matplotlib和mplot3d绘制它

我发现了一个函数,它将欧拉旋转应用于向量或向量数组:

import numpy as np
from scipy.linalg import expm

def rot_euler(v, xyz):
''' Rotate vector v (or array of vectors) by the euler angles xyz '''
# https://stackoverflow.com/questions/6802577/python-rotation-of-3d-vector
for theta, axis in zip(xyz, np.eye(3)):
    v = np.dot(np.array(v), expm(np.cross(np.eye(3), axis*-theta)))
return v 
但是,我需要旋转的椭球体表示为一组三个坐标矩阵(以便使用ax.plot_surface()进行绘制):

如何将Euler旋转应用于此对象?我曾想过将物体从三个坐标矩阵转换成向量,然后将其输入到现有的公式中,但我觉得这样做可能会导致计算效率低下。。。这让我想知道旋转函数是否可以被修改以处理坐标矩阵

我意识到这可能是一个相当琐碎的问题,但自从我上一次做线性代数以来已经好几年了,我非常感谢这里的专家的建议


谢谢

虽然我不认为你能比应用旋转点做得更好,但仍然有显著的经济空间

(1) 使用矩阵指数计算简单的旋转矩阵是荒谬的浪费。最好使用标量指数或正弦和余弦

(2) 在较小程度上,这同样适用于使用叉积进行洗牌。这里最好使用索引

(3) 矩阵乘法的顺序很重要。当批量旋转超过三个向量时,最左边的乘法应最后进行

这些措施加在一起可将计算速度提高六倍:

(在原始脚本的最后两行之前插入)

输出:



虽然我不认为你可以做得比应用旋转点更好,但仍然有显著的经济空间

(1) 使用矩阵指数计算简单的旋转矩阵是荒谬的浪费。最好使用标量指数或正弦和余弦

(2) 在较小程度上,这同样适用于使用叉积进行洗牌。这里最好使用索引

(3) 矩阵乘法的顺序很重要。当批量旋转超过三个向量时,最左边的乘法应最后进行

这些措施加在一起可将计算速度提高六倍:

(在原始脚本的最后两行之前插入)

输出:



值得一提的是:感谢指针,线性代数专家的建议更容易获得。我认为在这种情况下,这更像是一个numpy的效率问题,而不是一个纯粹的数学问题。只需提及:感谢指针,线性代数专家的建议更容易获得。我认为在这种情况下,这更像是numpy中的效率问题,而不是纯粹的数学问题。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from numpy import pi,sin,cos

fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
ax.set_aspect('equal','box')
ax.set_xlim3d(-1,1)
ax.set_ylim3d(-1,1)
ax.set_zlim3d(-1,1)
ax.view_init(90,90)

ellipseSteps= 100
diamCoef = 500
widthCoef = 25
coefs = (widthCoef, diamCoef, diamCoef)  # Coefficients in a0/c x**2 + a1/c y**2 + a2/c z**2 = 1 
# Radii corresponding to the coefficients:
rx, ry, rz = 1/np.sqrt(coefs)

# Set of all spherical angles:
u = np.linspace(0, 2 * pi, ellipseSteps)
v = np.linspace(0, pi, ellipseSteps)

# Cartesian coordinates that correspond to the spherical angles:
# (this is the equation of an ellipsoid):
ex = rx * np.outer(cos(u), sin(v))
ey = ry * np.outer(sin(u), sin(v))
ez = rz * np.outer(np.ones_like(u), cos(v))

# Plot:
ax.plot_surface(ex, ey, ez,  rstride=4, cstride=4, color='blue')

plt.show()
from scipy.linalg import block_diag
from timeit import timeit

def rot_euler_better(v, xyz):
    TD = np.multiply.outer(np.exp(1j * np.asanyarray(xyz)), [[1], [1j]]).view(float)
    x, y, z = (block_diag(1, TD[i])[np.ix_(*2*(np.arange(-i, 3-i),))] for i in range(3))
    return v @ (x @ y @ z)

# example
xyz = np.pi * np.array((1/6, -2/3, 1/4))

print("Same result:",
      np.allclose(rot_euler(np.array((*map(np.ravel, (ex, ey, ez)),)).T, xyz),
                  rot_euler_better(np.array((*map(np.ravel, (ex, ey, ez)),)).T, xyz))

print("OP:       ", timeit(lambda: rot_euler(np.array((*map(np.ravel, (ex, ey, ez)),)).T, xyz), number=1000), "ms")
print("optimized:", timeit(lambda: rot_euler_better(np.array((*map(np.ravel, (ex, ey, ez)),)).T, xyz), number=1000), "ms")

ex, ey, ez = map(np.reshape, rot_euler_better(np.array((*map(np.ravel, (ex, ey, ez)),)).T, xyz).T, map(np.shape, (ex, ey, ez)))
Same result: True
OP:        2.1019406360574067 ms
optimized: 0.3485010238364339 ms