三维向量的旋转?
我有两个向量,都是Python的列表,还有一个角度。例如:
v = [3, 5, 0]
axis = [4, 4, 1]
theta = 1.2 # In radians.
有什么简单的方法可以得到当我围绕axis
向量旋转v
向量后得到的结果向量吗?
旋转的方向应该是逆时针的,假设有一个观察者,他的视线正对着axis
向量。这种旋转方式被称为右手法则
11 个回答
57
这是一个简单的一行代码,使用了numpy和scipy的函数。
我们用到以下内容:
设 a 是沿着 axis 的单位向量,也就是 a = axis/norm(axis)
而 A = I × a 是与 a 相关的反对称矩阵,也就是单位矩阵和 a 的叉乘那么 M = exp(θ A) 就是旋转矩阵。
from numpy import cross, eye, dot
from scipy.linalg import expm, norm
def M(axis, theta):
return expm(cross(eye(3), axis/norm(axis)*theta))
v, axis, theta = [3,5,0], [4,4,1], 1.2
M0 = M(axis, theta)
print(dot(M0,v))
# [ 2.74911638 4.77180932 1.91629719]
expm
(代码在这里) 计算指数的泰勒级数:
\sum_{k=0}^{20} \frac{1}{k!} (θ A)^k
,这个计算比较耗时,但可读性强且安全。如果你需要进行少量旋转但有很多向量,这种方法是个不错的选择。
134
使用 欧拉-罗德里格斯公式:
import numpy as np
import math
def rotation_matrix(axis, theta):
"""
Return the rotation matrix associated with counterclockwise rotation about
the given axis by theta radians.
"""
axis = np.asarray(axis)
axis = axis / math.sqrt(np.dot(axis, axis))
a = math.cos(theta / 2.0)
b, c, d = -axis * math.sin(theta / 2.0)
aa, bb, cc, dd = a * a, b * b, c * c, d * d
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]])
v = [3, 5, 0]
axis = [4, 4, 1]
theta = 1.2
print(np.dot(rotation_matrix(axis, theta), v))
# [ 2.74911638 4.77180932 1.91629719]
13
你可以看看这个链接:http://vpython.org/contents/docs/visual/VisualIntro.html。
这里有一个叫做 vector
的类,它里面有一个方法 A.rotate(theta,B)
。如果你不想直接在 A
上调用这个方法,它还提供了一个辅助函数 rotate(A,theta,B)
。
更多信息可以查看这个链接:http://vpython.org/contents/docs/visual/vector.html