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

太阳系三体模拟器

上级 672780ae
...@@ -8,4 +8,13 @@ ...@@ -8,4 +8,13 @@
#  天体质量: #  天体质量:
#  平均密度: #  平均密度:
``` ```
参考:
https://solarsystem.nasa.gov/solar-system/our-solar-system/overview/
https://trek.nasa.gov/mars/
https://trek.nasa.gov/moon/
https://www.jpl.nasa.gov/images
https://nasasearch.nasa.gov/search?affiliate=nasa&sort_by=&query=moon+map+texture
\ No newline at end of file
...@@ -23,7 +23,7 @@ class Body(metaclass=ABCMeta): ...@@ -23,7 +23,7 @@ class Body(metaclass=ABCMeta):
density=5e3, color=(125 / 255, 125 / 255, 125 / 255), density=5e3, color=(125 / 255, 125 / 255, 125 / 255),
texture=None, size_scale=1.0, distance_scale=1.0, texture=None, size_scale=1.0, distance_scale=1.0,
rotation_speed=None, parent=None, ignore_mass=False, rotation_speed=None, parent=None, ignore_mass=False,
is_fixed_star=False, trail_color=None): is_fixed_star=False, trail_color=None, show_name=False):
""" """
天体类 天体类
:param name: 天体名称 :param name: 天体名称
...@@ -83,6 +83,8 @@ class Body(metaclass=ABCMeta): ...@@ -83,6 +83,8 @@ class Body(metaclass=ABCMeta):
self.parent = parent self.parent = parent
self.__is_fixed_star = is_fixed_star self.__is_fixed_star = is_fixed_star
self.show_name = show_name
@property @property
def init_position(self): def init_position(self):
""" """
......
...@@ -27,3 +27,15 @@ ...@@ -27,3 +27,15 @@
?大角星 ?大角星
请从 NASA 官网上获取以下恒星的信息:
天狼星A,参宿五,昴宿六,大角星,毕宿五,参宿七,猎犬座Y,海山二,心宿二,船底座V382,参宿四,大犬座VY,盾牌座 UY,史蒂文森2-18
恒星信息格式如下:
昴宿六 (Alcyone)
质量:太阳质量的6倍 (1.193e+31 kg)
半径:太阳半径的9倍 (6.613e+06 km)
直径: 太阳直径的9倍 (1.323e+07 km)
密度: kg/m³
自转: 度/小时(自转角速度)
...@@ -12,7 +12,12 @@ from common.consts import MO ...@@ -12,7 +12,12 @@ from common.consts import MO
class Sirius(FixedStar): class Sirius(FixedStar):
""" """
天狼星A (Sirius) 天狼星A (Sirius A)
质量:太阳质量的2.02倍 (3.994e+30 kg)
半径:太阳半径的1.711倍 (9.529e+05 km)
直径:太阳直径的1.423倍 (2.386e+06 km)
密度: 1.590 kg/m³
自转: 16.7 度/小时
--------------- 维基百科 --------------- --------------- 维基百科 ---------------
天狼星A/B 天狼星A/B
(大犬座α) (大犬座α)
......
...@@ -17,6 +17,8 @@ class Stephenson_2_18(FixedStar): ...@@ -17,6 +17,8 @@ class Stephenson_2_18(FixedStar):
分类: 红超巨星 分类: 红超巨星
直径: 3005015000 km 直径: 3005015000 km
半径: 2158R☉ [1] 半径: 2158R☉ [1]
https://baijiahao.baidu.com/s?id=1734063731226819203&wfr=spider&for=pc
这颗恒星的体积就更加夸张了,根据科学家的估计,这颗恒星的体积,是太阳的100亿倍。换一句话说,史蒂文森2-18的体积是盾牌座UY的两倍。
--------------- 维基百科 --------------- --------------- 维基百科 ---------------
史蒂芬森2-18 史蒂芬森2-18
Stephenson 2-18 zoomed in, 2MASS survey, 2003.png Stephenson 2-18 zoomed in, 2MASS survey, 2003.png
......
...@@ -15,6 +15,8 @@ class UYScuti(FixedStar): ...@@ -15,6 +15,8 @@ class UYScuti(FixedStar):
盾牌座 UY (UY Scuti) 盾牌座 UY (UY Scuti)
质量 7-10 M☉ 质量 7-10 M☉
半径 1708 R☉ (有争议) 半径 1708 R☉ (有争议)
https://baijiahao.baidu.com/s?id=1734063731226819203&wfr=spider&for=pc
单单一个盾牌座UY,就能够容纳6500万亿个地球,太阳也能放进去50亿个。前文所说的弹珠还不恰当,准确来说,在盾牌座UY面前,太阳比细菌还不如。
--------------- 维基百科 --------------- --------------- 维基百科 ---------------
盾牌座UY 盾牌座UY
盾牌座UY(影像中最亮恒星)周围有大量恒星。 盾牌座UY(影像中最亮恒星)周围有大量恒星。
......
...@@ -43,3 +43,17 @@ def adjust_brightness(color, target_brightness: float = 0.6): ...@@ -43,3 +43,17 @@ def adjust_brightness(color, target_brightness: float = 0.6):
return Vec4(r, g, b, color.w) return Vec4(r, g, b, color.w)
else: else:
return color return color
def get_inverse_color(color):
"""计算 RGB 颜色的反色"""
r, g, b = color
if r + g + b <= 3:
inverse_r = 1.0 - r
inverse_g = 1.0 - g
inverse_b = 1.0 - b
else:
inverse_r = 255 - r
inverse_g = 255 - g
inverse_b = 255 - b
return inverse_r, inverse_g, inverse_b
...@@ -34,7 +34,7 @@ if __name__ == '__main__': ...@@ -34,7 +34,7 @@ if __name__ == '__main__':
CarinaeV382(size_scale=SIZE_SCALE, ignore_mass=True), # 船底座V382 质量倍数 39 半径倍数 747 CarinaeV382(size_scale=SIZE_SCALE, ignore_mass=True), # 船底座V382 质量倍数 39 半径倍数 747
# Betelgeuse(size_scale=SIZE_SCALE, ignore_mass=True), # 参宿四 质量倍数 19 半径倍数 1180 # Betelgeuse(size_scale=SIZE_SCALE, ignore_mass=True), # 参宿四 质量倍数 19 半径倍数 1180
VYCanisMajoris(size_scale=SIZE_SCALE, ignore_mass=True), # 大犬座VY 质量倍数 30 半径倍数 1400 VYCanisMajoris(size_scale=SIZE_SCALE, ignore_mass=True), # 大犬座VY 质量倍数 30 半径倍数 1400
UYScuti(size_scale=SIZE_SCALE, ignore_mass=True), # 盾牌座 UY 质量倍数 10 半径倍数 1708 # UYScuti(size_scale=SIZE_SCALE, ignore_mass=True), # 盾牌座 UY 质量倍数 10 半径倍数 1708
Stephenson_2_18(size_scale=SIZE_SCALE, ignore_mass=True) # 史蒂文森2-18 质量倍数 40.0 半径倍数 2150 Stephenson_2_18(size_scale=SIZE_SCALE, ignore_mass=True) # 史蒂文森2-18 质量倍数 40.0 半径倍数 2150
] ]
distance_sum = 0 distance_sum = 0
...@@ -54,4 +54,4 @@ if __name__ == '__main__': ...@@ -54,4 +54,4 @@ if __name__ == '__main__':
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, AU, -AU / 500), show_trail=True) ursina_run(bodies, SECONDS_PER_WEEK, position=(0, AU, -AU / 500), show_name=True)
...@@ -62,6 +62,7 @@ def ursina_run(bodies, ...@@ -62,6 +62,7 @@ def ursina_run(bodies,
cosmic_bg=None, cosmic_bg=None,
show_grid=True, show_grid=True,
show_trail=False, show_trail=False,
show_name=False,
save_as_json=None): save_as_json=None):
""" """
...@@ -81,9 +82,15 @@ def ursina_run(bodies, ...@@ -81,9 +82,15 @@ def ursina_run(bodies,
from ursina import application, Sequence, camera, held_keys, time, clamp, Entity, Text, color from ursina import application, Sequence, camera, held_keys, time, clamp, Entity, Text, color
from ursina.prefabs.first_person_controller import FirstPersonController from ursina.prefabs.first_person_controller import FirstPersonController
body_sys = System(bodies) body_sys = System(bodies)
if show_name:
for body in body_sys.bodies:
body.show_name = True
if save_as_json is not None: if save_as_json is not None:
try: try:
body_sys.save_to_json(save_as_json, {"dt": dt, "position": position, "show_trail": show_trail}) body_sys.save_to_json(save_as_json, {"dt": dt, "position": position,
"show_trail": show_trail, "show_name": show_name})
print(f"{save_as_json} 文件生成成功!") print(f"{save_as_json} 文件生成成功!")
except Exception as e: except Exception as e:
print(f"{save_as_json} 文件生成失败!" + str(e)) print(f"{save_as_json} 文件生成失败!" + str(e))
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
# ============================================================================== # ==============================================================================
# pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina # pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina
from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, \ from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, \
camera, color, mouse, Vec2, Vec3, Vec4, \ camera, color, mouse, Vec2, Vec3, Vec4, Text, \
load_texture, held_keys, destroy, PointLight load_texture, held_keys, destroy, PointLight
from ursina.prefabs.first_person_controller import FirstPersonController from ursina.prefabs.first_person_controller import FirstPersonController
...@@ -17,7 +17,7 @@ from bodies import Body ...@@ -17,7 +17,7 @@ from bodies import Body
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from common.color_utils import adjust_brightness, conv_to_vec4_color from common.color_utils import adjust_brightness, conv_to_vec4_color, get_inverse_color
from simulators.views.body_view import BodyView from simulators.views.body_view import BodyView
from simulators.views.ursina_mesh import create_sphere, create_torus from simulators.views.ursina_mesh import create_sphere, create_torus
import numpy as np import numpy as np
...@@ -134,6 +134,19 @@ class Planet(Entity): ...@@ -134,6 +134,19 @@ class Planet(Entity):
if self.body_view.body.is_fixed_star: if self.body_view.body.is_fixed_star:
self.create_fixed_star_lights() self.create_fixed_star_lights()
if self.body_view.body.show_name:
self.create_name_text()
def create_name_text(self):
b_color = self.body_view.color
self.name_text = Text(self.body_view.body.name, scale=2, billboard=True, parent=self,
font=UrsinaConfig.CN_FONT, background=True,
origin=(0, 0))
self.name_text.background.color = color.rgba(b_color[0], b_color[1], b_color[2], 0.3)
# self.name_text.scale = self.scale
inverse_color = get_inverse_color(b_color)
self.name_text.color = color.rgba(inverse_color[0], inverse_color[1], inverse_color[2], 1)
def trail_init(self): def trail_init(self):
""" """
拖尾球体的初始化 拖尾球体的初始化
...@@ -271,6 +284,12 @@ class Planet(Entity): ...@@ -271,6 +284,12 @@ class Planet(Entity):
else: else:
self.clear_trails() self.clear_trails()
if hasattr(self, "name_text"):
# 计算相机和实体之间的距离
distance = (camera.world_position - self.world_position).length()
# 根据距离设置文本缩放比例
# self.name_text.scale = distance / 10
def follow_parent(self): def follow_parent(self):
if not hasattr(self, "f_parent"): if not hasattr(self, "f_parent"):
if not hasattr(self.body_view, "bodies_system"): if not hasattr(self.body_view, "bodies_system"):
...@@ -316,17 +335,17 @@ class Planet(Entity): ...@@ -316,17 +335,17 @@ class Planet(Entity):
if glow_num > 0: if glow_num > 0:
glow_alphas = [0, 0.5, 0.4, 0.3, 0.2, 0.1] glow_alphas = [0, 0.5, 0.4, 0.3, 0.2, 0.1]
if glow_alpha is None: if glow_alpha is None:
if glow_num < len(glow_alphas)-1: if glow_num < len(glow_alphas) - 1:
glow_alpha = glow_alphas[glow_num] glow_alpha = glow_alphas[glow_num]
else: else:
glow_alpha = glow_alphas[-1] glow_alpha = glow_alphas[-1]
# _color = color.white # _color = color.white
_color = self.body_view.body.color _color = self.body_view.body.color
_color = color.rgba(_color[0]/255, _color[1]/255, _color[2]/255, 1) _color = color.rgba(_color[0] / 255, _color[1] / 255, _color[2] / 255, 1)
for i in range(glow_num): for i in range(glow_num):
glow_entity = Entity(parent=self, model='sphere', color=_color, glow_entity = Entity(parent=self, model='sphere', color=_color,
scale=math.pow(glow_scale, i+1), alpha=glow_alpha) scale=math.pow(glow_scale, i + 1), alpha=glow_alpha)
if hasattr(self.body_view.body, "light_on"): if hasattr(self.body_view.body, "light_on"):
if self.body_view.body.light_on: if self.body_view.body.light_on:
for i in range(2): for i in range(2):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册