两个向量之间的夹角在区间[0,360]内。

6

我试图找出两个向量之间的夹角。
以下是我用来计算向量babc之间夹角的代码:

import numpy as np
import scipy.linalg as la

a = np.array([6,0])
b = np.array([0,0])
c = np.array([1,1])

ba = a - b
bc = c - b

cosine_angle = np.dot(ba, bc) / (la.norm(ba) * la.norm(bc))
angle = np.arccos(cosine_angle)

print (np.degrees(angle))

我的问题是,在下面这段代码中:
对于 c = np.array([1,1])c = np.array([1,-1]) 你得到的答案都是45度。我可以从数学的角度理解这一点,因为通过点积,你总是关注在区间 [0,180] 中的角度。

但从几何角度来看,这是误导性的,因为点 c[1,1][1,-1] 两个不同的位置。
那么,是否有一种方法可以获得起始点 b = np.array([x,y]) 的角度在区间 [0,360] 中的通用方法呢?

感谢您的帮助。


这是一个几何问题,不是Python或NumPy的问题。更进一步,这是一个需要直接研究而非在Stack Overflow上提问的问题。你没有包含区分arccos结果与输入值相关性的逻辑。你只需要查找完整的圆周定义并应用该逻辑,测试y值即可。 - Prune
1个回答

5
从概念上讲,使用点积获取两个向量之间的角度是非常正确的。然而,由于两个向量之间的角度在坐标系的平移/旋转下不变,因此我们可以找到每个向量相对于x轴正方向所形成的角度,并从一个值中减去另一个值。
优点是,我们将使用np.arctan2来找到这些角度,它将返回范围为[-π,π]的角度,因此您可以了解向量所处的象限。
# Syntax: np.arctan2(y, x) - put the y value first!
# Instead of explicitly referring by indices, you can unpack each vector in reverse, like so:
# np.arctan2(*bc[::-1])

angle = np.arctan2(bc[1], bc[0]) - np.arctan2(ba[1], ba[0])

然后,您可以适当转换它,以获得在 [0, 2π] 范围内的值。


1
np.arctan2(*bc)? - Quang Hoang
非常感谢您。我有一个小疑问...在这里的反正切函数中,我想知道为什么要从ba的角度中减去bc的角度,而不是相反(即ba-bc的角度)。 - Charith
@gune 这是一个选择问题。如果你做相反的事情,你得到的角度就是我得到的负数。在数学上,这对应于顺时针和逆时针旋转。 - amzon-ex
1
非常感谢您。您的答案帮助了我很多! - Charith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接