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

Python超人-宇宙模拟器

上级 f3aa535f
# -*- coding:utf-8 -*-
# title :从地球上看天空
# description :从地球上看天空
# author :Python超人
# date :2023-12-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from ursina import camera
from bodies import Sun, Earth
from common.consts import SECONDS_PER_DAY, SECONDS_PER_HOUR, AU
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, \
get_earth_pos_vel_by_term_name
from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.ursina.entities.body_timer import TimeData, BodyTimer
from simulators.ursina.entities.entity_utils import create_foreground
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
from common.func import find_file
class LookAtSkyOnEarth(UniverseSimScenes):
def __init__(self,
show_sphere_sky=True,
# look_at_earth=True,
show_china=False,
exit_at_total_days=375,
earth_cn_size_factor=1.001,
earth_clouds_size_factor=1.01,
show_name=False, look_point=None):
# self.sun = Sun(size_scale=2e1, texture="sun_light.jpg")
# self.sun.glows = (0, 1.005, 0.1)
self.sun = Sun(size_scale=2e1, texture="transparent.png")
self.sun.glows = None
self.show_sphere_sky = show_sphere_sky
self.look_point = look_point # -1:北半球, 1:南半球, 0:赤道
# self.look_at_earth = look_at_earth
self.show_china = show_china
self.show_name = show_name
self.exit_at_total_days = exit_at_total_days
earth_transparent = look_point is not None
self.earth_transparent = earth_transparent
if earth_transparent:
earth_texture = "transparent.png"
# earth_texture = "earth_miller_projection_SW.jpg"
clouds_texture = "transparent.png"
earth_size_scale = 1
else:
earth_texture = "earth-huge.jpg"
clouds_texture = "transparent_clouds.png"
earth_size_scale = 5e3
# 运动的地球
self.earth, self.earth_clouds, self.earth_cn = create_earth(earth_texture=earth_texture,
earth_size_scale=earth_size_scale,
earth_cn_texture=None,
clouds_texture=clouds_texture,
with_clouds=True, earth_rotation_speed=16,
clouds_rotation_speed=17,
earth_cn_size_factor=earth_cn_size_factor,
earth_clouds_size_factor=earth_clouds_size_factor)
# # 地球立春的位置和速度
# self.earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08]
# self.earth.init_velocity = [-23.550875, 0., -18.05398]
self.earth_clouds.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08]
self.earth_clouds.init_velocity = [-23.550875, 0., -18.05398]
self.earth.rotate_axis_color = (255, 255, 50)
self.earth.rotate_axis_scale = 0.65
pos_vel = get_earth_pos_vel_by_term_name("春分")
if pos_vel is not None:
self.earth.init_position = pos_vel["pos"]
self.earth.init_velocity = pos_vel["vel"]
self.bodies = [
self.sun, self.earth, self.earth_clouds
]
if self.show_china:
self.bodies += [self.earth_cn]
self.wait_days = 10
self.wait_days_count = self.wait_days
# 中国农历24节气表,数据为 节气名称 和 camera.rotation_y 的角度范围值
self.solar_terms_angles = get_solar_terms_angles()
def on_ready(self):
self.earth.planet.rotation_y -= 180 # 一开始就正对太阳
# self.earth_cn.planet.rotation_y -= 185 # 一开始就正对太阳
self.earth_clouds.planet.rotation_y -= 50 # 一开始就正对太阳
if self.show_name:
font = find_file("fonts/DroidSansFallback.ttf", UrsinaConfig.CN_FONT)
from ursina import color
text_scale = self.earth.name_text.scale * 2
self.earth.name_text.scale = text_scale
self.earth.name_text.font = font
self.earth.name_text.color = color.yellow
if hasattr(self.earth_clouds, "name_text"):
self.earth_clouds.name_text.enabled = False
if self.show_china:
if hasattr(self.earth_cn, "name_text"):
self.earth_cn.name_text.enabled = False
cn_planet = self.earth_cn.planet
origin_update = cn_planet.update
cn_planet.alpha_inc = 0.01
cn_planet.alpha_direct = -1
alpha_range = [0.3, 0.7]
cn_planet.alpha = alpha_range[1]
def cn_blink():
origin_update()
alpha = cn_planet.alpha
alpha += cn_planet.alpha_direct * cn_planet.alpha_inc
if cn_planet.alpha_direct < 0 and alpha < alpha_range[0]:
alpha = alpha_range[0]
cn_planet.alpha_direct = 1
elif cn_planet.alpha_direct > 0 and alpha > alpha_range[1]:
alpha = alpha_range[1]
cn_planet.alpha_direct = -1
cn_planet.alpha = alpha
# print(cn_planet.alpha)
if self.wait_days_count <= 0:
self.earth_cn.planet.alpha = alpha_range[1]
cn_planet.update = origin_update
cn_planet.update = cn_blink
from ursina import application, invoke
if self.show_sphere_sky:
self.sky = create_sphere_sky(scale=8000, texture="eso0932a.jpg")
# self.sky.rotation_x = -50
# self.sky.rotation_z = 90
self.sky.rotation_x = 50
self.sky.rotation_z = 50
# if self.look_point == 1:
if self.look_point is not None:
camera.rotation_x = 50 * self.look_point
# camera.rotation_x = 50 # 1 南半球
# if self.look_at_earth:
if self.look_point is None:
# 摄像机始终看向移动的地球
camera_look_at(self.earth, rotation_z=0)
# camera.parent = self.sun.planet
else:
camera.parent = self.earth.planet
camera.rotation_z = 90
camera.clip_plane_near = 10
camera.clip_plane_far = 1000000
camera.fov = 75 # 默认:60
def delay_app_start():
import time
# time.sleep(8.0 / self.speed_factor)
self.wait_days_count = 0
application.paused = False
import threading
application.paused = True
threading.Thread(target=delay_app_start).start()
# invoke(lambda: app_start, delay=3.0)
if self.look_point is not None:
# self.sun.planet.glow_circle.look_at(camera)
create_foreground(f"armazonesdusk_{self.look_point + 2}.png")
def on_timer_changed(self, time_data: TimeData):
pass
# 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.look_at_earth:
# # 摄像机始终看向移动的地球
# camera_look_at(self.earth, rotation_z=0)
# # 根据角度范围判断,显示中国农历24节气
# for info in self.solar_terms_angles:
# if info[1] <= camera.rotation_y < info[2]:
# term_name = info[0]
# # 控制4个透明地球文本是否显示,防止地球文字的叠加
# self.earth_text_display(term_name)
# # 地球名称文字显示为相应的节气
# if hasattr(self.earth, "name_text"):
# self.earth.name_text.text = term_name
# # if term_name == "立春": # 找到立春的位置和速度
# # print("position", earth.position)
# # print("velocity", earth.velocity)
#
# # print(camera.rotation_y)
def run(self, init_position=(0, 0, 0), speed_factor=1.0):
self.speed_factor = speed_factor
# 订阅事件后,上面2个函数功能才会起作用
# 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(self.on_ready)
# 运行中,每时每刻都会触发 on_timer_changed
UrsinaEvent.on_timer_changed_subscription(self.on_timer_changed)
# 设置计时器的最小时间单位为天
BodyTimer().min_unit = BodyTimer.MIN_UNIT_DAYS
# 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后-
ursina_run(self.bodies, SECONDS_PER_HOUR * speed_factor,
position=init_position, # 摄像机和太阳是相同位置
show_name=self.show_name,
show_grid=False,
cosmic_bg='',
# show_timer=True,
timer_enabled=True)
if __name__ == '__main__':
"""
摄像机以太阳的视角看地球(四季和24节气)
"""
# -1:北半球 Northern Hemisphere, 1:南半球 Southern Hemisphere, 0:赤道 Equator
sim = LookAtSkyOnEarth()
sim.run()
# -*- coding:utf-8 -*-
# title :从地球上看天空
# description :从地球上看天空
# author :Python超人
# date :2023-12-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from sim_scenes.featured.look_at_sky_on_earth import LookAtSkyOnEarth
if __name__ == '__main__':
"""
从地球赤道看天空
"""
# -1:北半球 Northern Hemisphere, 1:南半球 Southern Hemisphere, 0:赤道 Equator
sim = LookAtSkyOnEarth(look_point=0)
sim.run()
# -*- coding:utf-8 -*-
# title :从地球上看天空
# description :从地球上看天空
# author :Python超人
# date :2023-12-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from sim_scenes.featured.look_at_sky_on_earth import LookAtSkyOnEarth
if __name__ == '__main__':
"""
从地球北半球看天空
"""
# -1:北半球 Northern Hemisphere, 1:南半球 Southern Hemisphere, 0:赤道 Equator
sim = LookAtSkyOnEarth(look_point=-1)
sim.run()
# -*- coding:utf-8 -*-
# title :从地球上看天空
# description :从地球上看天空
# author :Python超人
# date :2023-12-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from sim_scenes.featured.look_at_sky_on_earth import LookAtSkyOnEarth
if __name__ == '__main__':
"""
从地球南半球看天空
"""
# -1:北半球 Northern Hemisphere, 1:南半球 Southern Hemisphere, 0:赤道 Equator
sim = LookAtSkyOnEarth(look_point=1)
sim.run()
......@@ -56,7 +56,8 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
earth_cn_texture=None,
clouds_texture="transparent_clouds.png",
earth_rotation_speed=0.5, clouds_rotation_speed=0.5,
earth_cn_size_factor=1.001, earth_clouds_size_factor=1.01):
earth_cn_size_factor=1.001, earth_clouds_size_factor=1.01,
earth_size_scale=5e3):
"""
创建运动的地球(和云层)
@param earth_texture: 地球的纹理图片
......@@ -67,7 +68,7 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
@return:
"""
# 运动的地球
earth = Earth(size_scale=5e3, texture=earth_texture,
earth = Earth(size_scale=earth_size_scale, texture=earth_texture,
text_color=[255, 255, 255], rotation_speed=earth_rotation_speed,
init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79])
......@@ -76,7 +77,7 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
else:
earth_cn = Earth(name="", texture=earth_cn_texture,
rotation_speed=earth_rotation_speed, show_name=False,
size_scale=earth_cn_size_factor * 5e3, parent=earth)
size_scale=earth_cn_size_factor * earth_size_scale, parent=earth)
if not with_clouds:
return earth, None, earth_cn
......@@ -84,7 +85,7 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
# 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点)
earth_clouds = Earth(name="", texture=clouds_texture,
rotation_speed=clouds_rotation_speed, show_name=False,
size_scale=earth_clouds_size_factor * 5e3, parent=earth)
size_scale=earth_clouds_size_factor * earth_size_scale, parent=earth)
return earth, earth_clouds, earth_cn
......
......@@ -31,7 +31,7 @@ class UniverseSimScenes:
UniverseSimScenes.screen_record = True
application.time_scale = 0.00001
instance = super().__new__(cls, *args, **kwargs)
instance = super().__new__(cls)
return instance
@staticmethod
......
......@@ -23,6 +23,7 @@ import math
import numpy as np
def create_name_text(parent):
"""
......@@ -383,7 +384,9 @@ def create_fixed_star_lights(fixed_star):
glow_circle.scale = fixed_star_ratio * fixed_star.scale_x
glow_circle.look_at(camera)
glow_circle.look_at(camera)
glow_circle.update = glow_circle_update
fixed_star.glow_circle = glow_circle
if hasattr(fixed_star.body_view.body, "light_on"):
if fixed_star.body_view.body.light_on:
......@@ -394,6 +397,38 @@ def create_fixed_star_lights(fixed_star):
intensity=10, range=10, color=color.white)
def create_foreground(foreground_img):
from ursina import Panel
# 创建一个前景图片层
foreground_img = find_texture(foreground_img, None)
width = 0.9
height = .2
foreground = Panel(
parent=None,
model='quad',
texture=foreground_img,
color=color.white,
origin=(-.48, .48, -.48),
scale=(width*2, height),
position=(-0.85, -0.33, 0)
)
# foreground = Entity(model='quad', scale=(1, 1), texture=foreground_img, eternal=True)
# 设置前景图片层的位置和缩放
# foreground.position = (0, 0, 0) # 设置位置
# foreground.scale = (1, 1) # 设置缩放
# 将前景图片层设置为相机的子实体
# camera = EditorCamera()
# camera.add_child(foreground)
def update():
# 使前景图片层保持在最前面
foreground.world_z = camera.world_z - 0.01
foreground.update = update
def create_point_light(parent, light_color=None, position=(0, 0, 0)):
if light_color is None:
light_color = color.white
......@@ -449,3 +484,12 @@ def create_trail_info(body, trail):
if trail is not None:
trail.entity_infos = {"velocity": [vel_value, vel_direction, vel_position],
"acceleration": [acc_value, acc_direction, acc_position]}
if __name__ == '__main__':
from ursina import *
app = Ursina()
create_foreground("sun.jpg")
EditorCamera()
app.run()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册