Python 如何知道两点之间的角度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42258637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 21:29:17  来源:igfitidea点击:

How to know the angle between two points?

pythonmathpygameangle

提问by ???? ??? ??????

I am making small game with pygame and I have made a gun that rotates around its center. My problem is that I want the gun to rotate by itself to the enemy direction, but I couldn't do that because I can't find the angle between the gun and the enemy to make the gun rotate to it I have searched and I found that I have to use the atan2but I didn't find any working code so I hope someone could help me.

我正在用 pygame 制作小游戏,我制作了一把围绕其中心旋转的枪。我的问题是我想让枪自己旋转到敌人的方向,但我不能这样做,因为我找不到枪和敌人之间的角度来让枪旋转到它我已经搜索过,我发现我必须使用atan2但我没有找到任何工作代码所以我希望有人可以帮助我。

Here is my code:

这是我的代码:

import pygame
from pygame.locals import*
pygame.init()
height=650
width=650
screen=pygame.display.set_mode((height,width))
clock=pygame.time.Clock()
gun=pygame.image.load("m2.png").convert_alpha() 
gun=pygame.transform.smoothscale(gun,(200,200)).convert_alpha()
angle=0
angle_change=0
RED=(255,0,0)
x=525
y=155
while True :
    screen.fill((150,150,150))
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            quit()
        if event.type==KEYDOWN:
            if event.key==K_a:
                angle_change=+1
            if event.key==K_d:
                angle_change=-1
        elif event.type==KEYUP:
            angle_change=0
    angle+=angle_change
    if angle>360:
        angle=0
    if angle<0:
        angle=360
    pygame.draw.rect(screen,RED,(x,y,64,64))
    position = (height/2,width/2)
    gun_rotate=pygame.transform.rotate(gun,angle) 
    rotate_rect = gun_rotate.get_rect()
    rotate_rect.center = position
    screen.blit(gun_rotate, rotate_rect)
    pygame.display.update()
    clock.tick(60) 

And here is a picture trying to make it clear:

这是一张试图阐明的图片:

enter image description here

在此处输入图片说明

How do I solve the problem?

我该如何解决问题?

回答by sabbahillel

The tangent of the angle between two points is defined as delta y / delta x That is (y2 - y1)/(x2-x1). This means that math.atan2(dy, dx)give the angle between the two points assumingthat you know the base axis that defines the co-ordinates.

两点间夹角的正切定义为delta y / delta x 即(y2 - y1)/(x2-x1)。这意味着假设您知道定义坐标的基轴,则math.atan2(dy, dx)给出两点之间的角度。

Your gun is assumed to be the (0, 0) point of the axes in order to calculate the angle in radians. Once you have that angle, then you can use the angle for the remainder of your calculations.

假设您的枪是轴的 (0, 0) 点,以便以弧度计算角度。一旦你有了这个角度,你就可以在剩下的计算中使用这个角度。

Note that since the angle is in radians, you need to use the math.pi instead of 180 degrees within your code. Also your test for more than 360 degrees (2*math.pi) is not needed. The test for negative (< 0) is incorrect as you then force it to 0, which forces the target to be on the x axis in the positive direction.

请注意,由于角度以弧度为单位,您需要在代码中使用 math.pi 而不是 180 度。也不需要您对超过 360 度 (2*math.pi) 的测试。负值 (< 0) 的测试是不正确的,因为您随后将其强制为 0,这会强制目标在 x 轴的正方向上。

Your code to calculate the angle between the gun and the target is thus

因此,您计算枪和目标之间角度的代码是

myradians = math.atan2(targetY-gunY, targetX-gunX)

If you want to convert radians to degrees

如果要将弧度转换为度数

mydegrees = math.degrees(myradians)

To convert from degrees to radians

从度数转换为弧度

myradians = math.radians(mydegrees)

Python ATAN2

蟒蛇ATAN2

The Python ATAN2 function is one of the Python Math function which is used to returns the angle (in radians) from the X -Axis to the specified point (y, x).

Python ATAN2 函数是 Python Math 函数之一,用于返回从 X 轴到指定点 (y, x) 的角度(以弧度为单位)。

math.atan2()

math.atan2()

DefinitionReturns the tangent(y,x) in radius.

Syntax
math.atan2(y,x)

Parameters
y,x=numbers

Examples
The return is:

>>> import math  
>>> math.atan2(88,34)  
1.202100424136847  
>>>

定义返回半径的切线(y,x)。

语法
math.atan2(y,x)

参数
y,x=数字

例子
返回是:

>>> import math  
>>> math.atan2(88,34)  
1.202100424136847  
>>>

回答by Chidi

Specifically for working with shapely linestringobjects, assuming your object (two points) is of the form (min long, min lat, max long, max lat)

专门用于处理shapely linestring对象,假设您的对象(两点)具有以下形式(min long, min lat, max long, max lat)

from math import atan2,degrees
line = #Your-LineString-Object
lineList = list(line.coords)

def AngleBtw2Points(pointA, pointB):
  changeInX = pointB[0] - pointA[0]
  changeInY = pointB[1] - pointA[1]
  return degrees(atan2(changeInY,changeInX)) #remove degrees if you want your answer in radians

AngleBtw2Points(lineList[0],lineList[1]) 

回答by Alex

As one commenter already said, there is only an angle between three points or between two intersecting vectors, that can be derived from this threee points. I assume you want the angle, that the gun and the target (vector 1) and the X-Axis (vector 2) has. Here is a link to a page, that explains how to calculate that angle. http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

正如一位评论者已经说过的,三点之间或两个相交向量之间只有一个角度,可以从这三个点导出。我假设您想要枪和目标(矢量 1)以及 X 轴(矢量 2)具有的角度。这是一个页面链接,解释了如何计算该角度。http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm

Python example:

蟒蛇示例:

import math

def angle(vector1, vector2):
    length1 = math.sqrt(vector1[0] * vector1[0] + vector1[1] * vector1[1])
    length2 = math.sqrt(vector2[0] * vector2[0] + vector2[1] * vector2[1])
    return math.acos((vector1[0] * vector2[0] + vector1[1] * vector2[1])/ (length1 * length2))

vector1 = [targetX - gunX, targetY - gunY] # Vector of aiming of the gun at the target
vector2 = [1,0] #vector of X-axis
print(angle(vector1, vector2))

回答by skrx

You can just use the as_polarmethod of Pygame's Vector2class which returns the polar coordinatesof the vector (radius and polar angle (in degrees)).

你可以只使用as_polarPygame 的Vector2类的方法,它返回向量的极坐标(半径和极角(以度为单位))。

So just subtract the first point vector from the second and call the as_polarmethod of the resulting vector.

所以只需从第二个点向量中减去第一个点向量并调用as_polar结果向量的方法。

import pygame as pg
from pygame.math import Vector2


pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')

point = Vector2(320, 240)
mouse_pos = Vector2(0, 0)
radius, angle = (mouse_pos - point).as_polar()

done = False
while not done:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            done = True
        elif event.type == pg.MOUSEMOTION:
            mouse_pos = event.pos
            radius, angle = (mouse_pos - point).as_polar()

    screen.fill(BG_COLOR)
    pg.draw.line(screen, (0, 100, 255), point, mouse_pos)
    pg.display.set_caption(f'radius: {radius:.2f} angle: {angle:.2f}')
    pg.display.flip()
    clock.tick(60)