私はpygameで小さなゲームを作っており、その中心を中心に回転する銃を作りました。私の問題は、銃を敵の方向にそれ自体で回転させたいことですが、銃と敵の間の角度を見つけることができず、銃をそれに向けて回転させることができませんでした。 atan2
を使用する必要があることがわかりましたが、機能するコードが見つからなかったため、誰かが私を助けてくれることを願っています。
これが私のコードです:
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)
そして、ここにそれを明確にしようとしている写真があります:
どうすれば問題を解決できますか?
2点間の角度のタンジェントは、デルタy /デルタxとして定義されます。つまり、(y2-y1)/(x2-x1)です。これは、math.atan2(dy, dx)
が2点間の角度を与えることを意味します仮定座標を定義するベース軸を知っていること。
ラジアンで角度を計算するために、銃は軸の(0、0)点と見なされます。その角度を取得したら、残りの計算にその角度を使用できます。
角度はラジアンであるため、コード内では180度ではなくmath.piを使用する必要があることに注意してください。また、360度を超えるテスト(2 * math.pi)も必要ありません。負(<0)のテストは、それを0に強制すると正しくないため、ターゲットはx軸の正方向に強制されます。
したがって、銃とターゲットの間の角度を計算するためのコードは
myradians = math.atan2(targetY-gunY, targetX-gunX)
ラジアンを度に変換したい場合
mydegrees = math.degrees(myradians)
度からラジアンに変換するには
myradians = math.radians(mydegrees)
Python ATAN2関数は、Python数学関数の1つであり、X軸から指定された点(y、x)までの角度(ラジアン)を返すために使用されます。
定義正接(y、x)を半径で返します。
構文
math.atan2(y、x)パラメータ
y、x =数値例
返品は:>>> import math >>> math.atan2(88,34) 1.202100424136847 >>>
1人のコメンターがすでに言ったように、この3つのポイントから導き出せる3つのポイント間または2つの交差するベクトル間の角度のみがあります。銃とターゲット(ベクトル1)とX軸(ベクトル2)が持つ角度が必要だと思います。これは、その角度を計算する方法を説明するページへのリンクです。 http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm
Pythonの例:
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))
特にshapely linestring
オブジェクト。オブジェクト(2点)が(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])
Pygameの Vector2 クラスのas_polar
メソッドを使用するだけで、ベクターの 極座標 (半径と極角(度単位))を返すことができます。
したがって、2番目のポイントベクトルから最初のポイントベクトルを減算し、結果のベクトルの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)