如何在python中找到两个向量之间的顺时针角度?

时间:2018-12-29 13:46:25

标签: python-3.x computational-geometry

我想在python中找到两个向量之间的顺时针角度 角度应在(-90,90)范围内

计算角度的方程式/代码是什么?

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)

2 个答案:

答案 0 :(得分:1)

向量几何提供(至少)两个有用的公式来查找两个向量之间的角度:

其中a · b可以使用

来计算

其中

并且由于我们的向量是二维的,因此我们可以将a3b3(z轴方向上的分量)取为0。这进一步简化了公式:

|a x b| = |a1 * b2 - a2 * b1| = |a| * |b| * sin(ϴ)

ϴ是这两个公式,但是有不同的解释。 对于点积,角度是两个矢量之间的夹角-因此始终是介于0和pi之间的值。

使用叉积,沿逆时针方向从ab测量角度。由于您要查找沿顺时针方向测量的角度,因此只需反转使用叉积公式获得的角度的符号即可。

在Python中,math.asin返回范围为[-pi / 2,pi / 2],而math.acos返回范围为[0,pi]。由于您想要的角度在[-pi / 2,pi / 2](以弧度为单位)范围内,因此叉积公式似乎是更有希望的候选者:

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是从vector1vector2沿逆时针方向测量的角度,范围为(0,360)。 angle是从vector1vector2的角度,沿顺时针方向且在(-90,90)度范围内。

答案 1 :(得分:0)

在这种情况下,您想要找到在(-90,90)范围内的角度。 更多信息,您可以获得在(-180,180)范围内的角度。 如图所示。

来自unutbu'answer 您可以获得目标角度theta的cos(θ),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θ=sinθ/consθ。 在Python中,numpy.arctan2返回范围为[-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)))   
相关问题