Saltar al contenido

¿Cómo saber el ángulo entre dos puntos?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *