Modelando o universo: mecânica celeste claramente



Vamos imaginar que precisamos lançar uma bola de futebol na órbita da Terra. Não são necessários foguetes! Montanhas suficientes, uma altura de 100 quilômetros e força notável. Mas quanto você precisa chutar a bola para que ela nunca retorne à Terra? Como enviar a bola em uma jornada para as estrelas, tendo apenas força bruta e conhecimento da mecânica celeste?

Hoje no programa:

  • Infinitas possibilidades de uma fórmula
  • Como tomar energia de Júpiter
  • De onde vêm os planetas
  • Como a matemática ajudou a descobrir Netuno

Felizmente, vivemos na era da tecnologia da computação. Não precisamos escalar uma montanha alta e chutar a bola com toda a nossa força, tudo pode ser modelado! Vamos começar.

Uma fórmula


O mesmo, conhecido pelas lições da física e da astronomia:



mostra o quanto os corpos interagem, dependendo de suas massas, a distância entre eles e a constante gravitacional G.

Escrevi um programa no qual você pode colocar bolas interagindo entre si por forças gravitacionais, com Cada bola tem sua própria massa, velocidade e coordenadas. Para maior clareza, as bolas deixam um rastro.

Vamos colocar uma bola azul grande e maciça (Terra) e uma pequena bola vermelha perto dela. Execute a simulação:



ele caiu!

Para entrar em órbita, é necessária velocidade para que a bola caia e erre a terra o tempo todo. Mas que velocidade? E, novamente, o conhecimento da escola vem em socorro:

a velocidade mínima necessária para entrar na órbita da Terra é chamadaprimeira velocidade cósmica .

Para a Terra, são 7,91 km / s. E para simulação, pode ser facilmente calculado:



dispersamos a bola e vemos o resultado:



Vôo normal!

A bola descreve um círculo com a Terra no centro. O que acontecerá se você der um pouco mais de velocidade? Agora



vamos verificar: agora a forma da órbita é elíptica, podemos distinguir 2 pontos muito importantes - apogeu e perigeu .

Apogeu é o ponto em que a bola está o mais longe possível da Terra.

Perigeu - pelo contrário, o ponto mais próximo da Terra.

Com o aumento da velocidade inicial, o perigeu não muda, mas o apogeu está cada vez mais longe e, no final, tem uma distância infinita da Terra. Aqui chegamos perto do conceitosegunda velocidade espacial . Esta é a velocidade que deve ser dada à bola para que ela supere a gravidade da Terra e voe para longe para arar as extensões do universo. Para terra, são 11,2 km / s.

Um truque interessante: se multiplicarmos a primeira velocidade cósmica por √2, obteremos a segunda velocidade cósmica.

Multiplicado. Lançado. Recebido:



Ele voou para longe irrevogavelmente! A propósito, agora ele tem uma órbita parabólica. E se você correr a bola ainda mais forte, temos uma hipérbole. Curiosamente, a matemática nos assombra em todos os lugares.

Nesse caso, a fórmula permanece a mesma. O círculo se transforma em uma elipse, uma elipse em uma parábola e uma parábola em uma hipérbola devido ao alongamento da órbita (aumento da excentricidade ).

Como tirar energia de Júpiter?


Vamos expandir nosso modelo, adicionar o Sol, fazer a Terra girar em torno dele.



Imagine que a bola precise de uma velocidade que voe para fora do sistema solar - a terceira velocidade cósmica . No mundo real, é 16,7 km / s. Infelizmente, essa velocidade é muito alta, receio que não tenhamos força suficiente ...

Espere! Mas e se você der um pouco de velocidade a um corpo maciço, por exemplo, Júpiter. Podemos voar até algo muito maciço e fazer uma manobra gravitacional . Ao passar por Júpiter, as forças gravitacionais atraem mutuamente a bola e o gigante gasoso, mas a massa da bola é tão pequena que quase não afeta o movimento de Júpiter, e o próprio Júpiter acelera um corpo que passa em alta velocidade.

Fale menos, trabalhe mais:



O momento da manobra gravitacional - a bola voou para Júpiter.



Viva! Temos uma velocidade suficiente para sair do sistema solar, sem gastar nada. É verdade que Júpiter começou a se mover um pouco mais devagar, mas definitivamente não perceberemos.

Todas as naves espaciais lançadas pelo homem além dos limites do sistema solar (Voyagers 1 e 2, Pioneers 10 e 11, New Horizons) usavam exatamente esse método de aceleração.

Mais Zoom!


Acrescentei o atrito das partículas para que, quando colidissem, transferissem parte da energia uma para a outra. Eu também introduzi o poder de uma reação normal, agora as partículas respeitam seu espaço pessoal, afastando outras pessoas de si mesmas.

Colocamos a geração aleatória de bolas e damos a elas uma direção e velocidade aleatórias. Que sejam, digamos, 100 peças.



Caos completo, cada partícula se move para onde quiser, mas, no entanto, as forças gravitacionais têm seu preço e grupos de bolas começam a se formar:



e depois de um tempo um corpo grande é formado, consistindo de 99 bolas e uma única bola orbitando em torno dele:



com outro lançamento, o seguinte :



Dois corpos massivos orbitando um centro de massa comum. Se imaginarmos que esses dois objetos são estrelas, obteremos uma estrela dupla. Curiosamente, cerca de metade das estrelas da nossa galáxia são binárias. Se nosso Sol tivesse uma estrela companheira, no céu poderíamos observar a seguinte figura:



De onde vêm os planetas?


A principal razão para o aparecimento de anéis é a destruição de satélites voando muito perto do planeta, ou melhor, cruzando o limite da Roche . Nesse caso, as forças de maré causadas pela gravidade do planeta se tornam maiores do que as forças que mantêm o satélite intacto e se dividem em várias partes, deixando para trás um anel que circunda o planeta. Vamos simular esta situação:



o satélite está um pouco além do limite da Roche, gira ao redor do planeta em uma órbita circular estável. Mas o que acontece se você o gerar um pouco mais perto do planeta?



O satélite se espalhou em muitas partes pequenas que formaram anéis ao redor do planeta. O mesmo acontece no mundo real. Tritão (satélite de Netuno) está gradualmente se aproximando do planeta, e em 2 bilhões de anos será rasgado, e Netuno terá mais anéis que Saturno.

Como Netuno foi descoberto e o que a matemática tem a ver com isso?


Já que estamos falando de Netuno, vamos falar sobre sua descoberta. "Um planeta aberto na ponta de uma caneta" tem uma massa, o que significa que age sobre os objetos ao redor. Astrônomos do século 19 notaram mudanças na órbita de Urano, sua órbita era diferente da calculada, aparentemente, algo a influenciou. A órbita de Urano teve distúrbios:



esse modelo exagerado mostra como um corpo desconhecido além de Urano afetou sua órbita. Os astrônomos só podiam calcular a posição de um planeta secreto e olhar através de um telescópio. De fato, o planeta Netuno estava exatamente onde foi previsto!



Conclusão


Certamente, essa simulação não generaliza todas as leis e fenômenos que ocorrem no espaço, por exemplo, a teoria da relatividade de Einstein não é levada em consideração aqui, pois a velocidade das partículas está longe da velocidade da luz. Mas há muitas coisas mais interessantes que podem ser implementadas nesta simulação. Tente você mesmo! Tudo o que você precisa é Python3 e a biblioteca Pygame.

Fonte
# 
Track = True

# 
Track_time = 5

# 
G = 5

#  (  -
#,  - )
MagnConst = 0

# 
count = 100

#  
kv = 6

#  
RANDOM = True

#  
r = 3

#   
WIN_WIDTH, WIN_HEIGHT = 900, 650


''',  ,   '''

#   
zg = 2

#   
zm = 2

#. ,    -   
k = 40

# 
antiG = 0.1

max_speed = 3

ResDist = 1

# 
EarthG = 0

#   
Mirror = True

import pygame
from math import hypot, ceil, sqrt
from random import randint, random


def custom_pos():
    '''      '''
    '''   RANDOM = FALSE'''
    B.append(Ball(200, 300, YELLOW, r = 10, mass = 200, vx = 0.151))    #x, y, col, r, vx, vy, mass
    B.append(Ball(200, 50, GREEN, r = 6, mass = 10, vx = -(200 * G / 250)**0.5))
    

class Ball:
    def __init__(self, x, y, col, r = 4, vx = 0, vy = 0, mass = 4):
        self.x = x
        self.y = y
        self.r = r
        self.col = col
        self.vx = vx
        self.vy = vy
        self.mass = mass
        
    def move(self, Walls, WIN_WIDTH, WIN_HEIGHT, ofs_x, ofs_y):
        if Walls:
            x = self.x - ofs_x
            y = self.y - ofs_y
            if x <= 0 and self.vx < 0:
                if Mirror:
                    self.vx = -self.vx
                else:
                    self.x += WIN_WIDTH
                self.vx, self.vy = self.v_norm(self.vx, self.vy)
            if x >= WIN_WIDTH and self.vx > 0:
                if Mirror:
                    self.vx = -self.vx
                else:
                    self.x -= WIN_WIDTH
                self.vx, self.vy = self.v_norm(self.vx, self.vy)
            if y <= 0 and self.vy < 0:
                if Mirror:
                    self.vy = -self.vy
                else:
                    self.y += WIN_HEIGHT
                self.vx, self.vy = self.v_norm(self.vx, self.vy)
            if y >= WIN_HEIGHT and self.vy > 0:
                if Mirror:
                    self.vy = -self.vy
                else:
                    self.y -= WIN_HEIGHT
                self.vx, self.vy = self.v_norm(self.vx, self.vy)
            
        self.x += self.vx
        self.y += self.vy

        
    def force(self, ind, selfind):
        ox = B[ind].x
        oy = B[ind].y
        m = B[ind].mass
        if m < 0.01 and self.mass < 0.01:
            return 0
        r = B[ind].r
        vx = B[ind].vx
        vy = B[ind].vy
        dist = hypot(self.x - ox, self.y - oy)
        min_dist = (self.r + B[ind].r) * ResDist
        f = 0
        m_relative = self.mass / B[ind].mass
        if dist <= min_dist:
            newVx = (vx * m + self.vx * self.mass) / (m + self.mass)
            newVy = (vy * m + self.vy * self.mass) / (m + self.mass)
            self.vx = (newVx + k * self.vx) / (k + 1)
            B[ind].vx = (newVx + k * B[ind].vx) / (k + 1)
            self.vy = (newVy + k * self.vy) / (k + 1)
            B[ind].vy = (newVy + k * B[ind].vy) / (k + 1)
            f -= antiG * min(abs(min_dist - dist), min(m, self.mass) * 3)
        else:
            f += min(self.mass * B[ind].mass * G  / (dist ** zg), G / 10)
            mf = MagnConst * self.mass / (dist ** zm)
            if B[ind].col == B[selfind].col:
                mf = - mf
            f += mf
        fx = f * ((ox - self.x) / dist)
        fy = f * ((oy - self.y) / dist)
        ax = fx / self.mass
        ay = fy / self.mass
        self.vx += ax
        self.vy += ay + EarthG
        B[ind].vx -= ax * m_relative
        B[ind].vy -= ay * m_relative - EarthG

    @staticmethod
    def v_norm(vx, vy):
        v = hypot(vx, vy)
        if v > max_speed:
            vx = max_speed * (vx / v)
            vy = max_speed * (vy / v)
        return vx, vy


class Point:
    def __init__(self, x, y, col, r = 0, max_age = Track_time):
        self.age = 0
        self.x = x
        self.y = y
        self.col = col
        self.r = r
        self.max_age = max_age
    def vis(self, ofs_x, ofs_y):
        pygame.draw.circle(sc, self.col, (round(self.x - ofs_x),
                                          round(self.y - ofs_y)), self.r, 0)
        self.age += 1
        if self.age > self.max_age:
            T.remove(self)
        
def rand(count, WIN_WIDTH, WIN_HEIGHT):
    global kv
    B = []
    for i in range(count):
        m = r ** 2
        x = randint(0, WIN_WIDTH) + random()
        y = randint(0, WIN_HEIGHT) + random()
        vx = kv * randint(-100, 100) / 100
        vy = kv * randint(-100, 100) / 100
        col = Colors[randint(0, len(Colors) - 1)]
        B.append(Ball(x, y, col, r = r, vx = vx, vy = vy, mass = m))
    return B

def createBall(col, x, y, r = r, m = r):
    m = r
    B.append(Ball(x, y, col))

def get_offset(B):
    sum_x, sum_y = 0, 0
    m = 0
    for i in range(len(B)):
        sum_x += B[i].x * B[i].mass
        sum_y += B[i].y * B[i].mass
        m += B[i].mass
    if len(B) == 0:
        return 0, 0
    return sum_x / m, sum_y / m

def visBalls(B):
    for i in range(len(B)):
        pygame.draw.circle(sc, B[i].col, (round(B[i].x - ofs_x),
                                          round(B[i].y - ofs_y)), B[i].r, 0)
        T.append(Point(B[i].x, B[i].y, B[i].col))
        
FPS = 60
darkblue = (0, 2, 25)
ORANGE = (255, 200, 150)
RED = (255, 150, 150)
GREEN = (150, 255, 150)
BLUE = (150, 150, 255)
YELLOW = (255, 255, 0)
Colors = [RED, BLUE]#, GREEN]#, ORANGE]                       
pygame.init() 
clock = pygame.time.Clock()
sc = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
sc.fill(darkblue)

maxF = 0.3
minv = 0.01
Walls = True
Collisions = True
Same = True
Check = False
tt = []

B = []
if RANDOM:
    B = rand(count, WIN_WIDTH, WIN_HEIGHT)
else:
    custom_pos()
    
Pause = False
delay = 0

if Track:
    T = []
for z in range(100000):
    sc = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
    sc.fill(darkblue)
    ofs_x, ofs_y = get_offset(B)
    ofs_x -= WIN_WIDTH // 2
    ofs_y -= WIN_HEIGHT // 2
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            pygame.quit()
            quit()
        if i.type == pygame.KEYDOWN:
            if i.key == pygame.K_SPACE:
                Pause = not Pause
            elif i.key == pygame.K_w:
                WIN_HEIGHT += 10
                WIN_WIDTH += 10
            elif i.key == pygame.K_s:
                WIN_HEIGHT -= 10
                WIN_WIDTH -= 10
                
    pressed = pygame.mouse.get_pressed()
    pos = pygame.mouse.get_pos()
    x = pos[0]
    y = pos[1]
    if pressed[0] and delay < 0:
        delay = 20
        createBall(RED, x + ofs_x, y + ofs_y)
    if pressed[2] and delay < 0:
        delay = 20
        createBall(BLUE, x + ofs_x, y + ofs_y )
    delay -= 1
    
    if not Pause:
        for i in range(len(B)):
            for j in range(i + 1, len(B)):
                B[i].force(j, i)
        for i in range(len(B)):
            B[i].move(Walls, WIN_WIDTH, WIN_HEIGHT, ofs_x, ofs_y)
    for i in range(len(T)):
        try:
            T[i].vis(ofs_x, ofs_y)
        except IndexError:
            pass
    visBalls(B)
    
    pygame.display.update()
    clock.tick(FPS)


Espero que este artigo tenha sido informativo para você. Obrigado pela atenção!

All Articles