Как превратить вычисленный угол (вектор) в одно число, представляющее этот угол? - PullRequest
0 голосов
/ 16 мая 2019

Я в основном получил свой угол вектора из двух точек:

Точка аа собирается в точку 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 и т. Д.? Имейте в виду, мы идем от аа до бб .... под этим углом.

Еще один способ выразить это - я хочу преобразовать указанное выше значение "Угол" в одно число.


Здесь нет оси Z. Только 2d две точки аа и бб. Окно x-cord определяется слева направо, а 0 начинается слева.

Y-образный шнур Window определяется снизу вверх, а 0 начинается снизу.


Пытаясь быть более ясным здесь ...

Вектор aa подобен середине круга. Нулевая степень начнется с середины правого края круга, а движение против часовой стрелки будет увеличивать градусы, пока вы не нажмете 360, и вы вернетесь к среднему правому краю.

Векторная точка aa может двигаться, но независимо от ее положения в окне, я хочу вычислить угол между aa и точкой, в которой она движется (bb), где aa является центром круга, а градусы идут против часовой стрелки, как I объяснено выше.

Надеюсь, что проливает еще немного света.


Хорошо, я нашел функцию 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.

Видите, что там происходит?

Как я могу заставить эту функцию возвращать значение от 0 до 360, как целый круг вместо 0 до 180 +/-, как это происходит в настоящее время?

Ответы [ 3 ]

2 голосов
/ 16 мая 2019

Вы можете использовать некоторую тригонометрию:)

tan (угол) = противоположность / смежность

angle = arctan (противоположность / смежность)

ваша противоположность будет: bb.height - aa.height

ваши соседние будут: bb.width - aa.width

Надеюсь, это поможет.

тригонометрия

0 голосов
/ 17 мая 2019

Понял!

 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 !!!!!!!

0 голосов
/ 16 мая 2019

В этом ответе используются радианы https://stackoverflow.com/a/2827475/4711754

# 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

EDIT

Ниже указана версия, вектор происхождения - центр окна.

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
...