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

Python超人-宇宙模拟器

上级 fd77b603
...@@ -15,79 +15,80 @@ from sim_scenes.universe_sim_scenes import UniverseSimScenes ...@@ -15,79 +15,80 @@ from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.func import ext_fun_for_method from simulators.func import ext_fun_for_method
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
if __name__ == '__main__':
sun = Sun(size_scale=5e2).set_resolution(60) # 太阳放大 500 倍
sun.glows = (30, 1.005, 0.03)
asteroids = Asteroids(size_scale=1.08e2, parent=sun) # 小行星模拟(仅 ursina 模拟器支持)
# 环状星群带(inner_radius, outer_radius, subdivisions)
# inner_radius:内圆半径 outer_radius:外圆半径,subdivisions:细分数,控制圆环的细节和精度
asteroids.torus_zone = 4.7, 5.5, 64
moon = Moon(size_scale=3e3, init_position=[0, 0, (0.4 + 2.4) * AU], distance_scale=1.8)
ceres = Ceres(size_scale=3e3, distance_scale=1.7)
earth = Earth(size_scale=3e3, distance_scale=3.8)
mars = Mars(size_scale=3e3, distance_scale=2.9)
jupiter = Jupiter(size_scale=0.68e3, distance_scale=1.15)
saturn = Saturn(size_scale=0.68e3, distance_scale=0.74)
bodies = [
sun,
Mercury(size_scale=3e3, distance_scale=7), # 水星放大 4000 倍
Venus(size_scale=3e3, distance_scale=4.3), # 金星放大 4000 倍
earth, # 地球放大 4000 倍
mars, # 火星放大 4000 倍
asteroids,
moon,
ceres,
# Earth(size_scale=3e3, init_position=[0, 0, (2.17) * AU]), # 地球放大 4000 倍
# Earth(size_scale=3e3, init_position=[0, 0, (3.64) * AU]), # 地球放大 4000 倍
jupiter, # 木星放大 680 倍
saturn, # 土星放大 680 倍
Uranus(size_scale=0.8e3, distance_scale=0.42), # 天王星放大 800 倍
Neptune(size_scale=1e3, distance_scale=0.3), # 海王星放大 1000 倍
]
# 水星 0.4AU
# 金星 0.4+0.3 AU
# 地球 0.4+0.6 AU
# 火星 0.4+1.2 AU
# 木星 0.4+4.8 AU
# 土星 0.4+9.6 AU
# 天王星 0.4+19.2 AU
# d = (n+4)/10
# an = 0.4+0.3×(2n-2)
planet_no = -1
for idx, body in enumerate(bodies):
if isinstance(body, Asteroids):
continue
body.rotation_speed = 0
planet_no += 1
# body.init_velocity = [0, 0, 0]
# an = 0.4 + 0.3 * pow(2,idx)
# an = (idx+4)/10
# 其中k=0,1,2,4,8,16,32,64,128 (0以后数字为2的2次方)
# 行星 公式推得值 实测值
# 金星 0.7 0.72
# 地球 1 1
# 火星 1.6 1.52
# 谷神星 2.8 2.9 [1]
# 木星 5.2 5.2
# 土星 10 9.54
# 天王星 19.6 19.18
# 海王星 38.8 30.06
# 冥王星 77.2 39.44
# 提丢斯-波得定则
# https://baike.baidu.com/item/%E6%8F%90%E4%B8%A2%E6%96%AF-%E6%B3%A2%E5%BE%97%E5%AE%9A%E5%88%99/859407
# 小行星 2.17-3.64天文单位
if planet_no == 0:
continue
elif planet_no == 1:
an = 0.4
else:
an = 0.4 + 0.3 * pow(2, planet_no - 2)
print(body.name, an, body.position[2] / AU)
class TheLostPlanetSim(UniverseSimScenes):
def __init__(self):
self.sun = Sun(size_scale=5e2).set_resolution(60) # 太阳放大 500 倍
self.sun.glows = (30, 1.005, 0.03)
# self.asteroids = Asteroids(size_scale=1.08e2, parent=self.sun) # 小行星模拟(仅 ursina 模拟器支持)
# 环状星群带(inner_radius, outer_radius, subdivisions)
# inner_radius:内圆半径 outer_radius:外圆半径,subdivisions:细分数,控制圆环的细节和精度
# self.asteroids.torus_zone = 4.7, 5.5, 64
self.moon = Moon(size_scale=3e3, init_position=[0, 0, (0.4 + 2.4) * AU], distance_scale=1.76)
# ceres = Ceres(size_scale=3e3, distance_scale=1.7)
self.earth = Earth(size_scale=3e3, distance_scale=3.8)
self.mars = Mars(size_scale=3e3, distance_scale=2.9)
self.jupiter = Jupiter(size_scale=0.68e3, distance_scale=1.12)
self.saturn = Saturn(size_scale=0.68e3, distance_scale=0.74)
self.bodies = [
self.sun,
Mercury(size_scale=3e3, distance_scale=7.3), # 水星放大 4000 倍
Venus(size_scale=3e3, distance_scale=4.5), # 金星放大 4000 倍
self.earth, # 地球放大 4000 倍
self.mars, # 火星放大 4000 倍
# asteroids,
self.moon,
# ceres,
# Earth(size_scale=3e3, init_position=[0, 0, (2.17) * AU]), # 地球放大 4000 倍
# Earth(size_scale=3e3, init_position=[0, 0, (3.64) * AU]), # 地球放大 4000 倍
self.jupiter, # 木星放大 680 倍
self.saturn, # 土星放大 680 倍
Uranus(size_scale=0.8e3, distance_scale=0.42), # 天王星放大 800 倍
Neptune(size_scale=1e3, distance_scale=0.3), # 海王星放大 1000 倍
]
# 水星 0.4AU
# 金星 0.4+0.3 AU
# 地球 0.4+0.6 AU
# 火星 0.4+1.2 AU
# 木星 0.4+4.8 AU
# 土星 0.4+9.6 AU
# 天王星 0.4+19.2 AU
# d = (n+4)/10
# an = 0.4+0.3×(2n-2)
planet_no = -1
for idx, body in enumerate(self.bodies):
if isinstance(body, Asteroids):
continue
body.rotation_speed = 0
planet_no += 1
# body.init_velocity = [0, 0, 0]
# an = 0.4 + 0.3 * pow(2,idx)
# an = (idx+4)/10
# 其中k=0,1,2,4,8,16,32,64,128 (0以后数字为2的2次方)
# 行星 公式推得值 实测值
# 金星 0.7 0.72
# 地球 1 1
# 火星 1.6 1.52
# 谷神星 2.8 2.9 [1]
# 木星 5.2 5.2
# 土星 10 9.54
# 天王星 19.6 19.18
# 海王星 38.8 30.06
# 冥王星 77.2 39.44
# 提丢斯-波得定则
# https://baike.baidu.com/item/%E6%8F%90%E4%B8%A2%E6%96%AF-%E6%B3%A2%E5%BE%97%E5%AE%9A%E5%88%99/859407
# 小行星 2.17-3.64天文单位
if planet_no == 0:
continue
elif planet_no == 1:
an = 0.4
else:
an = 0.4 + 0.3 * pow(2, planet_no - 2)
print(body.name, an, body.position[2] / AU)
def on_ready(): def on_ready(self):
""" """
事件绑定后,模拟器运行前会触发 事件绑定后,模拟器运行前会触发
@return: @return:
...@@ -99,7 +100,7 @@ if __name__ == '__main__': ...@@ -99,7 +100,7 @@ if __name__ == '__main__':
camera.clip_plane_near = 0.1 camera.clip_plane_near = 0.1
camera.clip_plane_far = 1000000 camera.clip_plane_far = 1000000
camera.look_at(jupiter.planet) camera.look_at(self.jupiter.planet)
# camera.look_at(sun.planet) # camera.look_at(sun.planet)
camera.rotation_z -= 90 camera.rotation_z -= 90
...@@ -109,13 +110,16 @@ if __name__ == '__main__': ...@@ -109,13 +110,16 @@ if __name__ == '__main__':
# UniverseSimScenes.show_grid_axises() # UniverseSimScenes.show_grid_axises()
asteroids.planet.enabled = False # self.asteroids.planet.enabled = False
moon.planet.enabled = False self.moon.planet.enabled = False
ceres.planet.enabled = False # ceres.planet.enabled = False
def set_alpha_animation(self, body, begin_alpha, end_alpha, interval, is_destroy=False):
def set_alpha_animation(body, begin_alpha, end_alpha, interval): from ursina import destroy
planet = body.planet if hasattr(body, "planet"):
planet = body.planet
else:
planet = body
planet.alpha = begin_alpha planet.alpha = begin_alpha
if begin_alpha > end_alpha: if begin_alpha > end_alpha:
interval = -abs(interval) interval = -abs(interval)
...@@ -135,127 +139,211 @@ if __name__ == '__main__': ...@@ -135,127 +139,211 @@ if __name__ == '__main__':
planet.enabled = (alpha > 0) planet.enabled = (alpha > 0)
planet.alpha = alpha planet.alpha = alpha
if is_destroy and not planet.enabled:
destroy(planet)
# planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha)
print(planet.alpha) # print(planet.alpha)
planet.update = alpha_animation planet.update = alpha_animation
# ext_fun_for_method(planet, after_run_fun=alpha_animation) # ext_fun_for_method(planet, after_run_fun=alpha_animation)
def create_asteroid(self, init_angle=89.5):
def create_asteroid():
from ursina import Entity, color, Vec3 from ursina import Entity, color, Vec3
import math import math
import random import random
pos = moon.planet.position # + Vec3() pos = self.moon.planet.position # + Vec3()
radius = moon.planet.position[2] + 40 * random.random() - 20 # * moon.distance_scale radius = self.moon.planet.position[2] + 40 * random.random() - 20 # * moon.distance_scale
asteroid = Entity(model='sphere', position=pos, color=color.white, scale=1.5) asteroid = Entity(model='sphere', position=pos, color=color.white, scale=1.5)
asteroid.s_angle = 89.5 asteroid.s_angle = init_angle
y = 10 * random.random() - 5 y = 10 * random.random() - 5
def rotation(): def rotation():
x = sun.planet.x + radius * math.cos(asteroid.s_angle) x = self.sun.planet.x + radius * math.cos(asteroid.s_angle)
z = sun.planet.z + radius * math.sin(asteroid.s_angle) z = self.sun.planet.z + radius * math.sin(asteroid.s_angle)
asteroid.position = (x, y, z) asteroid.position = (x, y, z)
speed = random.random() / 100 speed = random.random() / 50
asteroid.s_angle += speed asteroid.s_angle += speed
asteroid.update = rotation asteroid.update = rotation
return asteroid
def create_asteroids(self):
self.asteroids = []
for i in range(500):
self.asteroids.append(self.create_asteroid(i))
# # def clear_asteroids(self):
# def after_ready(): # for a in self.asteroids:
# from ursina import camera, Vec3 # a.enabled = False
# camera.position = Vec3(0,149.60,-665.76)
# camera.world_position = Vec3(-14.71,-98.38,0)
#
def on_timer_changed(time_data):
from ursina import camera, Vec3, distance
import math
# print(time_data.years)
if time_data.years > 1 and not hasattr(asteroids, "years_1"):
set_alpha_animation(asteroids, 0.0, 1.0, 0.01)
setattr(asteroids, "years_1", True)
elif time_data.years > 4 and not hasattr(asteroids, "years_5"):
set_alpha_animation(asteroids, 1.0, 0.0, 0.01)
setattr(asteroids, "years_5", True)
elif time_data.years > 6 and not hasattr(moon, "years_6"):
moon.planet.look_at(mars.planet)
moon.planet.update = lambda: None
set_alpha_animation(moon, 0.0, 1.0, 0.005)
setattr(moon, "years_6", True)
elif time_data.years > 8 and not hasattr(asteroids, "years_8"):
if not hasattr(asteroids, "c_time"):
asteroids.c_time = time.time()
c_time = time.time()
# set_alpha_animation(asteroids, 0.0, 1.0, 0.01)
if c_time - asteroids.c_time > 0.1:
asteroids.c_time = c_time
create_asteroid()
if time_data.years > 30 and not hasattr(moon, "mars_rotation"):
setattr(asteroids, "years_8", True)
moon.planet.look_at(mars.planet)
radius = 12
d = distance(moon.planet, mars.planet.position)
if d > 12:
moon.planet.position += moon.planet.forward * 0.1
else:
if not hasattr(mars, "moon_angle"):
setattr(mars, "moon_angle", 90)
moon_angle = getattr(mars, "moon_angle") def asteroid_fade_in(self):
x = mars.planet.x + radius * math.cos(moon_angle) """
z = mars.planet.z + radius * math.sin(moon_angle) 小行星群渐渐显示
moon.planet.position = (x, 0, z) @return:
"""
self.create_asteroids()
for a in self.asteroids:
self.set_alpha_animation(a, 0.0, 1.0, 0.01)
setattr(mars, "moon_angle", moon_angle + 0.08) def asteroid_fade_out(self):
"""
小行星群渐渐消失
@return:
"""
for a in self.asteroids:
self.set_alpha_animation(a, 1.0, 0.0, 0.01, is_destroy=True)
if moon_angle >= 110: def moon_fade_in(self):
setattr(moon, "mars_rotation", True) """
月球渐渐显示
@return:
"""
self.moon.planet.look_at(self.mars.planet)
self.moon.planet.update = lambda: None
self.set_alpha_animation(self.moon, 0.0, 1.0, 0.005)
def moon_renovation(self):
"""
月球改造中
@return:
"""
if not hasattr(self, "moon_redesign_last_time"):
self.moon_redesign_last_time = time.time()
c_time = time.time()
# set_alpha_animation(asteroids, 0.0, 1.0, 0.01)
if c_time - self.moon_redesign_last_time > 0.05:
self.moon_redesign_last_time = c_time
self.create_asteroid()
def moon_move_to_target_and_rotation(self, target, rotation_radius, end_angle, end_tag,
forward=0.1,
angle_val=0.08):
from ursina import camera, Vec3, distance
import math
if hasattr(target, "planet"):
target_planet = target.planet.main_entity
else:
target_planet = target.main_entity
print("moon_angle", moon_angle) self.moon.planet.look_at(target_planet)
elif hasattr(mars, "moon_angle") and not hasattr(moon, "earth_rotation"): d = distance(self.moon.planet, target_planet)
earth_target = earth.planet.main_entity if d > rotation_radius:
moon.planet.look_at(earth_target) self.moon.planet.position += self.moon.planet.forward * forward
radius = 15 else:
d = distance(moon.planet.position, earth_target.position) if not hasattr(target_planet, "moon_angle"):
if d > 15: setattr(target_planet, "moon_angle", 90)
moon.planet.position += moon.planet.forward * 0.1
else: moon_angle = getattr(target_planet, "moon_angle")
if not hasattr(earth, "moon_angle"): x = target_planet.x + rotation_radius * math.cos(moon_angle)
setattr(earth, "moon_angle", 90) z = target_planet.z + rotation_radius * math.sin(moon_angle)
self.moon.planet.position = (x, 0, z)
moon_angle = getattr(earth, "moon_angle") setattr(target_planet, "moon_angle", moon_angle + angle_val)
x = earth_target.x + radius * math.cos(moon_angle)
z = earth_target.z + radius * math.sin(moon_angle)
moon.planet.position = (x, 0, z)
setattr(earth, "moon_angle", moon_angle + 0.08) if moon_angle >= end_angle:
setattr(self, end_tag, True)
if moon_angle >= 360 * 2 + 90: # print("moon_angle", moon_angle)
setattr(moon, "earth_rotation", True)
print("moon_angle", moon_angle) def on_timer_changed(self, time_data):
# moon.planet.world_rotation_z = 90 from ursina import camera, Vec3, distance
# moon.planet.position += moon.planet.right * 0.1 import math
# setattr(moon, "years_8", True) if time_data.years > 1 and not hasattr(self, "step_01"):
# 小行星群渐渐显示,运行一次
self.asteroid_fade_in()
setattr(self, "step_01", True) # 控制运行一次
elif time_data.years > 6 and not hasattr(self, "step_02"):
# 小行星群渐渐消失,运行一次
self.asteroid_fade_out()
setattr(self, "step_02", True) # 控制运行一次
elif time_data.years > 8 and not hasattr(self.moon, "step_03"):
# 月球渐渐显示,运行一次
self.moon_fade_in()
setattr(self.moon, "step_03", True) # 控制运行一次
elif time_data.years > 10 and not hasattr(self, "step_04"):
# 月球改造中,运行多次
self.moon_renovation()
if time_data.years > 25 and not hasattr(self, "moon_around_mars"):
setattr(self, "step_04", True)
self.moon_move_to_target_and_rotation(target=self.mars,
rotation_radius=12,
end_angle=110,
end_tag="moon_around_mars",
forward=0.03, angle_val=0.05)
# self.moon.planet.look_at(self.mars.planet)
# radius = 12
# d = distance(self.moon.planet, self.mars.planet.position)
# if d > 12:
# self.moon.planet.position += self.moon.planet.forward * 0.1
# else:
# if not hasattr(self.mars, "moon_angle"):
# setattr(self.mars, "moon_angle", 90)
#
# moon_angle = getattr(self.mars, "moon_angle")
# x = self.mars.planet.x + radius * math.cos(moon_angle)
# z = self.mars.planet.z + radius * math.sin(moon_angle)
# self.moon.planet.position = (x, 0, z)
#
# setattr(self.mars, "moon_angle", moon_angle + 0.08)
#
# if moon_angle >= 110:
# setattr(self.moon, "mars_rotation", True)
# print("moon_angle", moon_angle)
elif hasattr(self, "moon_around_mars") and not hasattr(self, "moon_around_earth"):
self.moon_move_to_target_and_rotation(target=self.earth,
rotation_radius=15,
end_angle=360,
end_tag="moon_around_earth",
forward=0.03, angle_val=0.05)
# earth_target = self.earth.planet.main_entity
# self.moon.planet.look_at(earth_target)
# radius = 15
# d = distance(self.moon.planet.position, earth_target.position)
# if d > 15:
# self.moon.planet.position += self.moon.planet.forward * 0.1
# else:
# if not hasattr(self.earth, "moon_angle"):
# setattr(self.earth, "moon_angle", 90)
#
# moon_angle = getattr(self.earth, "moon_angle")
# x = earth_target.x + radius * math.cos(moon_angle)
# z = earth_target.z + radius * math.sin(moon_angle)
# self.moon.planet.position = (x, 0, z)
#
# setattr(self.earth, "moon_angle", moon_angle + 0.08)
# if moon_angle >= 360 * 2 + 90:
# setattr(moon, "earth_rotation", True)
# print("moon_angle", moon_angle)
# moon.planet.world_rotation_z = 90
# moon.planet.position += moon.planet.right * 0.1
# setattr(moon, "years_8", True)
# elif time_data.years > 15 and not hasattr(moon, "years_15"): # elif time_data.years > 15 and not hasattr(moon, "years_15"):
# set_alpha_animation(moon, 1.0, 0.0, 0.05) # set_alpha_animation(moon, 1.0, 0.0, 0.05)
# setattr(moon, "years_15", True) # setattr(moon, "years_15", True)
if __name__ == '__main__':
sim = TheLostPlanetSim()
# UniverseSimScenes.set_window_size((1920, 1079), False) # UniverseSimScenes.set_window_size((1920, 1079), False)
# 运行前会触发 on_ready # 运行前会触发 on_ready
UrsinaEvent.on_ready_subscription(on_ready) UrsinaEvent.on_ready_subscription(sim.on_ready)
# UrsinaEvent.after_ready_subscription(after_ready) # UrsinaEvent.after_ready_subscription(after_ready)
UrsinaEvent.on_timer_changed_subscription(on_timer_changed) UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(bodies, ursina_run(sim.bodies,
SECONDS_PER_YEAR, SECONDS_PER_YEAR,
gravity_works=False, gravity_works=False,
show_exit_button=False, show_exit_button=False,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册