常见旋转矩阵 R 的指定方法
R 在三维中的一般定义是
其中 (x', x) 表示 x' 和 x 轴的夹角,(x', y) 是 x' 和 y 轴的夹角,以此类推。
3-D 退化为 2-D
绕 z 轴旋转意味着 cos(z', z)=1 因为 z' 和 z 的夹角保持为 0°。同时,cos(x', z)=cos(y', z)=cos(z', x)=cos(z', y)=0,因为这些轴之间的夹角保持 90°。
x 和 y' 之间的角度为 (90∘+θ), 而 cos(y', x) = cos(90∘+θ)=−sinθ。
同样,x' 和 y 之间的角为 (90°−θ),而 cos(x', y)=cos(90°−θ)=sinθ。
所有这些导致 R 退化为
这揭示了三维旋转矩阵中的二维旋转矩阵。
通过绕轴旋转指定旋转矩阵 R
除了我们常见的指定旋转矩阵的方法,还有另一种指定旋转矩阵的方法,即是通过旋转轴向量 p 和一个绕 p 轴的旋转角 α。
在这种情况下,旋转矩阵被写成
其中
代入上式,把矩阵完整写出来
用这种方法很容易将坐标旋转可视化。例如,2-D 的情况可以通过注意旋转是关于
z轴的来再现,因此向量是p=(0,0,1)。这将导致R简化为
效果图与完整代码
import numpy as np
import bpy
# 获取单位向量
def get_unit_vector(vec):
# if not isinstance(vec,np.array):
vec = np.array(vec)
vec_norm = np.linalg.norm(vec)
return vec/vec_norm
# 围绕某单位向量旋转特定角度的旋转矩阵
def rotatematrix(vec,theta):
p1 = vec[0]
p2 = vec[1]
p3 = vec[2]
theta = np.radians(theta)
tem_1 = 1-np.cos(theta)
tem_2 = np.sin(theta)
tem_3 = np.cos(theta)
matrix = np.array([
[tem_3+p1*p1*(tem_1),(tem_1)*p1*p2-p3*tem_2,p1*p3*tem_1+p2*tem_2],
[p1*p2*tem_1+p3*tem_2,tem_3+tem_1*p2*p2,tem_1*p2*p3-p1*tem_2],
[tem_1*p1*p3-p2*tem_2,tem_1*p2*p3+p1*tem_2,tem_3+tem_1*p3*p3]
])
return matrix
ob = bpy.context.active_object
rotate_vec = np.array([5,6,2])
vec = get_unit_vector(rotate_vec)
p = np.array(ob.location)
# ob.location = p 围绕某特定向量旋转
num = 0
def test_roate(scene):
global num
per_frame = 360/250
theta = per_frame * scene.frame_current
r_m = rotatematrix(vec,theta)
# 旋转角度后的坐标
newp = np.dot(p,r_m)
ob.location = newp
num += 1
# 画出其运动轨迹
if scene.frame_current % 10 ==0 and num <251:
bpy.ops.mesh.primitive_ico_sphere_add(radius=1, location=newp, scale=(0.2, 0.2, 0.2))
def main():
bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(test_roate)
main()