Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Воган Ли - Python для хакеров (Библиотека программиста) - 2023.pdf
Скачиваний:
4
Добавлен:
07.04.2024
Размер:
14.76 Mб
Скачать

366      Решения для практических проектов

Останови меня!

practice_grav_assist_intersecting.py

"""gravity_assist_intersecting.py

Орбиты Луны и корабля переcекаются, в результате чего Луна замедляется и разворачивает корабль.

Реализация: Эрик Т. Мортенсон

"""

from turtle import Shape, Screen, Turtle, Vec2D as Vec import turtle

import math import sys

# Пользовательский ввод:

G = 8 # Гравитационная константа, используемая в симуляции. NUM_LOOPS = 7000 # Число временных шагов в симуляции.

Ro_X = -152.18 # Координата x стартовой позиции корабля. Ro_Y = 329.87 # Координата y стартовой позиции корабля.

Vo_X = 423.10 # Компонент x скорости выхода на транслунную орбиту. Vo_Y = -512.26 # Компонент y скорости выхода на транслунную орбиту.

MOON_MASS = 1_250_000

class GravSys():

"""Выполняем гравитационную симуляцию для n тел."""

def __init__(self): self.bodies = [] self.t = 0 self.dt = 0.001

def sim_loop(self):

"""Прогоняем тела из списка по временным шагам."""

for index in range(NUM_LOOPS): # остановка моделирования через некоторое время

self.t += self.dt

for body in self.bodies: body.step()

class Body(Turtle):

"""Небесный объект, вращающийся по орбите и проецирующий гравитационное поле."""

def __init__(self, mass, start_loc, vel, gravsys, shape): super().__init__(shape=shape)

self.gravsys = gravsys self.penup() self.mass=mass self.setpos(start_loc) self.vel = vel gravsys.bodies.append(self)

self.pendown() # Раскомментируйте, чтобы рисовать позади указателя его путь.

Глава 6. Победа в лунной гонке с помощью «Аполлона-8»      367

def acc(self):

"""Вычисляем комбинированную силу, действующую на тело, и возвращаем компоненты вектора."""

a = Vec(0,0)

for body in self.gravsys.bodies: if body != self:

r = body.pos() - self.pos()

a += (G * body.mass / abs(r)**3) * r # единицы расстояние/

время^2

return a

def step(self):

"""Вычисляем позицию, ориентацию и скорость тела.""" dt = self.gravsys.dt

a = self.acc()

self.vel = self.vel + dt * a

xOld, yOld = self.pos() # для ориентации корабля self.setpos(self.pos() + dt * self.vel)

xNew, yNew = self.pos() # для ориентации корабля if self.gravsys.bodies.index(self) == 1: # CSM

dir_radians = math.atan2(yNew-yOld,xNew-xOld) # для ориентации корабля

dir_degrees = dir_radians * 180 / math.pi # для ориентации корабля

self.setheading(dir_degrees+90) # для ориентации корабля

def main():

#Настройка экрана screen = Screen()

screen.setup(width=1.0, height=1.0) # для полноэкранного режима screen.bgcolor('black')

screen.title("Gravity Assist Example")

#Инстанцируем гравитационную систему

gravsys = GravSys()

# Инстанцируем планету image_moon = 'moon_27x27.gif' screen.register_shape(image_moon)

moon = Body(MOON_MASS, (-250, 0), Vec(500, 0), gravsys, image_moon) moon.pencolor('gray')

#Создаем фигуру командно-сервисного модуля (csm) csm = Shape('compound')

cm = ((0, 30), (0, -30), (30, 0)) csm.addcomponent(cm, 'red', 'red')

sm = ((-60,30), (0, 30), (0, -30), (-60, -30)) csm.addcomponent(sm, 'red', 'black')

nozzle = ((-55, 0), (-90, 20), (-90, -20)) csm.addcomponent(nozzle, 'red', 'red') screen.register_shape('csm', csm)

#Инстанцируем указатель CSM "Аполлона-8"

ship = Body(1, (Ro_X, Ro_Y), Vec(Vo_X, Vo_Y), gravsys, "csm")