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

Python超人-宇宙模拟器

上级 b98c56d0
...@@ -45,6 +45,8 @@ class LookAtSkyOnEarth(UniverseSimScenes): ...@@ -45,6 +45,8 @@ class LookAtSkyOnEarth(UniverseSimScenes):
self.show_name = show_name self.show_name = show_name
self.exit_at_total_days = exit_at_total_days self.exit_at_total_days = exit_at_total_days
self.angle = 55 self.angle = 55
self.angle_d = -1
self.angle_s = 0.01
earth_transparent = look_point is not None earth_transparent = look_point is not None
...@@ -92,9 +94,9 @@ class LookAtSkyOnEarth(UniverseSimScenes): ...@@ -92,9 +94,9 @@ class LookAtSkyOnEarth(UniverseSimScenes):
self.target = self.create_camera_target() self.target = self.create_camera_target()
self.target.size_scale = 1e4 self.target.size_scale = 1e4
ep = self.earth.init_position ep = self.earth.init_position
self.target.init_position = [ep[0]+4e7,ep[1],ep[2]-4e7] self.target.init_position = [ep[0] + 4e7, ep[1], ep[2] - 4e7]
self.bodies = [ self.bodies = [
self.sun, self.earth #, self.target # , self.earth_core # , self.earth_clouds self.sun, self.earth # , self.target # , self.earth_core # , self.earth_clouds
] ]
...@@ -142,6 +144,40 @@ class LookAtSkyOnEarth(UniverseSimScenes): ...@@ -142,6 +144,40 @@ class LookAtSkyOnEarth(UniverseSimScenes):
y=-y, x=-x, z=z, color=color.blue) y=-y, x=-x, z=z, color=color.blue)
# y=-y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.blue) # y=-y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.blue)
def sky_watchers_move(self):
self.angle += self.angle_d * self.angle_s
if self.angle_d<0 and self.angle<16:
self.angle = 16
self.angle_d = 1
elif self.angle_d>0 and self.angle>90:
self.angle = 90
self.angle_d = -1
# print(self.angle)
if self.look_point is not None:
camera.rotation_x = self.angle * self.look_point
r = 0.5
x_y_angle = math.pi * self.angle / 180
xr = r * math.cos(x_y_angle)
y = r * math.sin(x_y_angle)
# z = pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5)
x_z_angle = math.pi * 45 / 180
x = r * math.cos(x_z_angle)
z = r * math.sin(x_z_angle)
# if self.look_point is None or self.look_point == 0:
# self.watcher_e.position = [-x, 0.0, z]
# y=0.0, x=x-0.17, z=pow(pow(r, 2) - pow(x-0.17, 2), 0.5), color=color.green)
x = xr * math.cos(x_z_angle)
z = xr * math.sin(x_z_angle)
if self.look_point is None or self.look_point == -1:
self.watcher_n.position = [-x, y, z]
# y=y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.red)
if self.look_point is None or self.look_point == 1:
self.watcher_s.position = [-x, -y, z]
# y=-y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.blue)
def on_ready(self): def on_ready(self):
self.create_sky_watchers() self.create_sky_watchers()
...@@ -252,28 +288,8 @@ class LookAtSkyOnEarth(UniverseSimScenes): ...@@ -252,28 +288,8 @@ class LookAtSkyOnEarth(UniverseSimScenes):
if abs(self.earth.planet.init_rotation_y - self.earth.planet.rotation_y) > 380: if abs(self.earth.planet.init_rotation_y - self.earth.planet.rotation_y) > 380:
exit(0) exit(0)
# if self.show_china and self.wait_days_count > 0: # self.sky_watchers_move()
# 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): def run(self, init_position=(0, 0, 0), speed_factor=1.0):
self.speed_factor = speed_factor self.speed_factor = speed_factor
......
# -*- coding:utf-8 -*-
# title :从地球上看天空
# description :从地球上看天空
# author :Python超人
# date :2023-12-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
import math
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.earth_core = Sun(size_scale=2e-1, texture="sun.png", rotation_speed=0).set_ignore_gravity(True)
self.earth_core.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
self.angle = 90
self.angle_d = -1
self.angle_s = 0.1
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_miller_projection_sw_trans.png" # "earth_miller_projection_sw.png" # "earth_miller_projection_SW.jpg"
clouds_texture = "transparent_clouds.png"
earth_size_scale = 6e3
# 运动的地球
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=None,
with_clouds=True, earth_rotation_speed=4,
clouds_rotation_speed=4,
earth_cn_size_factor=earth_cn_size_factor,
earth_clouds_size_factor=earth_clouds_size_factor)
self.earth.set_resolution(200)
self.earth.set_ignore_gravity(True)
self.earth.set_light_disable(True)
# # 地球立春的位置和速度
# 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.earth.init_velocity = [0, 0, 0]
self.target = self.create_camera_target()
self.target.size_scale = 1e4
ep = self.earth.init_position
self.target.init_position = [ep[0] + 4e7, ep[1], ep[2] - 4e7]
self.bodies = [
self.sun, self.earth # , self.target # , self.earth_core # , 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 create_sky_watchers(self):
from simulators.ursina.ursina_mesh import create_sphere
from ursina import Entity, color
r = 0.5
scale = 0.05
model = 'diamond'
model = "sphere"
# subdivisions = 16
x_y_angle = math.pi * self.angle / 180
xr = r * math.cos(x_y_angle)
y = r * math.sin(x_y_angle)
# z = pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5)
x_z_angle = math.pi * 45 / 180
x = r * math.cos(x_z_angle)
z = r * math.sin(x_z_angle)
# if self.look_point is None or self.look_point == 0:
# self.watcher_e = Entity(parent=self.earth.planet,
# model=model, # create_sphere(r, subdivisions),
# scale=scale,
# y=0.0, x=-x, z=z, color=color.red)
# y=0.0, x=x-0.17, z=pow(pow(r, 2) - pow(x-0.17, 2), 0.5), color=color.green)
x = xr * math.cos(x_z_angle)
z = xr * math.sin(x_z_angle)
if self.look_point is None or self.look_point == -1:
self.watcher_n = Entity(parent=self.earth.planet,
model=model, # create_sphere(r, subdivisions),
scale=scale,
y=y, x=-x, z=z, color=color.green)
# y=y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.red)
# if self.look_point is None or self.look_point == 1:
# self.watcher_s = Entity(parent=self.earth.planet,
# model=model, # create_sphere(r, subdivisions),
# scale=scale,
# y=-y, x=-x, z=z, color=color.blue)
# y=-y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.blue)
def sky_watchers_move(self):
self.angle += self.angle_d * self.angle_s
# if self.angle_d<0 and self.angle<16:
# self.angle = 16
# self.angle_d = 1
# elif self.angle_d>0 and self.angle>90:
# self.angle = 90
# self.angle_d = -1
# print(self.angle)
if self.look_point is not None:
camera.rotation_x = self.angle * self.look_point
r = 0.5
x_y_angle = math.pi * self.angle / 180
xr = r * math.cos(x_y_angle)
y = r * math.sin(x_y_angle)
# z = pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5)
x_z_angle = math.pi * 45 / 180
x = r * math.cos(x_z_angle)
z = r * math.sin(x_z_angle)
# if self.look_point is None or self.look_point == 0:
# self.watcher_e.position = [-x, 0.0, z]
# y=0.0, x=x-0.17, z=pow(pow(r, 2) - pow(x-0.17, 2), 0.5), color=color.green)
x = xr * math.cos(x_z_angle)
z = xr * math.sin(x_z_angle)
if self.look_point is None or self.look_point == -1:
self.watcher_n.position = [-x, y, z]
# y=y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.red)
# if self.look_point is None or self.look_point == 1:
# self.watcher_s.position = [-x, -y, z]
# y=-y, x=x, z=pow(pow(r, 2) - pow(x, 2) - pow(y, 2), 0.5), color=color.blue)
def on_ready(self):
self.create_sky_watchers()
self.earth.planet.rotation_y -= 180 # 一开始就正对太阳
# self.earth.planet.alpha = 0.8
# self.earth_cn.planet.rotation_y -= 185 # 一开始就正对太阳
if hasattr(self.earth_clouds, "planet"):
self.earth_clouds.planet.rotation_y -= 50 # 一开始就正对太阳
self.earth.planet.init_rotation_y = self.earth.planet.rotation_y
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 = self.angle * 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.fov = 120 # 默认:60
# camera.parent = self.sun.planet
else:
if self.look_point == 0:
camera.parent = self.watcher_e
elif self.look_point == -1:
camera.parent = self.watcher_n
elif self.look_point == 1:
camera.parent = self.watcher_s
# camera.parent = self.earth.planet
camera.rotation_z = 90
camera.fov = 75 # 默认:60
camera.clip_plane_near = 10
camera.clip_plane_far = 100000000
if hasattr(self.earth_core, "planet"):
self.earth_core.planet.parent = self.earth.planet
self.earth_core.planet.alpha = 1
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")
# if self.look_point is None:
def on_timer_changed(self, time_data: TimeData):
if abs(self.earth.planet.init_rotation_y - self.earth.planet.rotation_y) > 380:
exit(0)
self.sky_watchers_move()
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(speed_factor=0.75)
sim = LookAtSkyOnEarth(look_point=-1)
sim.run(speed_factor=0.7000)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册