简体   繁体   中英

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

I basically got my angle vector from two points:

Point aa is going to Point 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]

Is there a way to convert the vector into a single number that represents the angle...like 90.0, 45.0, 180, etc...? Keep in mind, we're going from aa to bb....that angle.

Another way to put it is, I want to convert the above "Angle" value into a single number.


There's no Z axis here. Only the 2d two points of aa and bb. The Window x-cord is defined going from left to right, with 0 starting at the left.

The Window y-cord is defined going from bottom to top, with 0 starting at the bottom.


Trying to be more clear here...

Vector point aa is like the middle of a circle. Degree zero will start at the the middle-right edge of the circle and going counter clockwise will increase the degrees, until you hit 360 which places you back at the middle-right edge.

Vector point aa can move but regardless of its position in the Window, I want to calculated the angle between aa and the point its moving towards (bb), with aa being the center of the circle and degrees going counter clockwise like I explained above.

Hope that sheds some more light.


Ok, I found a python function that works but not perfect.

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

What happens is,

I do get the correct degree but it's in a split screen format and what I mean by that is, the top half of my screen going from right to left is 0 to 180 positive. The bottom half of my screen going from right to left is 0 to -180.

See what's going on there?

How can I make that function return a value between 0 to 360, like a whole circle instead of the 0 to 180 +/- split like it's currently doing?

You can use some trigonometry :)

tan(angle) = opposite / adjacent

angle = arctan ( opposite / adjacent )

your opposite will be: bb.height - aa.height

your adjacent will be: bb.width - aa.width

I hope that helps.

trigonometry

This answer uses radians 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)))

To convert to degree divide by 2*math.pi and multiple by 360.

Given I believe you want angle to horizontal you'll want

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

Examples

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

Below is version is origin vector is center of 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

Examples

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

Got it!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM