我觉得这应该很简单,但是我一直盯着代码,现在变得很愚蠢。我有一个方法,它接受两个输入3D向量,并以度为单位返回它们之间的角度。
方法如下:
def CalculateAngleBetweenVector(vector, vector2):
dp = np.dot(vector, vector2)
maga = math.sqrt((vector[0] ** 2) + vector[1] ** 2 + vector[2] ** 2)
magb = math.sqrt((vector2[0] ** 2) + vector2[1] ** 2 + vector2[2] ** 2)
magc = maga * magb
dpmag = dp / magc
angleindeg = ((math.acos(dpmag)) * 180) / math.pi
return angleindeg
目前,我有两个相同的向量将用于测试其他内容,并且当我这样做时已经意识到此方法错误。这两个向量是:
[ 0.38154065 -0.38688849 -0.83949034]
我计算输入的单位矢量的方法是:
UnitVector = Vector / np.linalg.norm(Vector)
以防万一这是什么问题。
非常感谢所有帮助。
谢谢
编辑:
很抱歉,输入的向量实际上是(0.38154065,-0.38688849,-0.83949034)我刚刚复制了终端打印行。该错误是数学域错误。
edit2:
Error traceback:
Traceback (most recent call last):
File "file path info that contains personal info Documents/com~apple~CloudDocs/WORK/Code1/CompareAnglesBetweenProteinAndMembane.py", line 261, in <module>
angle = CalculateAngleBetweenVector(ProteinRotatedUV, MemRotatedUV)
File "file path info that contains personal info Documents/com~apple~CloudDocs/WORK/Code1/CompareAnglesBetweenProteinAndMembane.py", line 167, in CalculateAngleBetweenVector
angleindeg = ((math.acos(dpmag)) * 180) / math.pi
ValueError: math domain error
如评论所讨论,问题源于浮点算术中的舍入误差(acos
的参数略微超出范围)。
我会考虑以下更改:
angle = acos(dot(A,B) / (|A|* |B|))
如果arccos的参数稍微大于1.0或小于-1.0,则将其四舍五入。如果参数在范围内,则无需执行此操作。
归一化仅在向量接近[0,0,0]或具有非常大的条目时才有用-计算在数值上更稳定。如果您的应用程序都不是,请考虑删除标准化。