Modélisation de l'univers: la mécanique céleste clairement



Imaginons que nous devons lancer un ballon de football sur l'orbite de la Terre. Aucune fusée nécessaire! Assez de montagnes, une hauteur de 100 kilomètres et une force remarquable. Mais de combien avez-vous besoin pour lancer la balle afin qu'elle ne revienne jamais sur Terre? Comment envoyer la balle dans un voyage vers les étoiles, n'ayant que la force brute et la connaissance de la mécanique céleste?

Aujourd'hui au programme:

  • Possibilités infinies d'une formule
  • Comment prendre l'énergie de Jupiter
  • D'où viennent les planètes
  • Comment les mathématiques ont aidé à découvrir Neptune

Heureusement, nous vivons à l'ère de la technologie informatique. Nous n'avons pas besoin de gravir une haute montagne et de botter le ballon de toutes nos forces, tout peut être modélisé! Commençons.

Une formule


Le même, connu des leçons de physique et d'astronomie:



il montre à quel point les corps vont interagir, selon leurs masses, la distance entre eux et la constante gravitationnelle G.

J'ai écrit un programme dans lequel vous pouvez placer des boules interagissant les unes avec les autres par des forces gravitationnelles, avec Chaque balle a sa propre masse, vitesse et coordonnées. Pour plus de clarté, les boules laissent une trace.

Mettons une grande et massive boule bleue (Terre) et une petite boule rouge près d'elle. Exécutez la simulation:



il est tombé!

Pour entrer en orbite, il faut de la vitesse pour que la balle tombe et rate la terre tout le temps. Mais QUELLE vitesse? Et encore une fois, les connaissances scolaires viennent à la rescousse:

la vitesse minimale requise pour entrer dans l'orbite de la Terre est appeléepremière vitesse cosmique .

Pour la Terre, c'est 7,91 km / s. Et pour la simulation, il peut être facilement calculé: nous



dispersons le ballon et voyons le résultat:



vol normal!

La balle décrit un cercle avec la Terre au centre. Que se passera-t-il si vous lui donnez un peu plus de vitesse? Maintenant



, vérifions: maintenant la forme de l'orbite est elliptique, nous pouvons distinguer 2 points très importants - l' apogée et le périgée .

Apogee est le point où la balle est aussi éloignée que possible de la Terre.

Périgée - au contraire, le point le plus proche de la Terre.

Avec une augmentation de la vitesse initiale, le périgée ne change pas, mais l'apogée va plus loin, et à la fin, il a une distance infinie avec la Terre. Ici, nous nous rapprochons du conceptdeuxième vitesse spatiale . C'est la vitesse qui doit être donnée au ballon pour qu'il surmonte la gravité de la Terre et s'envole pour labourer les étendues de l'univers. Pour la terre, c'est 11,2 km / s.

Une astuce intéressante: si nous multiplions la première vitesse cosmique par √2, nous obtenons la deuxième vitesse cosmique.

Multiplié. Lancé. Reçu:



Il s'envola irrévocablement! Au fait, il a maintenant une orbite parabolique. Et si vous exécutez le ballon encore plus fort, nous obtenons une hyperbole. Il s'avère que les mathématiques nous hantent partout.

Dans ce cas, la formule reste la même. Le cercle se transforme en ellipse, une ellipse en parabole et une parabole en hyperbole en raison de l'allongement de l'orbite ( excentricité accrue ).

Comment prendre l'énergie de Jupiter?


Développons notre modèle, ajoutons le Soleil, faisons tourner la Terre autour de lui.



Imaginez que la balle ait besoin d'une vitesse telle qu'elle vole en dehors du système solaire - la troisième vitesse cosmique . Dans le monde réel, c'est 16,7 km / s. Malheureusement, cette vitesse est trop élevée, je crains que nous n'ayons pas assez de force ...

Attendez! Mais que se passe-t-il si vous prenez un peu de vitesse d'un corps massif, par exemple Jupiter. Nous pouvons voler jusqu'à quelque chose de très massif et faire une manœuvre gravitationnelle . En survolant Jupiter, les forces gravitationnelles attirent mutuellement la balle et la géante gazeuse, mais la masse de la balle est si petite qu'elle n'a presque aucun effet sur le mouvement de Jupiter, et Jupiter accélère lui-même le corps qui passe à grande vitesse.

Parlez moins, travaillez plus:



Le moment de la manœuvre gravitationnelle - la balle a volé jusqu'à Jupiter.



Hourra! Nous avons obtenu une vitesse suffisante pour sortir du système solaire, sans rien dépenser. Certes, Jupiter a commencé à se déplacer un peu plus lentement, mais nous ne le remarquerons certainement pas.

Tous les vaisseaux spatiaux lancés par l'homme au-delà des limites du système solaire (Voyagers 1 et 2, Pionniers 10 et 11, New Horizons) ont utilisé une telle méthode d'accélération.

Agrandir!


J'ai ajouté le frottement des particules pour que lorsqu'elles entrent en collision, elles se transfèrent une partie de l'énergie les unes aux autres. J'ai également introduit le pouvoir d'une réaction normale, maintenant les particules respectent leur espace personnel, éloignant les autres d'eux-mêmes.

Nous mettons la génération aléatoire de balles et leur donnons une direction et une vitesse aléatoires. Qu'ils soient, disons, 100 pièces.



Chaos complet, chaque particule se déplace où elle veut, mais néanmoins, les forces gravitationnelles font des ravages et des grappes de balles commencent à se former:



Et après un certain temps, un grand corps se forme, composé de 99 balles et d'une seule balle en orbite autour d'elle:



Avec un autre lancement, ce qui suit :



Deux corps massifs en orbite autour d'un centre de masse commun. Si nous imaginons que ces deux objets sont des étoiles, alors nous obtenons une double étoile. Fait intéressant, environ la moitié des étoiles de notre galaxie sont binaires. Si notre Soleil avait une étoile compagnon, alors dans le ciel, nous pourrions observer l'image suivante:



D'où viennent les planètes?


La principale raison de l'apparition d'anneaux est la destruction de satellites volant trop près de la planète, ou plutôt franchissant la limite de Roche . Dans ce cas, les forces de marée causées par la gravité de la planète deviennent plus importantes que les forces qui maintiennent le satellite intact, et il se divise en plusieurs parties, laissant derrière lui un anneau qui encercle la planète. Simulons cette situation:



le satellite est un peu plus loin que la limite de Roche, il tourne autour de la planète sur une orbite circulaire stable. Mais que se passe-t-il si vous le générez un peu plus près de la planète?



Le satellite s'est dispersé en de nombreuses petites parties qui ont formé des anneaux autour de la planète. C'est donc dans le monde réel. Triton (satellite de Neptune) s'approche progressivement de la planète et, dans 2 milliards d'années, il sera déchiré et Neptune aura plus d'anneaux que Saturne.

Comment Neptune a-t-il été découvert et qu'est-ce que les mathématiques ont à voir avec ça?


Puisque nous parlons de Neptune, parlons de sa découverte. «Une planète ouverte à la pointe d'un stylo» a une masse, ce qui signifie qu'elle agit sur les objets alentour. Les astronomes du 19ème siècle ont remarqué des changements dans l'orbite d'Uranus, son orbite était différente de celle calculée, apparemment, quelque chose l'influença. L'orbite d'Uranus avait des perturbations:



ce modèle exagéré montre comment un corps inconnu au-delà d'Uranus a affecté son orbite. Les astronomes ne pouvaient calculer que la position d'une planète secrète et regarder à travers un télescope. En effet, la planète Neptune était exactement là où elle était prévue!



Conclusion


Bien sûr, cette simulation ne généralise pas toutes les lois et phénomènes se produisant dans l'espace, par exemple, la théorie de la relativité d'Einstein n'est pas prise en compte ici, car la vitesse des particules est loin de la vitesse de la lumière. Mais il y a beaucoup d'autres choses intéressantes qui peuvent être implémentées dans cette simulation. Essayez-le vous-même! Tout ce dont vous avez besoin est Python3 et la bibliothèque Pygame.

La source
# 
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)


J'espère que cet article vous a été instructif. Merci pour l'attention!

All Articles