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

Python超人-宇宙模拟器

上级 309f55b8
......@@ -28,7 +28,8 @@ class EarthSeasonsSimBase(UniverseSimScenes):
exit_at_total_days=375,
earth_cn_size_factor=1.001,
earth_clouds_size_factor=1.01,
show_name=True):
show_name=True,
delay_run=True):
if sun_transparent:
self.sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机
else:
......@@ -37,18 +38,12 @@ class EarthSeasonsSimBase(UniverseSimScenes):
self.look_at_earth = look_at_earth
self.show_china = show_china
self.show_name = show_name
self.delay_run = delay_run
self.exit_at_total_days = exit_at_total_days
# 在 4 个节气的位置创建固定不动的透明地球
self.earth_1, self.earth_2, self.earth_3, self.earth_4 = create_important_pos_earths(texture="earth-huge.jpg",
size_scale=4.9e3,
position_offset=1.0)
self.earth_1, self.earth_2, self.earth_3, self.earth_4 = self.create_important_pos_earths()
# 运动的地球
self.earth, self.earth_clouds, self.earth_cn = create_earth(earth_texture="earth-huge.jpg",
earth_cn_texture="earth-huge-cn.png",
with_clouds=True, earth_rotation_speed=0.7,
clouds_rotation_speed=0.78,
earth_cn_size_factor=earth_cn_size_factor,
earth_clouds_size_factor=earth_clouds_size_factor)
self.earth, self.earth_clouds, self.earth_cn = self.create_earth(earth_cn_size_factor, earth_clouds_size_factor)
# 地球立春的位置和速度
self.earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08]
......@@ -73,6 +68,19 @@ class EarthSeasonsSimBase(UniverseSimScenes):
# 中国农历24节气表,数据为 节气名称 和 camera.rotation_y 的角度范围值
self.solar_terms_angles = get_solar_terms_angles()
def create_important_pos_earths(self):
return create_important_pos_earths(texture="earth-huge.jpg",
size_scale=4.9e3,
position_offset=1.0)
def create_earth(self, earth_cn_size_factor, earth_clouds_size_factor):
return create_earth(earth_texture="earth-huge.jpg",
earth_cn_texture="earth-huge-cn.png",
with_clouds=True, earth_rotation_speed=0.7,
clouds_rotation_speed=0.78,
earth_cn_size_factor=earth_cn_size_factor,
earth_clouds_size_factor=earth_clouds_size_factor)
def on_ready(self):
# 将 4 个节气位置的地球进行旋转,让中国面对太阳
self.earth_1.planet.rotation_y += 115 # 春分
......@@ -156,9 +164,10 @@ class EarthSeasonsSimBase(UniverseSimScenes):
self.wait_days_count = 0
application.paused = False
import threading
application.paused = True
threading.Thread(target=delay_app_start).start()
if self.delay_run:
import threading
application.paused = True
threading.Thread(target=delay_app_start).start()
# invoke(lambda: app_start, delay=3.0)
def earth_text_display(self, term_name):
......@@ -174,13 +183,18 @@ class EarthSeasonsSimBase(UniverseSimScenes):
else:
e.name_text.enabled = True
def exit_handle(self):
exit(0)
def on_timer_changed(self, time_data: TimeData):
if self.show_china and self.wait_days_count > 0:
self.wait_days_count = self.wait_days - time_data.total_days
if time_data.total_days > self.exit_at_total_days:
exit(0)
if self.exit_handle():
return
if self.look_at_earth:
# 摄像机始终看向移动的地球
camera_look_at(self.earth, rotation_z=0)
......@@ -199,7 +213,7 @@ class EarthSeasonsSimBase(UniverseSimScenes):
# print(camera.rotation_y)
def run(self, init_position=(0, 0, 0), speed_factor=1.0):
def run(self, dt=None, init_position=(0, 0, 0), speed_factor=1.0, **kwargs):
self.speed_factor = speed_factor
# 订阅事件后,上面2个函数功能才会起作用
# 运行前会触发 on_ready
......@@ -208,13 +222,15 @@ class EarthSeasonsSimBase(UniverseSimScenes):
UrsinaEvent.on_timer_changed_subscription(self.on_timer_changed)
# 设置计时器的最小时间单位为天
BodyTimer().min_unit = BodyTimer.MIN_UNIT_DAYS
if dt is None:
dt = SECONDS_PER_DAY * speed_factor
# 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后-
ursina_run(self.bodies, SECONDS_PER_DAY * speed_factor,
ursina_run(self.bodies, dt,
position=init_position, # 摄像机和太阳是相同位置
show_name=self.show_name,
show_grid=False,
cosmic_bg='',
# show_timer=True,
timer_enabled=True)
timer_enabled=True, **kwargs)
# -*- 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
from bodies import Sun, Earth, Moon
from common.celestial_data_service import set_solar_system_celestial_position, conv_to_astropy_time
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.ui.control_ui import ControlUI
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
class EarthSeasonsSimLive(EarthSeasonsSimBase):
def __init__(self):
super(EarthSeasonsSimLive, self).__init__(exit_at_total_days=370,
delay_run=False,
earth_cn_size_factor=1.01,
earth_clouds_size_factor=1.015)
self.start_time = '2023-12-20 00:00:00'
self.moon = Moon(name="月球", size_scale=5e3,
rotation_speed=0.645
) # 月球
self.bodies.append(self.moon)
for body in self.bodies:
if isinstance(body, Earth):
body.rotate_angle -= 22
body.set_resolution(50)
def on_ready(self):
super(EarthSeasonsSimLive, self).on_ready()
# camera_look_at(self.sun, rotation_z=0)
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
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 # 冬至
self.moon.planet.rotation_y = 180
self.show_title()
def on_timer_changed(self, time_data: TimeData):
super(EarthSeasonsSimLive, 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)
def set_bodies_position(self, time_data: TimeData):
"""
设置天体的位置(包含速度和加速度的信息)
@param time_data:
@return:
"""
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',
}
dt = conv_to_astropy_time(self.start_time)
bodies = []
year = int(dt.jyear)
for body in self.bodies:
jieqir = jieqis.get(f"{body.name}-{year}", None)
if jieqir is not None:
jieqir = conv_to_astropy_time(jieqir)
set_solar_system_celestial_position([body], jieqir, False)
else:
bodies.append(body)
t = dt + time_data.total_days
set_solar_system_celestial_position(bodies, t, True, recalc_moon_pos_scale=200)
def exit_handle(self):
UrsinaEvent.on_reset()
return True
def show_title(self):
font = "fonts/DroidSansFallback.ttf"
from common.func import find_file
font = find_file(f"{font}", UrsinaConfig.CN_FONT)
aspect_ratio = window.aspect_ratio
position, origin = (-0.5 * aspect_ratio + 0.05, 0.48), (-0.05, 0.1),
text = Text(text="太阳视角:观察日食月食", color=color.white, scale=2, position=position, # (-0.98, 0.48),
font=font)
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 = EarthSeasonsSimLive()
sim.run(
# dt=SECONDS_PER_DAY * 10,
dt=SECONDS_PER_DAY * 3,
show_exit_button=False,
show_camera_info=False,
gravity_works=False,
show_control_info=False)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册