Recuerda que en las ciencias informáticas cualquier problema casi siempre tiene diversas soluciones, por lo tanto aquí enseñamos lo más óptimo y eficiente.
Solución:
La tangente del ángulo entre dos puntos se define como delta y / delta x Es decir (y2 – y1) / (x2-x1). Esto significa que math.atan2(dy, dx)
dar el ángulo entre los dos puntos asumiendo que conoce el eje base que define las coordenadas.
Se supone que su arma es el punto (0, 0) de los ejes para calcular el ángulo en radianes. Una vez que tenga ese ángulo, puede usar el ángulo para el resto de sus cálculos.
Tenga en cuenta que, dado que el ángulo está en radianes, debe usar math.pi en lugar de 180 grados dentro de su código. Además, su prueba de más de 360 grados (2 * math.pi) no es necesaria. La prueba para negativo (<0) es incorrecta, ya que luego la fuerza a 0, lo que obliga al objetivo a estar en el eje x en la dirección positiva.
Su código para calcular el ángulo entre el arma y el objetivo es por lo tanto
myradians = math.atan2(targetY-gunY, targetX-gunX)
Si desea convertir radianes a grados
mydegrees = math.degrees(myradians)
Para convertir de grados a radianes
myradians = math.radians(mydegrees)
Python ATAN2
La función Python ATAN2 es una de las funciones Python Math que se utiliza para devolver el ángulo (en radianes) desde el eje X hasta el punto especificado (y, x).
math.atan2 ()
Definición Devuelve la tangente (y, x) en el radio.
Sintaxis
math.atan2 (y, x)
Parámetros
y, x = números
Ejemplos de
El regreso es:
>>> import math >>> math.atan2(88,34) 1.202100424136847 >>>
Específicamente para trabajar con shapely linestring
objetos, asumiendo que su objeto (dos puntos) tiene la forma (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])
En general, el ángulo de un vector (x, y) puede ser calculado por math.atan2(y, x)
. El vector se puede definir por 2 puntos (x1, y1) y (x2, y2) en una línea. Por lo tanto, el ángulo de la línea es math.atan2(y2-y1, x2-x1)
. Tenga en cuenta que el eje y debe invertirse (-y
respectivamente y1-y2
) porque el eje y generalmente apunta hacia arriba, pero en el sistema de coordenadas PyGame el eje y apunta hacia abajo. La unidad del ángulo en Python math
módulo es Radian, pero la unidad del ángulo en PyGame funciona como pygame.transform.rotate()
es grado. Por lo tanto, el ángulo debe convertirse de radianes a grados mediante math.degrees
:
import math
def angle_of_vector(x, y):
return math.degrees(math.atan2(-y, x))
def angle_of_line(x1, y1, x2, y2):
return math.degrees(math.atan2(-y1-y2, x2-x1))
Esto se puede simplificar utilizando el angle_to
método del pygame.math.Vector2
objeto. Este método calcula el ángulo entre 2 vectores en el sistema de coordenadas PyGame en grados. Por lo tanto, no es necesario invertir el eje y y convertir de radianes a grados. Simplemente calcula el ángulo entre el vector y (1, 0):
def angle_of_vector(x, y):
return pygame.math.Vector2(x, y).angle_to((1, 0))
def angle_of_line(x1, y1, x2, y2):
return angle_of_vector(x2-x1, y2-y1)
Ejemplo mínimo:
import pygame
import math
def angle_of_vector(x, y):
#return math.degrees(math.atan2(-y, x)) # 1: with math.atan
return pygame.math.Vector2(x, y).angle_to((1, 0)) # 2: with pygame.math.Vector2.angle_to
def angle_of_line(x1, y1, x2, y2):
#return math.degrees(math.atan2(-y1-y2, x2-x1)) # 1: math.atan
return angle_of_vector(x2-x1, y2-y1) # 2: pygame.math.Vector2.angle_to
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 50)
angle = 0
radius = 150
vec = (radius, 0)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
cpt = window.get_rect().center
pt = cpt[0] + vec[0], cpt[1] + vec[1]
angle = angle_of_vector(*vec)
window.fill((255, 255, 255))
pygame.draw.circle(window, (0, 0, 0), cpt, radius, 1)
pygame.draw.line(window, (0, 255, 0), cpt, (cpt[0] + radius, cpt[1]), 3)
pygame.draw.line(window, (255, 0, 0), cpt, pt, 3)
text_surf = font.render(str(round(angle/5)*5) + "°", True, (255, 0, 0))
text_surf.set_alpha(127)
window.blit(text_surf, text_surf.get_rect(bottomleft = (cpt[0]+20, cpt[1]-20)))
pygame.display.flip()
angle = (angle + 1) % 360
vec = radius * math.cos(angle*math.pi/180), radius * -math.sin(angle*math.pi/180)
pygame.quit()
exit()
angle_to
se puede utilizar para calcular el ángulo entre 2 vectores o líneas:
def angle_between_vectors(x1, y1, x2, y2):
return pygame.math.Vector2(x1, y1).angle_to((x2, y2))
Ejemplo mínimo:
import pygame
import math
def angle_between_vectors(x1, y1, x2, y2):
return pygame.math.Vector2(x1, y1).angle_to((x2, y2))
def angle_of_vector(x, y):
return pygame.math.Vector2(x, y).angle_to((1, 0))
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 50)
angle = 0
radius = 150
vec1 = (radius, 0)
vec2 = (radius, 0)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
cpt = window.get_rect().center
pt1 = cpt[0] + vec1[0], cpt[1] + vec1[1]
pt2 = cpt[0] + vec2[0], cpt[1] + vec2[1]
angle = angle_between_vectors(*vec2, *vec1)
window.fill((255, 255, 255))
pygame.draw.circle(window, (0, 0, 0), cpt, radius, 1)
pygame.draw.line(window, (0, 255, 0), cpt, pt1, 3)
pygame.draw.line(window, (255, 0, 0), cpt, pt2, 3)
text_surf = font.render(str(round(angle/5)*5) + "°", True, (255, 0, 0))
text_surf.set_alpha(127)
window.blit(text_surf, text_surf.get_rect(bottomleft = (cpt[0]+20, cpt[1]-20)))
pygame.display.flip()
angle1 = (angle_of_vector(*vec1) + 1/3) % 360
vec1 = radius * math.cos(angle1*math.pi/180), radius * -math.sin(angle1*math.pi/180)
angle2 = (angle_of_vector(*vec2) + 1) % 360
vec2 = radius * math.cos(angle2*math.pi/180), radius * -math.sin(angle2*math.pi/180)
pygame.quit()
exit()
Si para ti ha sido provechoso este artículo, sería de mucha ayuda si lo compartes con otros entusiastas de la programación de esta forma contrubuyes a dar difusión a nuestro contenido.