我使用math.acos()来计算两个向量之间的角度。想法是计算两个归一化向量的点积,并使用点积的arccos返回两个向量的角度(在0到pi的范围内)。
偶然地,两个向量在归一化时具有相同的方向,并且它们的点积应为1.但是,由于数值误差,它实际上是0.999999999998,...或者有时是1.0000000000002。后者使用错误<img runat="server" src="" data-id="12345" />
我偶然发现这个question询问了类似的问题,但是已经关闭了。在这里,我重新询问,希望能更好地了解如何避免此类错误。
就我而言,在进行点生成和arccos之前,我必须检查两个向量是否具有相同的方向。这有帮助,但我仍然想知道是否有更好的方法来做到这一点。
答案 0 :(得分:3)
这是使用向量和浮点运算的所有人遇到的旧数值问题。一个简单的解决方法是使用一些钳位逻辑来包装计算角度的代码:
import numpy as np
import math
def angle_between(vhat1, vhat2, tol = 5e-6):
cosang = np.dot(vhat1, vhat2)
if math.fabs(cosang) > 1.0:
if math.fabs(cosang) - 1.0 < tol:
cosang = math.modf(cosang)[1]
else:
raise ValueError('Invalid arguments (vectors not normalized?)')
return math.acos(cosang)
w = np.array([ 1., 0., 0.])
z = np.array([-1., 0., 0.])
v = np.array([ math.sqrt(2.)/2., math.sqrt(2.)/2., 0.])
z1 = np.array([-1.0000001, 0., 0.])
w1 = np.array([9., 3., -5.])
print "{0:>5} deg".format(angle_between(v, w) * 180.0 / math.pi)
print "{0:>5} deg".format(angle_between(w, z) * 180.0 / math.pi)
print "{0:>5} deg".format(angle_between(w, z1) * 180.0 / math.pi)
# this last one will raise ValueError
print "{0:>5} deg".format(angle_between(w1, z1) * 180.0 / math.pi)
输出:
45.0 deg
180.0 deg
180.0 deg
...
ValueError: Invalid arguments (vectors not normalized?)