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

Python超人-宇宙模拟器

上级 4d74c8da
import sys
import json
import gc
import os
default_encoding = 'utf-8'
if sys.getdefaultencoding() != default_encoding:
reload(sys)
class JieQi:
# 计算节气的C常量组
C_list_21 = [3.87, 18.73, 5.63, 20.646, 4.81, 20.1, 5.52, 21.04, 5.678, 21.37, 7.108, 22.83, 7.5, 23.13, 7.646,
23.042, 8.318, 23.438, 7.438, 22.36, 7.18, 21.94, 5.4055, 20.12]
C_list_20 = [4.6295, 19.4599, 6.3826, 21.4155, 5.59, 20.888, 6.318, 21.86, 6.5, 22.2, 7.928, 23.65, 8.35, 23.95,
8.44, 23.822, 9.098, 24.218, 8.218, 23.08, 7.9, 22.6, 6.11, 20.84]
# 节气名称组
name_Array = ["立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露",
"霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒"]
def __init__(self, name_arr=None):
self.c_list = []
if name_arr is not None:
self.name_arr = name_arr
else:
self.name_arr = JieQi.name_Array
## 特殊年份特殊节气进行纠正
def rectify_year(self, year, jieqiid, day):
## 特殊年份
rectify_year = [2026, 2084, 1911, 2008, 1902, 1928, 1925, 2016, 1922, 2002, 1927, 1942, 2089, 2089, 1978, 1954,
1918, 2021, 1982, 2082, 2019, 2021]
## 特殊节气
rectify_jieqi = [1, 3, 6, 7, 8, 9, 10, 10, 11, 12, 14, 15, 17, 18, 19, 20, 21, 21, 22, 22, 23]
## 偏移量
rectify_offset = [-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1]
pop2 = -1
if year in rectify_year:
if year == 2089:
pop1 = rectify_year.index(year) ## 找到位置
pop2 = pop1 + 1
else:
pop1 = rectify_year.index(year) ## 找到位置
if rectify_jieqi[pop1] == jieqiid:
day = day + int(rectify_offset[pop1])
if rectify_jieqi[pop2] == jieqiid:
day = day + int(rectify_offset[pop2])
return day
# 计算节气日期,并创建文件
def get_year_jieqi(self, year):
year_pre = year // 100
if year_pre == 19:
C_arr = self.C_list_20
elif year_pre == 20:
C_arr = self.C_list_21
year_num = year % 100
list_arr = []
for i in range(0, 24):
C = C_arr[i]
## 注意:凡闰年3月1日前闰年数要减一,即:L=[(Y-1)/4],因为小寒、大寒、立春、雨水这两个节气都小于3月1日,所以 y = y-1
if i == 0 or i == 1 or i == 22 or i == 23:
if self.comrun(year):
days = (year_num * 0.2422 + C) // 1 - ((year_num - 1) // 4)
else:
days = (year_num * 0.2422 + C) // 1 - (year_num // 4)
else:
days = (year_num * 0.2422 + C) // 1 - (year_num // 4)
## 特殊年份节气进行纠正
days = self.rectify_year(year, i, days)
days = int(days)
days = '%02d' % days
y = int(year_num // 1)
m = i // 2 + 2
if m == 13:
m = 1
m = '%02d' % m
y = '%02d' % y
strs = "{3}{0}-{1}-{2} 00:00:00".format(str(y), str(m), str(days), str(year_pre))
item = dict(name=self.name_Array[i], jieqiid=str(i + 1), time=strs)
# print (item)
list_arr.append(item)
return list_arr
# list_str = json.dumps(list_arr,ensure_ascii=False) ## 中文不进行编码
# file_name = "./json/{0}.json".format(str(year))
# with open(file_name, "w",encoding="utf-8") as f: ## 打开时用 utf-8 编码
# json.dump(list_str, f,ensure_ascii=False)
# print("{0}已载入文件完成...".format(str(year)))
# 读取年份为 name 年的节气数据
def read_json_file(self, name):
json_file = open('./json/' + name + '.json', 'r', encoding="utf-8")
json_str = json_file.read()
dic = json.loads(json_str)
print(dic)
# 读取测试
# read_json_file('2029')
# 读取所有年份的节气数据
def check_all_file(self):
for index in range(1900, 2100):
c_file_name = './json/{0}.json'.format(str(index))
if os.path.isfile(c_file_name):
json_file = open(c_file_name, 'r', encoding="utf-8")
json_str = json_file.read()
dic = json.loads(json_str)
print(str(index) + dic)
## 算是否是闰年
def comrun(self, year):
i = 0
if (year % 4) != 0:
i = 0
elif ((year % 100) == 0) & ((year % 400) != 0):
i = 0
else:
i = 1
return i
def get_years_jieqi(self, y1, y2):
# "春分-2023": '2023-03-21 00:00:00',
jieqis = {}
for y in range(y1, y2 + 1):
d = self.get_year_jieqi(y)
d = [(i["name"], i["time"]) for i in d]
for di in d:
if di[0] in self.name_arr:
jieqis[f"{di[0]}-{y}"] = di[1]
return jieqis
if __name__ == '__main__':
names = ["立春", "雨水", "惊蛰", "春分",
"清明", "谷雨", "立夏", "小满",
"芒种", "夏至", "小暑", "大暑",
"立秋", "处暑", "白露", "秋分",
"寒露", "霜降", "立冬", "小雪",
"大雪", "冬至", "小寒", "大寒"]
names = ["立春", "春分",
"立夏", "夏至",
"立秋", "秋分",
"立冬", "冬至"]
jieqi = JieQi(names)
d = jieqi.get_years_jieqi(2024, 2024)
print(d)
# jieqi.read_json_file('2006')
# jieqi.check_all_file()
#
# for i in range(1900,2100):
# jieqi.creat_year_jieqi(i)
# -*- 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
from bodies import *
from common.celestial_data_service import set_solar_system_celestial_position, conv_to_astropy_time, get_body_posvel
from common.consts import *
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, \
create_important_pos_earths_2
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
from simulators.ursina_simulator import UrsinaSimulator
import numpy as np
import math
class EarthSeasonsSimLive(EarthSeasonsSimBase):
def __init__(self):
super(EarthSeasonsSimLive, self).__init__(sun_transparent=False,
exit_at_total_days=3700,
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.start_time = '2024-04-08 00:00:00'
self.sun.size_scale = 5e1
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.6e3)
self.saturn = Saturn(size_scale=0.6e3)
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.earth_5, self.earth_6, self.earth_7, self.earth_8]
self.last_year = None
for body in self.bodies:
if isinstance(body, Earth):
body.show_name = True
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.earth_5, self.earth_6, self.earth_7, self.earth_8]
self.planets = []
names = ["立春", "春分",
"立夏", "夏至",
"立秋", "秋分",
"立冬", "冬至"]
from common.china_24_jieqi import JieQi
jieqi = JieQi(names)
self.jieqis = jieqi.get_years_jieqi(2023, 2025)
font = "fonts/DroidSansFallback.ttf"
# font = "fonts/新青年体.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.size_scale = self.earth.size_scale / 1.1
body.show_trail = False
def create_important_pos_earths(self):
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_5, self.earth_6, self.earth_7, self.earth_8 = create_important_pos_earths_2(texture="earth-huge.jpg",
size_scale=4.9e3,
position_offset=1.0)
return self.earth_1, self.earth_2, self.earth_3, self.earth_4
def earth_text_display(self, term_name):
for e in [self.earth_1, self.earth_2, self.earth_3, self.earth_4,
self.earth_5, self.earth_6, self.earth_7, self.earth_8]:
# if hasattr(e, "name_text"):
# if term_name == e.name:
# e.name_text.enabled = False
# else:
e.name_text.enabled = True
def get_center_pos(self, dt):
posvel = get_body_posvel(self.earth, dt)
position = [posvel[0].x.value * AU, posvel[0].z.value * AU, posvel[0].y.value * AU]
center_pos = np.array(position)
return center_pos
def on_ready(self):
super(EarthSeasonsSimLive, self).on_ready()
for e in self.season_earths:
if hasattr(e, "planet"):
# e.planet.rotation_y += 15 # 夏至
e.planet.alpha = 0.2
# 将 4 个节气位置的地球进行旋转,让中国面对太阳
# 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
UrsinaConfig.trail_type = "line"
# UrsinaConfig.trail_length = 91
UrsinaConfig.trail_type = "curve_line"
UrsinaConfig.trail_length = 50
# UrsinaConfig.trail_length = 1000
UrsinaConfig.trail_thickness_factor = 2
for body in self.planets:
body.planet.trail_scale = 3
body.planet.name_text.scale = 5
destroy(body.planet.name_text.background)
body.planet.name_text.color = color.white
body.planet.name_text.font = self.font
body.planet.name_text.position = Vec3(0, 0.6, 0)
# body.planet.name_text.position = Vec3(0, pow(body.planet.main_entity.scale_y, 1 / 12) / 2, 0)
# body.planet.name_text
def camera_distance_update(name_text):
o_scale = name_text.scale_x
def update2():
print(name_text.parent.body)
return update2
# body.planet.name_text.update = camera_distance_update(body.planet.name_text)
self.moon.planet.trail_scale = 1
# camera.orthographic = True
camera.clip_plane_near = 1
# camera.clip_plane_far = sky.scale_x * 1.5
destroy(self.earth_clouds.planet)
destroy(self.earth_cn.planet)
# self.earth_cn.size_scale = self.earth.size_scale
for e in self.season_earths:
# camera_look_at(self.sun, rotation_z=0)
# e.planet.scale = 0.1
# e.planet.alpha = 0.2
if not hasattr(e, "name_text"):
continue
e.name_text.scale = Vec3(10, 10, 10)
e.name_text.font = self.font
destroy(e.name_text.background)
# self.earth_2.planet.alpha = 0.2
# self.earth_3.planet.alpha = 0.2
# self.earth_4.planet.alpha = 0.2
self.earth.planet.name_text.enabled = False
# , self.earth_clouds, self.earth_cn
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()
# camera.fov = 140
window.borderless = True
window.exit_button = False
# window.fullscreen = True
# window.position = (1920, 0)
# # 设置窗口的宽度和高度
# window.size = (2340, 1079)
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)
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)
set_solar_system_celestial_position(self.planets, t, True, recalc_moon_pos_scale=60, center_pos=center_pos)
year = int(t.jyear)
if self.last_year != year:
for body in self.season_earths:
jieqir = self.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, center_pos=None)
body.abs_position = body.position
self.last_year = year
for body in self.season_earths:
body.position = body.abs_position + self.sun.position
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 = EarthSeasonsSimLive()
sim.run(
# dt=SECONDS_PER_DAY * 10,
dt=SECONDS_PER_DAY * 3,
# dt=SECONDS_PER_HOUR,
init_position=[0, 0, -3 * AU],
show_exit_button=False,
show_camera_info=False,
gravity_works=False,
show_control_info=False)
......@@ -41,7 +41,32 @@ def create_important_pos_earths(texture="earth_transparent.png", size_scale=5e3,
texture=texture, size_scale=size_scale)
earth_3 = create_trans_earth(name="秋分", text_color=(255, 255, 0), position=[position_offset * AU, 0, 0],
texture=texture, size_scale=size_scale)
earth_4 = create_trans_earth(name="冬至", text_color=(0, 255, 255), position=[0, 0, position_offset * AU],
earth_4 = create_trans_earth(name="冬至", text_color=(255, 255, 255), position=[0, 0, position_offset * AU],
texture=texture, size_scale=size_scale)
earth_1.set_light_disable(True)
earth_2.set_light_disable(True)
earth_3.set_light_disable(True)
earth_4.set_light_disable(True)
return earth_1, earth_2, earth_3, earth_4
def create_important_pos_earths_2(texture="earth_transparent.png", size_scale=5e3, position_offset=1.05):
"""
创建24节气中4个重要位置的透明地球
@param texture: 透明地球的纹理图片
@param size_scale:
@param position_offset:
@return:
"""
earth_1 = create_trans_earth(name="立春", text_color=(0, 255, 0), position=[-position_offset * AU, 0, 0],
texture=texture, size_scale=size_scale)
earth_2 = create_trans_earth(name="立夏", text_color=(255, 0, 0), position=[0, 0, -position_offset * AU],
texture=texture, size_scale=size_scale)
earth_3 = create_trans_earth(name="立秋", text_color=(255, 255, 0), position=[position_offset * AU, 0, 0],
texture=texture, size_scale=size_scale)
earth_4 = create_trans_earth(name="立冬", text_color=(255, 255, 255), position=[0, 0, position_offset * AU],
texture=texture, size_scale=size_scale)
earth_1.set_light_disable(True)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册