Гравитация системы точек
Написал маленькую программку с помощью пайгейм, имитирующую гравитацию системы точек. Поведение не совсем такое, как ожидалось. Все точки взаимодействуют между собой по закону всемирного тяготения, но нет никакого движения одних точек вокруг других, а оно должно быть. Все точки просто схлопываются друг с другом, пока не останется только одна. В чем ошибка? В самом коде или в системе рассчёта? Класс частиц:
class Particle(pygame.sprite.Sprite):
color = 'yellow2'
id_iter = itertools.count().__next__
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.x = x # Начальная координата точки по x
self.y = y # Начальная координата точки по y
self.m = 1 # Условная масса точки, она же радиус для отрисовки
self.v = (0, 0) # Начальная скорость точки по x и y
self.vector = pygame.math.Vector2(self.x, self.y) # Вектор расстояния до точки
self.id = Particle.id_iter() # Порядковый номер точки
self.add(particles) # Добавление точки в группу спрайтов
def draw(self, surface):
pygame.draw.circle(surface, self.color, (self.x, self.y), self.m)
def moving(self, t):
self.v = acceleration(self.x, self.y, self.id, self.vector, particles) # Вычисление ускорения
self.x += self.v[0] * t**2 / 2 # Ускорение по x
self.y += self.v[1] * t**2 / 2 # Ускорение по y
self.vector = pygame.math.Vector2(self.x, self.y) # Обновление расстояния до точки
def check_collide(self):
for particle in particles:
if particle.vector.distance_to(self.vector) <= (particle.m + self.m) and particle.id != self.id:
self.m += 0.75 * particle.m
particle.kill()
Функция расчёта ускорения:
def acceleration(part_x, part_y, part_id, part_v, particles):
g_const = 6.67
total_acc_x = []
total_acc_y = []
for particle in particles:
if particle.id != part_id:
part_dx = particle.x - part_x
part_dy = particle.y - part_y
r = particle.vector.distance_to(part_v) # Расстояние между парами частиц
part_acc = g_const * particle.m / r**2 # Гравитация между парами частиц
part_acc_x = part_acc * part_dx / r # Гравитация между парами по оси x
part_acc_y = part_acc * part_dy / r # По оси y
total_acc_x.append(part_acc_x)
total_acc_y.append(part_acc_y)
acc_x_sum = sum(total_acc_x) # Средняя величина ускорения по оси x
acc_y_sum = sum(total_acc_y) # По оси y
return acc_x_sum, acc_y_sum
Основной игровой цикл:
def run():
t = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.VIDEOEXPOSE: # Window minimization/open
pygame.display.update()
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
x, y = event.pos
particle = Particle(x, y)
particle.v = 1, 1
particle.draw(screen)
screen.fill((0, 0, 0))
for particle in particles:
particle.moving(t)
particle.check_collide()
particle.draw(screen)
t += 0.03
pygame.display.update()
clock.tick(30)
Ответы (1 шт):
Автор решения: Никомах
→ Ссылка
Проблема решилась очень просто. Надо было добавить линейную скорость каждой частице, которая равна разнице пройденного расстояния по осям х и у на каждом цикле. Плюс две строчки к коду.