提交 b4b2d814 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 c33a202c
# -*- coding:utf-8 -*-
# title :地球季节模拟(四季和24节气)
# description :地球季节模拟(四季和24节气)
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from ursina import camera, window, Text, color, Vec3, destroy, distance
from bodies import *
from common.celestial_data_service import set_solar_system_celestial_position, conv_to_astropy_time, get_body_posvel, \
get_reality_orbit_points
from common.consts import SECONDS_PER_DAY, AU
from sim_scenes.featured.earth_seasons_base import EarthSeasonsSimBase
from sim_scenes.func import ursina_run, camera_look_at, create_sphere_sky
from sim_scenes.science.earth_season_func import create_important_pos_earths, get_solar_terms_angles, create_earth
from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.ursina.entities.body_timer import TimeData, BodyTimer
from simulators.ursina.entities.world_grid import WorldGrid
from simulators.ursina.ui.control_ui import ControlUI
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
from simulators.ursina.ursina_mesh import create_orbit_by_points
from simulators.ursina_simulator import UrsinaSimulator
import numpy as np
import math
class CenterPointMovingSimLive(EarthSeasonsSimBase):
def __init__(self):
super(CenterPointMovingSimLive, self).__init__(sun_transparent=False,
exit_at_total_days=3700,
delay_run=False,
look_at_earth=False,
earth_cn_size_factor=1.01,
earth_clouds_size_factor=1.015)
self.start_time = '2023-12-20 00:00:00'
self.sun.size_scale = 3e1
self.earth.size_scale = 2e3
self.earth_clouds.size_scale = self.earth.size_scale
self.earth_cn.size_scale = self.earth.size_scale
self.moon = Moon(name="月球", size_scale=2e3,
rotation_speed=0.645
) # 月球
self.mercury = Mercury(size_scale=2e3)
self.venus = Venus(name="金星", size_scale=2e3)
self.mars = Mars(size_scale=2e3)
self.jupiter = Jupiter(size_scale=0.2e3)
self.saturn = Saturn(size_scale=0.2e3)
self.uranus = Uranus(size_scale=2e3)
self.neptune = Neptune(size_scale=2e3)
self.bodies += [self.moon, self.mercury, self.venus, self.mars,
self.jupiter, self.saturn, self.uranus, self.neptune
]
self.last_year = None
for body in self.bodies:
if isinstance(body, Earth):
body.show_name = False
body.rotate_angle -= 22
body.rotation_speed *= 2.5
body.set_resolution(50)
self.season_earths = [self.earth_1, self.earth_2, self.earth_3, self.earth_4]
self.planets = []
# self.jieqis = {
# "春分-2023": '2023-03-21 00:00:00',
# "夏至-2023": '2023-06-21 00:00:00',
# "秋分-2023": '2023-09-23 00:00:00',
# "冬至-2023": '2023-12-22 00:00:00',
# "春分-2024": '2024-03-20 00:00:00',
# "夏至-2024": '2024-06-21 00:00:00',
# "秋分-2024": '2024-09-22 00:00:00',
# "冬至-2024": '2024-12-21 00:00:00',
# "春分-2025": '2025-03-20 00:00:00',
# "夏至-2025": '2025-06-21 00:00:00',
# "秋分-2025": '2025-09-23 00:00:00',
# "冬至-2025": '2024-12-21 00:00:00',
# }
font = "fonts/DroidSansFallback.ttf"
from common.func import find_file
self.font = find_file(f"{font}", UrsinaConfig.CN_FONT)
for body in self.bodies:
if body not in self.season_earths:
self.planets.append(body)
else:
body.texture = "transparent.png"
body.show_trail = False
self.bodies = self.planets
def create_orbit_line(self, center_body, body, start_time, alpha=0.2):
if not hasattr(body, "orbital_days"):
return None
orbital_days = int(math.ceil(body.orbital_days))
points = get_reality_orbit_points(type(body).__name__.lower(),
start_time=start_time,
days=orbital_days,
segments=100)
# print(points)
orbit_line = create_orbit_by_points(center_body.position, points, line_color=body.trail_color,
alpha=alpha,thickness=2)
return orbit_line
def create_orbit_lines(self):
"""
创建太阳系天体的真实轨迹(太阳和哈雷彗星除外)
@return:
"""
self.orbit_lines = []
for body in self.planets:
if body is self.sun:
continue
if isinstance(body, Earth):
alpha = 0.5
else:
alpha = 0.2
start_time = conv_to_astropy_time(self.start_time)
orbit_line = self.create_orbit_line(self.sun, body, start_time, alpha=1.0)
if orbit_line is not None:
self.orbit_lines.append(orbit_line)
return self.orbit_lines
def get_center_pos(self, dt, time_data):
ec = UrsinaSimulator.EditorCamera
d_sun = distance(ec.world_position, self.sun.planet.world_position)
if not hasattr(self, "moving_factor"):
self.moving_factor = 1e-6
self.phase_num = 1
# elif time_data.total_days > 1500 and self.moving_factor < 1:
elif d_sun > 4500 and self.moving_factor < 1:
self.moving_factor += 0.01
if self.phase_num == 1:
for b in self.bodies:
from simulators.ursina.entities.entity_utils import clear_trails
clear_trails(b.planet.main_entity)
UrsinaConfig.trail_type = "line"
# UrsinaConfig.trail_length = 91
self.phase_num = 2
if self.moving_factor > 1:
self.moving_factor = 1
if self.phase_num == 2:
for b in self.bodies:
from simulators.ursina.entities.entity_utils import clear_trails
clear_trails(b.planet.main_entity)
UrsinaConfig.trail_type = "curve_line"
UrsinaConfig.trail_length = 91
self.phase_num = 3
e_posvel = get_body_posvel(self.earth, dt)
s_posvel = get_body_posvel(self.sun, dt)
e_position = [e_posvel[0].x.value * AU, e_posvel[0].z.value * AU, e_posvel[0].y.value * AU]
s_position = [s_posvel[0].x.value * AU, s_posvel[0].z.value * AU, s_posvel[0].y.value * AU]
center_pos = np.array(e_position) * self.moving_factor
return center_pos
def on_ready(self):
super(CenterPointMovingSimLive, self).on_ready()
UrsinaConfig.trail_type = "line"
# UrsinaConfig.trail_length = 91
UrsinaConfig.trail_type = "curve_line"
UrsinaConfig.trail_length = 200
# UrsinaConfig.trail_length = 1000
UrsinaConfig.trail_thickness_factor = 2
UrsinaConfig.trail_factor = 2
for body in self.bodies:
body.planet.trail_scale = 2
self.moon.planet.trail_scale = 1
# WorldGrid().draw_axises(10)
camera.clip_plane_near = 1
camera.look_at(Vec3(0, 0, 0))
destroy(self.earth_clouds.planet)
destroy(self.earth_cn.planet)
self.earth.planet.name_text.enabled = False
self.moon.planet.rotation_y = 180
self.show_title()
# camera.fov = 140
window.borderless = True
window.exit_button = False
# window.fullscreen = True
# window.position = (1920, 0)
# # 设置窗口的宽度和高度
# window.size = (2340, 1079)
self.orbit_lines = self.create_orbit_lines()
def hide_orbit_lines(self):
for orbit_line in self.orbit_lines:
destroy(orbit_line)
def on_timer_changed(self, time_data: TimeData):
super(CenterPointMovingSimLive, self).on_timer_changed(time_data)
camera.rotation_z = -8
dt = time_data.get_datetime(self.start_time)
self.set_bodies_position(time_data)
self.show_clock(dt)
ec = UrsinaSimulator.EditorCamera
d_sun = distance(ec.world_position, self.sun.planet.world_position)
print("Sun distance:", d_sun)
if self.phase_num == 1:
ec.world_position += ec.up * 2 * UrsinaConfig.run_speed_factor
ec.world_position += ec.back * 1 * UrsinaConfig.run_speed_factor
elif self.phase_num == 2:
self.hide_orbit_lines()
elif self.phase_num == 3:
pass
# ec.world_position -= ec.up * 2 * UrsinaConfig.run_speed_factor
# ec.world_position -= ec.back * 1 * UrsinaConfig.run_speed_factor
# if d_sun > 4500:
# ec.target_z -= 0.01
# self.camera_around()
def camera_around(self):
ec = UrsinaSimulator.EditorCamera
ec.rotation_y -= 0.01 * UrsinaConfig.run_speed_factor # 每帧绕y轴旋转1度
# print(self.earth.planet.world_position)
# print(self.earth.planet.position)
def set_bodies_position(self, time_data: TimeData):
"""
设置天体的位置(包含速度和加速度的信息)
@param time_data:
@return:
"""
dt = conv_to_astropy_time(self.start_time)
t = dt + time_data.total_days
center_pos = self.get_center_pos(t, time_data)
set_solar_system_celestial_position(self.planets, t, True, recalc_moon_pos_scale=60, center_pos=center_pos)
def exit_handle(self):
UrsinaEvent.on_reset()
return True
def show_title(self):
aspect_ratio = window.aspect_ratio
position, origin = (-0.5 * aspect_ratio - 0.1, 0.48), (-0.05, 0.1)
position2, origin2 = (-0.5 * aspect_ratio - 0.1, 0.40), (-0.05, 0.1)
# text1 = Text(text="太阳视角:观察日食月食", color=color.white, scale=2.5, position=position, # (-0.98, 0.48),
# font=font)
ext1 = Text(text="太阳视角:2024年重要天象", color=color.white, scale=2.5, position=position, # (-0.98, 0.48),
font=self.font)
text2 = Text(text="(地球自转放慢10倍)", color=color.white, scale=1.5, position=position2, # (-0.98, 0.48),
font=self.font)
# 2024年重要天象
def show_clock(self, dt):
"""
显示时钟
@param dt: 时间 datetime
@return:
"""
# if self.clock_position_center:
# position, origin = (0, .25), (0, 0),
# else:
from ursina import window
aspect_ratio = window.aspect_ratio
position, origin = (0., 0.45), (0., 0.),
ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d'),
position=position,
origin=origin,
# font="verdana.ttf",
font="fonts/Digital-7Mono.TTF",
font_scale=2,
font_color=(0, 255, 0),
close_time=-1)
if __name__ == '__main__':
"""
摄像机以太阳的视角看地球(四季和24节气)
"""
sim = CenterPointMovingSimLive()
sim.run(
dt=SECONDS_PER_DAY * 20,
# dt=SECONDS_PER_DAY * 3,
init_position=[0, -60 * AU, 30 * AU],
show_exit_button=False,
show_camera_info=False,
gravity_works=False,
show_trail=True,
show_control_info=False)
......@@ -83,23 +83,25 @@ class EarthSeasonsSimBase(UniverseSimScenes):
def on_ready(self):
# 将 4 个节气位置的地球进行旋转,让中国面对太阳
self.earth_1.planet.rotation_y += 115 # 春分
self.earth_2.planet.rotation_y += 15 # 夏至
self.earth_3.planet.rotation_y -= 80 # 秋分
self.earth_4.planet.rotation_y -= 145 # 冬至
if hasattr(self.earth_1, "planet"):
self.earth_1.planet.rotation_y += 115 # 春分
self.earth_1.planet.alpha = 0.2
if hasattr(self.earth_2, "planet"):
self.earth_2.planet.rotation_y += 15 # 夏至
self.earth_2.planet.alpha = 0.2
if hasattr(self.earth_3, "planet"):
self.earth_3.planet.rotation_y -= 80 # 秋分
self.earth_3.planet.alpha = 0.2
if hasattr(self.earth_4, "planet"):
self.earth_4.planet.rotation_y -= 145 # 冬至
self.earth_4.planet.alpha = 0.2
self.earth.planet.rotation_y -= 185 # 一开始就正对太阳
self.earth_cn.planet.rotation_y -= 185 # 一开始就正对太阳
self.earth_clouds.planet.rotation_y -= 50 # 一开始就正对太阳
self.earth_1.planet.alpha = 0.2
self.earth_2.planet.alpha = 0.2
self.earth_3.planet.alpha = 0.2
self.earth_4.planet.alpha = 0.2
if self.show_sphere_sky:
self.sky = create_sphere_sky(scale=8000)
self.sky = create_sphere_sky(scale=800000)
self.sky.rotation_y = 100
self.sky.rotation_x = 20
self.sky.rotation_z = -65
......@@ -110,17 +112,21 @@ class EarthSeasonsSimBase(UniverseSimScenes):
text_scale = self.earth.name_text.scale * 2
self.earth.name_text.scale = text_scale
self.earth_1.name_text.scale = text_scale
self.earth_2.name_text.scale = text_scale
self.earth_3.name_text.scale = text_scale
self.earth_4.name_text.scale = text_scale
if hasattr(self.earth_1, "name_text"):
self.earth_1.name_text.scale = text_scale
self.earth_1.name_text.font = font
if hasattr(self.earth_2, "name_text"):
self.earth_2.name_text.scale = text_scale
self.earth_2.name_text.font = font
if hasattr(self.earth_3, "name_text"):
self.earth_3.name_text.scale = text_scale
self.earth_3.name_text.font = font
if hasattr(self.earth_4, "name_text"):
self.earth_4.name_text.scale = text_scale
self.earth_4.name_text.font = font
self.earth.name_text.font = font
self.earth.name_text.color = color.yellow
self.earth_1.name_text.font = font
self.earth_2.name_text.font = font
self.earth_3.name_text.font = font
self.earth_4.name_text.font = font
if hasattr(self.earth_clouds, "name_text"):
self.earth_clouds.name_text.enabled = False
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册