Skip to content

Develop #35

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 2016-solar_project
Submodule 2016-solar_project added at a2df82
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# solar_project
Модель Солнечной системы на языке Python

Работает!!
1 change: 0 additions & 1 deletion feature

This file was deleted.

107 changes: 107 additions & 0 deletions planet_and_moon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# https://github.com/python/cpython/tree/master/Lib/turtledemo
""" turtle-example-suite:
tdemo_planets_and_moon.py
Gravitational system simulation using the
approximation method from Feynman-lectures,
p.9-8, using turtlegraphics.
Example: heavy central body, light planet,
very light moon!
Planet has a circular orbit, moon a stable
orbit around the planet.
You can hold the movement temporarily by
pressing the left mouse button with the
mouse over the scrollbar of the canvas.
"""
from turtle import Shape, Turtle, mainloop, Vec2D as Vec

G = 8

class GravSys(object):
def __init__(self):
self.planets = []
self.t = 0
self.dt = 0.01
def init(self):
for p in self.planets:
p.init()
def start(self):
for i in range(10000):
self.t += self.dt
for p in self.planets:
p.step()

class Star(Turtle):
def __init__(self, m, x, v, gravSys, shape):
Turtle.__init__(self, shape=shape)
self.penup()
self.m = m
self.setpos(x)
self.v = v
gravSys.planets.append(self)
self.gravSys = gravSys
self.resizemode("user")
self.pendown()
def init(self):
dt = self.gravSys.dt
self.a = self.acc()
self.v = self.v + 0.5*dt*self.a
def acc(self):
a = Vec(0,0)
for planet in self.gravSys.planets:
if planet != self:
v = planet.pos()-self.pos()
a += (G*planet.m/abs(v)**3)*v
return a
def step(self):
dt = self.gravSys.dt
self.setpos(self.pos() + dt*self.v)
if self.gravSys.planets.index(self) != 0:
self.setheading(self.towards(self.gravSys.planets[0]))
self.a = self.acc()
self.v = self.v + dt*self.a

## create compound yellow/blue turtleshape for planets

def main():
s = Turtle()
s.reset()
s.getscreen().tracer(0,0)
s.ht()
s.pu()
s.fd(6)
s.lt(90)
s.begin_poly()
s.circle(6, 180)
s.end_poly()
m1 = s.get_poly()
s.begin_poly()
s.circle(6,180)
s.end_poly()
m2 = s.get_poly()

planetshape = Shape("compound")
planetshape.addcomponent(m1,"orange")
planetshape.addcomponent(m2,"blue")
s.getscreen().register_shape("planet", planetshape)
s.getscreen().tracer(1,0)

## setup gravitational system
gs = GravSys()
sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle")
sun.color("yellow")
sun.shapesize(1.8)
sun.pu()
earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet")
earth.pencolor("green")
earth.shapesize(0.8)
moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet")
moon.pencolor("blue")
moon.shapesize(0.5)
gs.init()
gs.start()
return "Done!"

if __name__ == '__main__':
main()
mainloop()
98 changes: 51 additions & 47 deletions solar_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,44 @@
from solar_objects import Star, Planet


def read_space_objects_data_from_file(input_filename):
"""Cчитывает данные о космических объектах из файла, создаёт сами объекты
и вызывает создание их графических образов

Параметры:

**input_filename** — имя входного файла
"""

objects = []
with open(input_filename) as input_file:
for line in input_file:
if len(line.strip()) == 0 or line[0] == '#':
continue # пустые строки и строки-комментарии пропускаем
object_type = line.split()[0].lower()
if object_type == "star": # FIXME: do the same for planet
star = Star()
parse_star_parameters(line, star)
objects.append(star)
else:
print("Unknown space object")
space_objects = []

return objects

# Заменила функции parse_planet_parameters и parse_star_parameters на эту:
def parse_object_parameters(line):

def parse_star_parameters(line, star):
"""Считывает данные о звезде из строки.
"""Считывает данные о звезде или планете из строки.
Входная строка должна иметь слеюущий формат:
Star <радиус в пикселах> <цвет> <масса> <x> <y> <Vx> <Vy>
Planet <радиус в пикселах> <цвет> <масса> <x> <y> <Vx> <Vy>

Здесь (x, y) — координаты зведы, (Vx, Vy) — скорость.
Здесь (x, y) — координаты зведы или планеты, (Vx, Vy) — скорость.
Пример строки:
Star 10 red 1000 1 2 3 4

Параметры:

**line** — строка с описание звезды.
**star** — объект звезды.
"""
type_, R, color, m, x, y, Vx, Vy = line.split(' ')
type_ = type_.lower()

pass # FIXME: not done yet
if type_ == 'planet':
obj = Planet()
elif type_ == 'star':
obj = Star()
else:
print('Invalid type of object.')
raise ValueError

def parse_planet_parameters(line, planet):
"""Считывает данные о планете из строки.
Предполагается такая строка:
Входная строка должна иметь слеюущий формат:
Planet <радиус в пикселах> <цвет> <масса> <x> <y> <Vx> <Vy>
obj.type_ = type_
obj.R = float(R)
obj.color = color
obj.m = float(m)
obj.y = float(y)
obj.x = float(x)
obj.Vy = float(Vy)
obj.Vx = float(Vx)

Здесь (x, y) — координаты планеты, (Vx, Vy) — скорость.
Пример строки:
Planet 10 red 1000 1 2 3 4
space_objects.append(obj)

Параметры:

**line** — строка с описание планеты.
**planet** — объект планеты.
"""
pass # FIXME: not done yet...
return obj


def write_space_objects_data_to_file(output_filename, space_objects):
Expand All @@ -77,10 +57,34 @@ def write_space_objects_data_to_file(output_filename, space_objects):
"""
with open(output_filename, 'w') as out_file:
for obj in space_objects:
print(out_file, "%s %d %s %f" % ('1', 2, '3', 4.5))
# FIXME: should store real values
out_file.write(' '.join([obj.type_, str(obj.R), obj.color, str(obj.m), str(obj.Fx), str(obj.Fy), str(obj.Vx), str(obj.Vy)]))


def read_space_objects_data_from_file(input_filename):
"""Cчитывает данные о космических объектах из файла, создаёт сами объекты
и вызывает создание их графических образов

Параметры:

**input_filename** — имя входного файла
"""

objects = []
with open(input_filename) as input_file:
for line in input_file:
if len(line.strip()) == 0 or line[0] == '#':
continue # пустые строки и строки-комментарии пропускаем
object_type = line.split(' ')[0].lower()
if object_type == 'star' or object_type == 'planet':
obj = parse_object_parameters(line)
objects.append(obj)

else:
print("Unknown space object")

return objects
# FIXME: хорошо бы ещё сделать функцию, сохранающую статистику в заданный файл...
# D: Статистику чего?

if __name__ == "__main__":
print("This module is not for direct call!")
4 changes: 2 additions & 2 deletions solar_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ def open_file_dialog():
calculate_scale_factor(max_distance)

for obj in space_objects:
if obj.type == 'star':
if obj.type_ == 'star':
create_star_image(space, obj)
elif obj.type == 'planet':
elif obj.type_ == 'planet':
create_planet_image(space, obj)
else:
raise AssertionError()
Expand Down
20 changes: 12 additions & 8 deletions solar_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ def calculate_force(body, space_objects):
for obj in space_objects:
if body == obj:
continue # тело не действует гравитационной силой на само себя!
r = ((body.x - obj.x)**2 + (body.y - obj.y)**2)**0.5
body.Fx += 1 # FIXME: нужно вывести формулу...
body.Fy += 2 # FIXME: нужно вывести формулу...

r = (((body.x - obj.x)**2) + ((body.y - obj.y)**2)) ** 0.5
F = - gravitational_constant * body.m * obj.m/r**2
cos = (-obj.x + body.x)/r
sin = (-obj.y + body.y)/r
body.Fx += F * cos
body.Fy += F * sin

def move_space_object(body, dt):
"""Перемещает тело в соответствии с действующей на него силой.
Expand All @@ -31,10 +33,12 @@ def move_space_object(body, dt):
**body** — тело, которое нужно переместить.
"""

ax = body.Fx/body.m
body.x += 42 # FIXME: не понимаю как менять...
body.Vx += ax*dt
# FIXME: not done recalculation of y coordinate!
ax = body.Fx / body.m
body.x += ax * (dt ** 2) / 2 + body.Vx * dt
body.Vx += ax * dt
ay = body.Fy / body.m
body.y += ay * (dt ** 2) / 2 + body.Vy * dt
body.Vy += ay * dt


def recalculate_space_objects_positions(space_objects, dt):
Expand Down
34 changes: 31 additions & 3 deletions solar_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Star:
а также визуальный радиус звезды в пикселах и её цвет.
"""

type = "star"
type_ = "star"
"""Признак объекта звезды"""

m = 0
Expand Down Expand Up @@ -41,14 +41,28 @@ class Star:
image = None
"""Изображение звезды"""

def __repr__(self):
return print({
'type': self.type_,
'm': self.m,
'x': self.x,
'y': self.y,
'Vx': self.Vx,
'Vy': self.Vy,
'Fx': self.Fx,
'Fy': self.Fy,
'R': self.R,
'color': self.color
})


class Planet:
"""Тип данных, описывающий планету.
Содержит массу, координаты, скорость планеты,
а также визуальный радиус планеты в пикселах и её цвет
"""

type = "planet"
type_ = "planet"
"""Признак объекта планеты"""

m = 0
Expand Down Expand Up @@ -79,4 +93,18 @@ class Planet:
"""Цвет планеты"""

image = None
"""Изображение планеты"""
"""Изображение планеты"""

def __repr__(self):
return print({
'type': self.type_,
'm': self.m,
'x': self.x,
'y': self.y,
'Vx': self.Vx,
'Vy': self.Vy,
'Fx': self.Fx,
'Fy': self.Fy,
'R': self.R,
'color': self.color
})
4 changes: 2 additions & 2 deletions solar_system.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Солнечная система
Star 2 red 1.98892E30 0 0 0 0
# Солнце
Star 25 red 1.98892E30 0 0 0 0

# Меркурий
Planet 2 orange 3.302E23 57.909E9 0 0 47.87E3
Expand Down
11 changes: 7 additions & 4 deletions solar_vis.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
header_font = "Arial-16"
"""Шрифт в заголовке"""

window_width = 800
window_width = 1200
"""Ширина окна"""

window_height = 800
window_height = 1000
"""Высота окна"""

scale_factor = None
Expand Down Expand Up @@ -54,7 +54,7 @@ def scale_y(y):
**y** — y-координата модели.
"""

return y # FIXME: not done yet
return int(y*scale_factor) + window_width//2.5


def create_star_image(space, star):
Expand All @@ -80,7 +80,10 @@ def create_planet_image(space, planet):
**space** — холст для рисования.
**planet** — объект планеты.
"""
pass # FIXME: сделать как у звезды
x = scale_x(planet.x)
y = scale_y(planet.y)
r = planet.R
planet.image = space.create_oval([x-r, y-r], [x+r, y+r], fill=planet.color)


def update_system_name(space, system_name):
Expand Down
1 change: 1 addition & 0 deletions test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
planet 5 green (5.974e+24+0j) (149600000000+0j) 0j 0j (29760+0j)
Loading