gpt4 book ai didi

python - 重力问题

转载 作者:太空宇宙 更新时间:2023-11-03 14:37:10 25 4
gpt4 key购买 nike

我一直在尝试用 pygame 编写代码来模拟简单的重力。目前,只有一个物体(HOM)绕太阳运行。然而,由于我不知道的原因,每当我运行代码时,HOM 一开始都会在轨道上围绕太阳运行,但当它到达时就会加速远离太阳与垂直方向约 135 度。

有谁知道为什么会发生这种情况以及如何解决它?我一直在打印一些变量来尝试找出问题根源,但到目前为止还没有运气。

代码:

import pygame,sys,time
from math import *

screen=pygame.display.set_mode((800,600))

G = 5

class Object: #Just an object, like a moon or planet
def __init__(self,mass,init_cds,init_vel,orbit_obj='Sun'):
self.mass = mass
self.cds = init_cds
self.velocity = init_vel
self.accel = [0,0]
self.angle = 0
self.orb_obj = orbit_obj

def display(self):
int_cds = (round(self.cds[0]),round(self.cds[1]))#Stores its co-ordinates as floats, has to convert to integers for draw function
pygame.draw.circle(screen,(255,0,0),int_cds,10)

def calc_gravity(self):
if self.orb_obj == 'Sun':
c_x,c_y = 400,300
c_mass = 10000
else:
c_x,c_y = self.orb_obj.cds
c_mass = self.orb_obj.mass
d_x = self.cds[0]-c_x
d_y = self.cds[1]-c_y
dist = sqrt(d_x**2+d_y**2) #Find direct distance
angle = atan(d_x/d_y) #Find angle
print(d_x,d_y)
print(dist,degrees(angle))
if dist == 0:
acc = 0
else:
acc = G*c_mass/(dist**2) #F=G(Mm)/r^2, a=F/m -> a=GM/r^2
print(acc)
acc_x = acc*sin(angle) #Convert acceleration from magnitude+angle -> x and y components
acc_y = acc*cos(angle)
self.accel = [acc_x,acc_y]
print(self.accel)
self.velocity = [self.velocity[0]+self.accel[0],self.velocity[1]+self.accel[1]] #Add acceleration to velocity
print(self.velocity)
self.cds = (self.cds[0]+self.velocity[0],self.cds[1]+self.velocity[1]) #Change co-ordinates by velocity
print(self.cds)
print('-------------------') #For seperating each run of the function when printing variables

HOM = Object(1000000,(400,100),[10,0]) #The problem planet

clock = pygame.time.Clock()

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

screen.fill((0,0,0))
pygame.draw.circle(screen,(255,255,0),(400,300),25)
HOM.display()
HOM.calc_gravity()

clock.tick(30)

pygame.display.flip()

最佳答案

您的主要问题与此行有关:

angle = atan(d_x/d_y) #Find angle

atan 函数计算角度的能力非常有限,因为它无法告诉您在除法中组合的坐标的符号。例如,它会对 atan(1/1)atan(-1/-1) 给出相同的结果,因为两个除法计算相同的斜率 ( >1)。

您应该使用atan2,并单独传递坐标。由于这将使代码看到两个坐标,因此它每次都可以在圆的右象限中选取一个角度。

但是还有一个更好的解决办法。为什么不直接计算单位向量,而不是计算角度然后立即将其转换回单位向量(通过调用 sincos )?您已经有了原始向量的长度!而不是:

acc_x = acc*sin(angle) #Convert acceleration from magnitude+angle -> x and y components
acc_y = acc*cos(angle)

用途:

acc_x = acc * d_x / distance
acc_y = acc * d_y / distance

d_x/distanced_y/distance 值与您的 sincos 值相同之前已经得到了(对于它们正常工作时的角度),但是不需要三角学。你可以完全摆脱我在上面引用的那一行!

请注意,您可能需要反转计算d_xd_y的方式,以便获得指向绕轨道运行的物体朝向其绕轨道运行的物体(而不是指向另一个方向,从轨道中心指向绕轨道运行的物体)。我不确定我是否正确地阅读了您的代码,但在我看来,您现在的情况正好相反。这意味着,在当前代码按照您预期的方式工作的情况下,您实际上从 atan 得到了错误的结果,而不良行为(飞到无处可去)是代码“正确”工作(从数学的角度来看)。或者,您可以将 acc 计算为负数,而不是正数。

正如几位评论者提到的,您可能会遇到与选择积分算法相关的其他问题,但这些错误不会像加速角度的主要问题那么大。当您在更长的时间内运行模拟时(并尝试使用更大的时间步长以使模拟进行得更快),它们就会突然出现。您当前的算法对于一两个轨道来说已经足够了,但是如果您要模拟数十或数百个轨道,您将开始看到错误累积,因此您应该选择更好的积分器。

关于python - 重力问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46844603/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com