如何找到 python 中两个向量之间的顺时针角度?
How to find the clockwise angle between two vectors in python?
我想求 python 中两个向量之间的顺时针夹角
角度应在 (-90,90)
范围内
计算角度的 equation/code 是什么?
class Vect:
def __init__(self, a, b):
self.a = a
self.b = b
def findClockwiseAngle(self, other):
## how to compute ??
pass
vector1 = Vect(a1,b1) ## a1*i + b1*j
vector2 = Vect(a2,b2) ## a2*i + b2*j
angle = vect1.findClockwiseAngle(vect2)
向量几何提供(至少)两个有用的公式来计算两个向量之间的角度:
其中 a · b
可以使用
计算
哪里
并且因为我们的向量是二维的,所以我们可以取 a3
和 b3
(z-axis 方向的分量)等于 0。这进一步简化了公式:
|a x b| = |a1 * b2 - a2 * b1| = |a| * |b| * sin(ϴ)
ϴ
s就是这两个公式,但是,有不同的解释。
对于点积,角度是两个向量之间的 夹角 -- 因此始终是 0 和 pi 之间的值。
使用叉积,角度是从a
到b
沿逆时针方向测量的。由于您正在寻找顺时针方向测量的角度,因此您只需反转使用叉积公式获得的角度的符号即可。
在 Python、math.asin
returns 范围内的值 [-pi/2、pi/2],而 math.acos
returns 范围内的值 [0, pi]。由于您希望角度在 [-pi/2、pi/2] 范围内(以弧度为单位),因此 cross-product 公式似乎是更有希望的候选者:
import math
class Vect:
def __init__(self, a, b):
self.a = a
self.b = b
def findClockwiseAngle(self, other):
# using cross-product formula
return -math.degrees(math.asin((self.a * other.b - self.b * other.a)/(self.length()*other.length())))
# the dot-product formula, left here just for comparison (does not return angles in the desired range)
# return math.degrees(math.acos((self.a * other.a + self.b * other.b)/(self.length()*other.length())))
def length(self):
return math.sqrt(self.a**2 + self.b**2)
vector1 = Vect(2,0)
N = 12
theta = [i * 2 * math.pi / N for i in range(N)]
result = []
for t in theta:
vector2 = Vect(math.cos(t), math.sin(t)) ## a2*i + b2*j
angle = vector1.findClockwiseAngle(vector2)
result.append((math.degrees(t), angle))
print('{:>10}{:>10}'.format('t', 'angle'))
print('\n'.join(['{:>10.2f}{:>10.2f}'.format(*pair) for pair in result]))
打印
t angle
0.00 -0.00
30.00 -30.00
60.00 -60.00
90.00 -90.00
120.00 -60.00
150.00 -30.00
180.00 -0.00
210.00 30.00
240.00 60.00
270.00 90.00
300.00 60.00
330.00 30.00
上面,t
是vector1
到vector2
的角度,在(0, 360)度范围内逆时针方向测得。 angle
是从 vector1
到 vector2
的角度,按顺时针方向测量,范围为 (-90, 90) 度。
在这种情况下,您想要找到 (-90,90) 范围内的角度。
更多信息,您可以获得 (-180,180) 范围内的角度。
如下所示。
来自 unutbu'answer
可以得到目标角度theta的cos(theta),sin(theta)
cosTh1 = np.dot(a,b)/(np.linalg.norm(a)*np.linalg.norm(b))
sinTh1 = np.cross(a,b)/(np.linalg.norm(a)*np.linalg.norm(b))
你可以得到 tan(theta) = sin(theta)/cons(theta)。
在 Python 中,numpy.arctan2 returns 值在 [-pi, pi] 范围内。所以,
print (np.rad2deg(np.arctan2(sinTh1,cosTh1)),end=",")
更简单,(因为 np.linalg.norm(a)*np.linalg.norm(b) 很常见。)
cosTh = np.dot(a,b)
sinTh = np.cross(a,b)
print (np.rad2deg(np.arctan2(sinTh,cosTh)))
我想求 python 中两个向量之间的顺时针夹角 角度应在 (-90,90)
范围内计算角度的 equation/code 是什么?
class Vect:
def __init__(self, a, b):
self.a = a
self.b = b
def findClockwiseAngle(self, other):
## how to compute ??
pass
vector1 = Vect(a1,b1) ## a1*i + b1*j
vector2 = Vect(a2,b2) ## a2*i + b2*j
angle = vect1.findClockwiseAngle(vect2)
向量几何提供(至少)两个有用的公式来计算两个向量之间的角度:
其中 a · b
可以使用
哪里
并且因为我们的向量是二维的,所以我们可以取 a3
和 b3
(z-axis 方向的分量)等于 0。这进一步简化了公式:
|a x b| = |a1 * b2 - a2 * b1| = |a| * |b| * sin(ϴ)
ϴ
s就是这两个公式,但是,有不同的解释。
对于点积,角度是两个向量之间的 夹角 -- 因此始终是 0 和 pi 之间的值。
使用叉积,角度是从a
到b
沿逆时针方向测量的。由于您正在寻找顺时针方向测量的角度,因此您只需反转使用叉积公式获得的角度的符号即可。
在 Python、math.asin
returns 范围内的值 [-pi/2、pi/2],而 math.acos
returns 范围内的值 [0, pi]。由于您希望角度在 [-pi/2、pi/2] 范围内(以弧度为单位),因此 cross-product 公式似乎是更有希望的候选者:
import math
class Vect:
def __init__(self, a, b):
self.a = a
self.b = b
def findClockwiseAngle(self, other):
# using cross-product formula
return -math.degrees(math.asin((self.a * other.b - self.b * other.a)/(self.length()*other.length())))
# the dot-product formula, left here just for comparison (does not return angles in the desired range)
# return math.degrees(math.acos((self.a * other.a + self.b * other.b)/(self.length()*other.length())))
def length(self):
return math.sqrt(self.a**2 + self.b**2)
vector1 = Vect(2,0)
N = 12
theta = [i * 2 * math.pi / N for i in range(N)]
result = []
for t in theta:
vector2 = Vect(math.cos(t), math.sin(t)) ## a2*i + b2*j
angle = vector1.findClockwiseAngle(vector2)
result.append((math.degrees(t), angle))
print('{:>10}{:>10}'.format('t', 'angle'))
print('\n'.join(['{:>10.2f}{:>10.2f}'.format(*pair) for pair in result]))
打印
t angle
0.00 -0.00
30.00 -30.00
60.00 -60.00
90.00 -90.00
120.00 -60.00
150.00 -30.00
180.00 -0.00
210.00 30.00
240.00 60.00
270.00 90.00
300.00 60.00
330.00 30.00
上面,t
是vector1
到vector2
的角度,在(0, 360)度范围内逆时针方向测得。 angle
是从 vector1
到 vector2
的角度,按顺时针方向测量,范围为 (-90, 90) 度。
在这种情况下,您想要找到 (-90,90) 范围内的角度。 更多信息,您可以获得 (-180,180) 范围内的角度。 如下所示。
来自 unutbu'answer 可以得到目标角度theta的cos(theta),sin(theta)
cosTh1 = np.dot(a,b)/(np.linalg.norm(a)*np.linalg.norm(b))
sinTh1 = np.cross(a,b)/(np.linalg.norm(a)*np.linalg.norm(b))
你可以得到 tan(theta) = sin(theta)/cons(theta)。 在 Python 中,numpy.arctan2 returns 值在 [-pi, pi] 范围内。所以,
print (np.rad2deg(np.arctan2(sinTh1,cosTh1)),end=",")
更简单,(因为 np.linalg.norm(a)*np.linalg.norm(b) 很常见。)
cosTh = np.dot(a,b)
sinTh = np.cross(a,b)
print (np.rad2deg(np.arctan2(sinTh,cosTh)))