Гравитация системы точек

Написал маленькую программку с помощью пайгейм, имитирующую гравитацию системы точек. Поведение не совсем такое, как ожидалось. Все точки взаимодействуют между собой по закону всемирного тяготения, но нет никакого движения одних точек вокруг других, а оно должно быть. Все точки просто схлопываются друг с другом, пока не останется только одна. В чем ошибка? В самом коде или в системе рассчёта? Класс частиц:

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 шт):

Автор решения: Никомах

Проблема решилась очень просто. Надо было добавить линейную скорость каждой частице, которая равна разнице пройденного расстояния по осям х и у на каждом цикле. Плюс две строчки к коду.

→ Ссылка