我正在尝试使用 py 制作一个基本的重力模拟,但由于某种原因,它会将所有线条绘制成直线,当我遇到困难时,我查看了几个示例,但它们都使用类似的方程/绘制数据的方式,所以不确定我哪里出错了
class Body:
# A class to initialise a body of mass to plot
def __init__(self, id, mass, coordinates, velocities):
self.id = id
self.coordinates = np.array(coordinates, dtype=float)
self.v = np.array(velocities, dtype=float)
self.mass = mass
self.a = np.zeros(3, dtype=float)
MOTION_LOG.append({"name": self.id, "x":[coordinates[0]], "y": [coordinates[1]], "z": [coordinates[2]]})
# Procedure for checking gravity effects on body
def gravity(self):
self.a = 0
for body in bodies:
if body != self:
dist = body.coordinates - self.coordinates
r = np.sqrt(np.sum(dist**2))
self.a += (SETTINGS['G'] * body.mass * dist / r**3) ** 2
# Procedure to plot the new coordinates of the body
def move(self):
self.v += self.a * SETTINGS["deltaT"]
self.coordinates += self.v * SETTINGS['deltaT']
然后实际模拟它我做了
# For loop to run a simulation for a specific time set
for step in range(int(SETTINGS["tLimit"] / SETTINGS["deltaT"])):
SETTINGS['elapsedT'] += SETTINGS['deltaT']
if SETTINGS['elapsedT'] % SETTINGS["frequency"] == 0:
prog = ((SETTINGS['elapsedT'] / SETTINGS['tLimit'])*100)//1
for index, location in enumerate(MOTION_LOG):
location["x"].append(bodies[index].coordinates[0])
location["y"].append(bodies[index].coordinates[1])
location["z"].append(bodies[index].coordinates[2])
print(f"{prog}%")
for body in bodies:
body.gravity()
for body in bodies:
body.move()
然后最后在我做的图表上绘制它
fig = plt.figure()
ax = fig.add_subplot(1,1,1, projection='3d')
for body in MOTION_LOG:
ax.plot(body["x"], body["y"], body["z"])
plt.show()
不知道我是不是刚刚做错了加速,或者我只是把点画错了,但我见过的其他例子做的事情并没有太大的不同
示例数据
SETTINGS = {
'G' : 6.67e-11,
'deltaT' : 172800,
'elapsedT' : 0,
'tLimit' : 315360000,
"frequency": 1,
}
MOTION_LOG = []
bodies = []
set_bodies = {
"Sun": {
"id": "Sun",
"mass": 1e20,
"coordinates": [0, 0, 0],
"velocities": [0, 0, 0]
},
"Earth": {
"id": "Earth",
"mass": 1e3,
"coordinates": [1e2, -1e2, 0],
"velocities": [0, 0, 0]
}
}
for body, body_data in set_bodies.items():
bodies.append(Body(**body_data))