jm2*_*22b 1 python class python-2.7
我编写了一个计算冥王星轨道并设置动画的程序,并开始使用类重写它,因为这似乎是将更多行星引入模拟的明智方法。即有一个定义物理的类,然后输入特定的行星数据以获得轨道数据。
class Planet(object):
m_sun = 1.989*(10**30)
G = 6.67*(10**-11)
dt = 1
coords = []
def __init__(self, x, y, vx, vy, m):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.m = m
def genData(self):
while self.dt < 100000000:
r = ((self.x)**2 + (self.y)**2)**0.5
a = ((self.G*self.m_sun)/r**2)
ax = -a*((self.x)/r)
ay = -a*((self.y)/r)
self.vx = self.vx + ax*self.dt
self.vy = self.vy + ay*self.dt
self.x = self.x + self.vx*self.dt
self.y = self.y + self.vy*self.dt
coord = (self.x, self.y)
print coord
self.coords.append(coord)
self.dt = self.dt + 1000
pluto = Planet(4495978707000, 0, 0, 4670, 1.305*(10**22))
pluto.genData()
Run Code Online (Sandbox Code Playgroud)
我确定它并不完美,但它似乎正在工作(这是我自己构建的第一个类)。我的问题是如何将“坐标”中的数据提取到我可以在课外使用的列表中。
我想为每个星球生成数据,然后使用这些数据在 Pygame 中创建动画。例如,冥王星、地球、土星等的 (x,y) 坐标列表。就目前而言,它会生成数据,但似乎无法从类外部访问它。
我希望我的问题是有道理的。
谢谢!
您的问题已得到解答,但我有一些您应该会发现对改进程序有用的信息。从技术上讲,此信息属于评论(因为您实际上并未在问题中询问此问题),但它不适合。:)
冥王星的轨道向黄道倾斜了很多,所以如果你想将它与太阳系中的其他几颗行星一起绘制,你需要在 3D 中工作才能准确。但我想这对您的应用程序来说没什么大不了的。
与冥王星相比,地球的轨道很小,因此您可能需要实现缩放才能在一个动画中同时看到它们。
通过使用标准重力参数而不是使用单独的 G 和质量值,您可以获得更高的计算精度。
您用于计算速度和位置的算法称为Euler 积分。相当于用多边形逼近轨道曲线。它有效,但不是很准确。因此,您需要使时间增量非常小,否则轨道将不太现实,甚至可能不是闭合曲线。即便如此也无济于事,因为误差是累积性的,所以最终计算出的轨道与现实几乎没有相似之处。
没有任何数值积分技术是完美的(除了非常简单的函数),但更准确(因此可以在更大的时间步长下正常工作)的流行积分技术系列是Runge-Kutta 方法。你可以找到很多使用 Runge-Kutta 方法计算轨道的示例代码;大多数代码示例使用称为 RK4 的变体。
但是,我强烈建议您尝试Leapfrog集成。编写 Leapfrog 的同步形式非常容易,并且它比 Runge-Kutta 的主要优点在于它是辛的,这(粗略地)意味着它节省了能量,因此误差不会从轨道到轨道累积。