如何将计算出的角度(矢量)转换为表示该角度的单个数字?

How To Turn A Calculated Angle (vector) Into A Single Number Representing That Angle?

我基本上从两点得到了我的角度向量:

aa 点将转到 bb 点.... (Window.width=800, Window.height=600)

 aa = (50.0*Window.width/100.0, 50.0*Window.height/100.0)
 bb = (10.0*Window.width/100.0, 70.0*Window.height/100.0)

 Angle = Vector(bb)-Vector(aa)

 print(Angle)

 [-320, 120]

有没有办法将矢量转换为表示角度的单个数字...例如 90.0、45.0、180 等...?请记住,我们要从 aa 到 bb....那个角度。

另一种说法是,我想将上面的"Angle"值转换成一个数字。


这里没有Z轴。只有aa和bb的2d两个点。 Window x-cord 定义为从左到右,0 从左边开始。

Window y 轴定义为从下到上,0 从底部开始。


试图在这里更清楚...

矢量点aa就像一个圆的中间。零度将从圆圈的右中边缘开始,逆时针方向会增加度数,直到您达到 360,这将使您回到右中边缘。

矢量点 aa 可以移动,但不管它在 Window 中的位置如何,我想计算 aa 和它向 (bb) 移动的点之间的角度,其中 aa 是圆的中心并且像我上面解释的那样逆时针旋转度数。

希望能带来更多启发。


好的,我找到了一个 python 可以工作但不完美的函数。

 def GetAngleOfLineBetweenTwoPoints(self, p1, p2):
     xDiff = p2[0] - p1[0]
     yDiff = p2[1] - p1[1]
     return degrees(atan2(yDiff, xDiff))

发生的事情是,

我确实得到了正确的度数,但它是分屏格式,我的意思是,我屏幕的上半部分从右到左是 0 到 180 正数。我屏幕的下半部分从右到左是 0 到 -180。

看看那里发生了什么?

如何使该函数 return 成为一个介于 0 到 360 之间的值,就像一个完整的圆圈,而不是像当前那样从 0 到 180 +/- 分割?

你可以使用一些三角函数:)

tan(角) = 对面/相邻

angle = arctan(相对/相邻)

你的对立面是:bb.height - aa.height

您的邻座将是:bb.width - aa.width

希望对您有所帮助。

trigonometry

这个答案使用弧度

# Copy of link
import math

def dotproduct(v1, v2):
  return sum((a*b) for a, b in zip(v1, v2))

def length(v):
  return math.sqrt(dotproduct(v, v))

def angle(v1, v2):
  """angle between two vectors"""
  return math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))

转换为度除以 2*math.pi 并乘以 360。

鉴于我相信你想要水平角度你会想要

def angle(v1, v2=(1,0)):
  """angle between two vectors"""
  return math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))*(360/(2*math.pi))

例子

>>> a=(0, 100)
>>> angle(a)
90.0
>>> a=(100, 0)
>>> angle(a)
0.0
>>> a=(40, 40)
>>> angle(a)
45.00000000000001
>>> a=(-40, 40)
>>> angle(a)
135.0

编辑

下面的版本是原向量是 window

的中心
def angle(v1):
  """angle around window"""
  v2=(1, 0)
  v1 = (v1[0] - Window.width/2, v1[1] - Window.height/2)
  angle_between_radians = math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))
  angle_between_degrees = angle_between_radians *(360/(2*math.pi))
  if v1[1] >= 0:
      return angle_between_degrees 
  else:
      return 360 - angle_between_degrees

# or hardcoded this would be

def angle(v1):
  """angle around window"""
  v2=(1, 0)
  v1 = (v1[0] - 400, v1[1] - 300)
  angle_between_radians = math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))
  angle_between_degrees = angle_between_radians *(360/(2*math.pi))
  if v1[1] >= 0:
      return angle_between_degrees 
  else:
      return 360 - angle_between_degrees

例子

>>> angle((400, 400))
90.0
>>> angle((500, 300))
0.0
>>> angle((440, 340))
45.00000000000001
>>> angle((360, 340))
135.0
>>> angle((360, 260))
225.0

知道了!

 from math import atan2, degrees, pi, cos, sin

 def GetAngleOfLineBetweenTwoPoints(self, p1, p2):
     xDiff = p2[0] - p1[0]
     yDiff = p2[1] - p1[1]
     val = degrees(atan2(yDiff, xDiff))
     if str(val).find('-')!=-1:
         val = float(360)-float(val)
     return val

Yaaaaaayyyyyyy!!!!!!!