Я пытаюсь создать симуляцию планет из двух тел в Python, используя FuncAnimation. Я создал функцию, которая правильно рассчитывает их положение с течением времени, и подтвердил, что она работает при использовании отладчика. Однако, когда я передаю функцию в FuncAnimation и запускаю ее, она просто открывает stap c matplotlib, вычисляя только самый первый временной шаг. Кроме того, у меня уже была работающая анимация, но она перестала работать после внесения более значительных изменений в мой другой код.
class Simulation(object):
def __init__(self, cbodies, dt):
self.dt = dt
self.bodies = cbodies
self.kinetic = 0
for i in self.bodies:
self.kinetic += i.kinetic()
def update_positions(self):
self.t = 0
while self.t < 100:
for i in range(len(self.bodies)):
self.t += self.dt
bodies_except = np.delete(self.bodies, i)
self.bodies[i].update_position(bodies_except, self.dt)
return self.bodies
def init(self):
for j in range(0,len(patches)):
patches[j].center = tuple(self.bodies[j].pos)
return patches
def animate(self, i):
self.update_positions()
for j in range(0,len(patches)):
patches[j].center = tuple(self.bodies[j].pos)
return patches
def run(self):
global fig, ax, bodies, patches
for i in self.bodies:
patches.append(plt.Circle((tuple(i.pos)), 10**5, color = 'r', animated = True))
for i in range(0, len(patches)):
ax.add_patch(patches[i])
print(str(self.kinetic) + "J" + "\n")
print(str(self.bodies[0]) + "\n")
anim = FuncAnimation(fig, self.animate, init_func = self.init, frames = 300, repeat = True, interval = .01, blit = True)
plt.show()
Метод update_positions () вызывается для экземпляров класса CelestialBody:
class CelestialBody:
def __init__(self, mass, position, velocity):
self.mass = mass
self.pos = np.array(position)
self.vel = np.array(velocity)
def distance(self, body):
rel_position = body.pos - self.pos
return rel_position
def calculate_force(self, body, dt):
m1 = self.mass
m2 = body.mass
r = self.distance(body)
r_mag = np.linalg.norm(r)
r_unit = r / r_mag
force = G * ((m1*m2)/(r_mag**2)) * r_unit
return force
def total_acc(self, cbodies, dt):
acc = 0
for i in cbodies:
acc_i = self.calculate_force(i, dt) / self.mass
acc += acc_i
return acc
def update_velocity(self, cbodies, dt):
self.vel = self.total_acc(cbodies, dt)*dt
return self.vel
def update_position(self, cbodies, dt):
self.pos += self.update_velocity(cbodies, dt)*dt
return self.pos