📜 ⬆️ ⬇️

Create a solar system simulator

Foreword
Eternal thrust to the new pushed for the study of such a wonderful programming language like Python. As is often the case, the absence of an idea, the implementation of which is not a pity to spend your time, greatly slowed down the process.

By the will of fate, I came across a remarkable series of articles on the creation of a platform game on Python
here and here .
I decided to take on one old project. For the simulator of the movement of bodies under the action of gravitational forces.

What came of this, read on.
')
Part one. Theoretical

To solve a problem, you must first clearly imagine it.
Suppose, by hook or by crook, we managed to get a two-dimensional piece of airless space with the bodies in it. All bodies move by gravity. There is no external impact.
It is necessary to build the process of their movement relative to each other. The simplicity of implementation and the brilliance of the final result will serve as an incentive and reward. Mastering Python will be a good investment in the future.

We introduce a coordinate system.

Let our system consists of two bodies:
1. massive star of mass M and center (x0, y0)
2. light planet of mass m, with center at point (x, y), speed v = (vx, vy) and acceleration a = (ax, ay).

When we manage to disassemble this case, we can easily move on to complex systems with the mutual influence of the stars and planets on each other. Now we will talk about the simplest.

After simple manipulations with Newton's second law, the law of world wideness, and similar triangles, I found that:

ax = G * M * (x0-x) / r ^ 3
ay = G * M * (y0-y) / r ^ 3

This allows you to create an algorithm for moving the planet in the gravitational field of a star:

1. Before the start we set the initial position of the planet (x, y) and the initial velocity (vx, vy)
2. At each step, we calculate the new acceleration using the formula above, then recalculate the speed and coordinates:

vx: = vx + T * ax
vy: = vy + t * ax

x: = x + T * vx
y: = y + T * yx

It remains to deal with the constants G and T. Put G = 1. For our problem, this is not so important. The parameter T affects the accuracy and speed of the calculations. Also put 1 to start.

Part two. Practical

So, my first program on Python. At the same time once again I want to thank Velese for the practical guidance.

import pygame, math from pygame import * from math import * WIN_WIDTH = 800 WIN_HEIGHT = 640 PLANET_WIDTH = 20 PLANET_HEIGHT = 20 DISPLAY = (WIN_WIDTH, WIN_HEIGHT) SPACE_COLOR = "#000022" SUN_COLOR = "yellow" PLANET_COLOR = "blue" #Sun position X0 = WIN_WIDTH // 2 Y0 = WIN_HEIGHT // 2 #Sun mass M0 = 5000 #Stop conditions CRASH_DIST = 10 OUT_DIST = 1000 def main(): #PyGame init pygame.init() screen = pygame.display.set_mode(DISPLAY) pygame.display.set_caption("Solar Mechanics v0.1") #Space init bg = Surface((WIN_WIDTH,WIN_HEIGHT)) bg.fill(Color(SPACE_COLOR)) draw.circle (bg, Color(SUN_COLOR), (X0, Y0), 10) #Timer init timer = pygame.time.Clock() #Planet init planet = Surface((PLANET_WIDTH, PLANET_HEIGHT)) planet.fill(Color(SPACE_COLOR)) draw.circle (planet, Color(PLANET_COLOR), (PLANET_WIDTH // 2, PLANET_HEIGHT // 2), 5) #Planet to Sun distance r = 0.0 #Initial planet pos, speed and accel x = 100.0 y = 290.0 vx = 0.1 vy = 1.5 ax = 0.0 ay = 0.0 done = False while not done: timer.tick(50) for e in pygame.event.get(): if e.type == QUIT: done = True break r = sqrt((x - X0)**2 + (y - Y0)**2) ax = M0 * (X0 - x) / r**3 ay = M0 * (Y0 - y) / r**3 #New spped based on accel vx += ax vy += ay #New pos based on speed x += vx y += vy screen.blit(bg, (0, 0)) screen.blit(planet, (int(x), int(y))) pygame.display.update() if r < CRASH_DIST: done = True print("Crashed") break if r > OUT_DIST: done = True print("Out of system") break #Farewell print (":-)") if __name__ == "__main__": main() 


This is how our system looks after some simulation time.



While this note was being written, the simulator expanded with new functionality: the number of objects in the star system is not limited, their mutual influence on each other is taken into account, the calculated part is moved to its class, the system configuration is set in a separate file and the system selection option is added.

Now I’m looking for interesting system scripts and minor interface improvements.

Here is an example of what is currently in development:


If this article meets with positive reviews, I promise to continue the story of a newer version.

Update:

1. I am grateful to all commentators for critical comments. They give great food for thought.

2. The project has grown. All bodies are already independent, they affect each pipe in accordance with the law of the world. N ^ 2 interactions are counted.
Now it is possible to store the star system configurations in external files and select at the start.
Code here
Run like this: python3.3 main.py -f <configuration name> .ini
Different configurations are there.

3. Thanks to the comments, it was possible to find and eliminate the main flaw - the method of calculating coordinates.
The Runge-Kutta method is now used. As I read Non-Rigid Tasks, I will learn new methods.

Source: https://habr.com/ru/post/197754/


All Articles