我有一个单元格,在我的入射光束击中单元格后,该单元格具有法线矢量,我计算法线光束和入射光束之间的角度,角度为 45 度,现在我想计算击中旋转矩阵后反射光线的新方向,但我我坚持这样做 我有像这样的法线(不是恒定的)例如(1,0,1)和像这样的方向(0,0,-1) 我应该如何计算旋转矩阵并给我 3 个新方向以及我应该沿着哪个轴进行旋转?
def angle_between(v1, v2):
v1_u = -unit_vector(v1)
v2_u = unit_vector(v2)
gradian = np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))
return gradian
这是我的主要 cal_rotaion
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
print(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]])
)
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 = [0,0,-1]
axis = [1,0,1]
theta = np.deg2rad(45)
print(np.dot(rotation_matrix(axis, theta), v))
我应该期待什么结果?以及我如何检查功能的有效性(如果你认为是对的)
你不应该使用旋转矩阵来进行反射。
将入射矢量分成分别平行于法线和垂直于法线的部分
vn
和 vt
。如果 n
是单位法线,则
vn = (v.n)n
vt = v - vn
反射后,平行于法线的部分符号反转,平面切线部分不变。重新组装新向量:
vreflected = vt - vn
您会注意到的是
vreflected = v - 2 vn = v - 2(v.n)n
在检查方面......对于你的例子,我使用了一张纸和几支铅笔,我在空中挥舞着它们。
import numpy as np
def reflect_vector( v, normal ):
n = normal / np.linalg.norm( normal )
return v - 2 * v.dot( n ) * n
v = np.array( [ 0.0, 0.0, -1.0 ] )
normal = np.array( [ 1.0, 0.0, 1.0 ] )
print( "Original vector = ", v )
print( "Reflected vector = ", reflect_vector( v, normal ) )
输出(受一些浮点舍入影响):
Original vector = [ 0. 0. -1.]
Reflected vector = [ 1.00000000e+00 0.00000000e+00 -2.22044605e-16]