Skip to content

Wie kann man den Winkel zwischen zwei Punkten bestimmen?

Wir empfehlen Ihnen, diese Auflösung in einer kontrollierten Umgebung zu testen, bevor Sie sie an die Produktion weitergeben.

Lösung:

Der Tangens des Winkels zwischen zwei Punkten ist definiert als delta y / delta x
Das ist (y2 - y1)/(x2-x1). Das bedeutet, dass math.atan2(dy, dx) den Winkel zwischen den beiden Punkten unter der Annahme . dass du die Basisachse kennst, die die Koordinaten definiert.

Deine Waffe wird als (0, 0) Punkt der Achsen angenommen, um den Winkel im Bogenmaß zu berechnen. Sobald du diesen Winkel hast, kannst du ihn für den Rest deiner Berechnungen verwenden.

Da der Winkel im Bogenmaß angegeben wird, müssen Sie in Ihrem Code math.pi anstelle von 180 Grad verwenden. Auch Ihr Test für mehr als 360 Grad (2*math.pi) ist nicht erforderlich. Der Test für den negativen Wert (<0) ist falsch, da du ihn auf 0 zwingst, was dazu führt, dass das Ziel auf der X-Achse in positiver Richtung liegt.

Ihr Code zur Berechnung des Winkels zwischen der Kanone und dem Ziel lautet also

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

Wenn du Bogenmaß in Grad umrechnen willst

mydegrees = math.degrees(myradians)

Um von Grad in Bogenmaß zu konvertieren

myradians = math.radians(mydegrees)

Python ATAN2

Die Python-Funktion ATAN2 ist eine der Python-Math-Funktionen, die
verwendet wird, um den Winkel (im Bogenmaß) zwischen der X-Achse und dem
angegebenen Punkt (y, x).

math.atan2()

Definition Gibt den Tangens(y,x) im Radius zurück.

Syntax
math.atan2(y,x)

Parameter
y,x=Zahlen

Beispiele
Die Rückgabe ist:

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

Speziell für die Arbeit mit shapely linestring Objekten, angenommen, Ihr Objekt (zwei Punkte) hat die Form (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]) 

Im Allgemeinen ist der Winkel eines Vektors (x, y) kann berechnet werden durch math.atan2(y, x). Der Vektor kann durch 2 Punkte definiert werden (x1, y1) und (x2, y2) auf einer Linie. Daher ist der Winkel der Geraden math.atan2(y2-y1, x2-x1).
Beachten Sie, dass die y-Achse umgedreht werden muss (-y bzw. y1-y2), da die y-Achse im Allgemeinen nach oben zeigt, im PyGame-Koordinatensystem aber nach unten. Die Einheit des Winkels im Python math Modul ist Radian, aber die Einheit des Winkels in PyGame funktioniert wie pygame.transform.rotate() ist Grad. Daher muss der Winkel von Bogenmaß in Grad umgewandelt werden durch 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))

Dies kann vereinfacht werden, indem man die angle_to Methode der pygame.math.Vector2 Objekts. Diese Methode berechnet den Winkel zwischen 2 Vektoren im PyGame-Koordinatensystem in Grad. Daher ist es nicht notwendig, die y-Achse umzudrehen und von Bogenmaß in Grad zu konvertieren. Berechnen Sie einfach den Winkel zwischen dem Vektor und (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)

Minimalbeispiel:

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 kann verwendet werden, um den Winkel zwischen 2 Vektoren oder Linien zu berechnen:

def angle_between_vectors(x1, y1, x2, y2):
    return pygame.math.Vector2(x1, y1).angle_to((x2, y2))

Minimales Beispiel:

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

Kommentare und Bewertungen des Leitfadens

Wenn Sie scrollen, können Sie die Rezensionen anderer Programmierer finden, Sie haben immer noch die Freiheit, Ihre eigenen einzufügen, wenn Sie das Thema beherrschen.



Nutzen Sie unsere Suchmaschine

Suche
Generic filters

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.