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

Python超人-宇宙模拟器

上级 402ca47b
......@@ -11,6 +11,7 @@ from common.consts import AU
import numpy as np
import random
import os
import math
def get_dominant_colors(infile, resize=(20, 20)):
......@@ -107,7 +108,45 @@ def calculate_distance(pos1, pos2=[0, 0, 0]):
pow(np.array(pos1[2]) - np.array(pos2[2]), 2), 1 / 2)
return d
G = 6.67408e-11
# AU = 149597870700.0
def calculate_velocity(mass, semimajor_axis, eccentricity):
"""
计算天体在椭圆轨道上的速度。
参数:
- mass: 天体质量,单位 kg
- semimajor_axis: 轨道半长轴,单位 m
- eccentricity: 轨道离心率
返回值:
天体在轨道上的速度,单位 m/s。
"""
# 计算轨道的半短轴和半焦距
semiminor_axis = semimajor_axis * math.sqrt(1 - eccentricity ** 2)
focus_distance = semimajor_axis * eccentricity
# 计算轨道的第一和第二离心率角
theta = math.atan2(focus_distance, semiminor_axis)
psi = math.atan2(math.sqrt(1 - eccentricity ** 2) * math.sin(theta), eccentricity + math.cos(theta))
# 计算轨道的速率
v = math.sqrt(G * mass * (2 / semimajor_axis - 1 / semiminor_axis))
# 计算天体在轨道上的速度,注意要考虑太阳的质量
return v * math.sqrt(1 + (2 * mass) / (v ** 2 * AU)) * math.sin(psi)
if __name__ == '__main__':
# print(calculate_distance([6, 8, 0], [3, 4, 0]))
print(find_file("common/func.py"))
# print(find_file("common/func.py"))
# 使用地球数据测试
mass_earth = 5.972e24
semimajor_axis_earth = AU
eccentricity_earth = 0.0167
velocity_earth = calculate_velocity(mass_earth, semimajor_axis_earth, eccentricity_earth)
print("地球在轨道上的速度是:{:.2f} km/s".format(velocity_earth / 1000))
\ No newline at end of file
......@@ -9,11 +9,22 @@
# pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina
from ursina import Entity, Mesh, Text, color, destroy, Vec3
from common.color_utils import get_inverse_color
from simulators.ursina.ursina_mesh import create_arrow_line
class BodyTrail(Entity):
def __init__(self, **kwargs):
if "last_pos" in kwargs:
from_pos = kwargs["last_pos"]
else:
from_pos = (0, 0, 0)
if "to_pos" in kwargs:
to_pos = kwargs["to_pos"]
else:
to_pos = (1, 1, 1)
super().__init__(
model='sphere',
collider='sphere',
......@@ -21,6 +32,8 @@ class BodyTrail(Entity):
**kwargs
)
self.set_light_off()
def input(self, key):
if self.hovered:
if key == 'left mouse down':
......@@ -29,11 +42,18 @@ class BodyTrail(Entity):
self.show_infos()
def show_infos(self):
if not hasattr(self, "origin_alpha"):
self.origin_color = self.color
self.origin_alpha = self.alpha
if len(self.children) > 0:
for c in self.children:
destroy(c)
# self.color = self.origin_color
self.alpha = self.origin_alpha
return
self.alpha = 0.2
# self.color = get_inverse_color(self.origin_color)
vel_info, vel_direction, vel_position = self.entity_infos["velocity"]
acc_info, acc_direction, acc_position = self.entity_infos["acceleration"]
......@@ -53,19 +73,35 @@ class BodyTrail(Entity):
a_line.enabled = False
# class BodyTrail(Entity):
# def __init__(self, **kwargs):
# from_pos = (0, 0, 0)
# to_pos = (1, 1, 1)
# super().__init__(
# # model='line',
# model=Mesh(vertices=(from_pos, to_pos), mode='line', thickness=3),
# ignore_paused=True,
# **kwargs
# )
#
# def update(self):
# self.look_at(self.parent)
# # line = Entity(parent=parent,
# # model=Mesh(vertices=(from_pos * len_scale, to_pos * len_scale), mode='line', thickness=thickness),
# # color=color, alpha=alpha)
class BodyTrailLine_OK(Entity):
def __init__(self, **kwargs):
if "last_pos" in kwargs:
from_pos = kwargs["last_pos"]
else:
from_pos = (0, 0, 0)
if "to_pos" in kwargs:
to_pos = kwargs["to_pos"]
else:
to_pos = (1, 1, 1)
super().__init__(
# model='line',
model=Mesh(vertices=(from_pos, to_pos), mode='line', thickness=3),
ignore_paused=True,
**kwargs
)
class BodyTrailLine(Entity):
def __init__(self, **kwargs):
if "direction" in kwargs:
direction = kwargs["direction"]
else:
direction = (0, 0, 0)
super().__init__(
# model='line',
model=Mesh(vertices=((0, 0, 0), direction), mode='line', thickness=2),
ignore_paused=True,
**kwargs
)
......@@ -11,7 +11,7 @@ from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, t
camera, color, mouse, Vec2, Vec3, Vec4, Text, \
load_texture, held_keys, destroy, PointLight
from simulators.ursina.entities.body_trail import BodyTrail
from simulators.ursina.entities.body_trail import BodyTrail, BodyTrailLine
from simulators.ursina.ursina_config import UrsinaConfig
from common.color_utils import adjust_brightness, conv_to_vec4_color, get_inverse_color
from simulators.ursina.ursina_mesh import create_torus
......@@ -28,8 +28,8 @@ def create_name_text(parent):
"""
b_color = parent.body_view.color
name_text = Text(parent.body_view.body.name, scale=1, billboard=True, parent=parent,
font=UrsinaConfig.CN_FONT, background=True,
origin=(0, 0))
font=UrsinaConfig.CN_FONT, background=True,
origin=(0, 0))
name_text.background.color = color.rgba(b_color[0], b_color[1], b_color[2], 0.3)
name_text.resolution = 24
# self.name_text.scale = self.scale
......@@ -89,6 +89,7 @@ def create_trails(parent):
parent.destroy_all()
return
trails_keys = parent.trails.keys()
trail_int_scale = 1.2
# 如果有拖尾
if len(trails_keys) > 0:
# 获取最后一个拖尾的位置
......@@ -101,11 +102,15 @@ def create_trails(parent):
# if self_pos_distance < self.scale_x + (self.trail_scale / 2):
# pass
# 如果位置比较近,就不创建拖尾了,保证拖尾间隔一定的距离
if last_pos_distance < parent.trail_scale * 1.2: # 间隔距离不小于1.2倍的拖尾球体
if last_pos_distance < parent.trail_scale * trail_int_scale: # 间隔距离不小于1.2倍的拖尾球体
return
trail = create_trail(parent, pos)
create_trail_info(parent.body, trail)
# trail = create_trail_line(parent, pos)
trail = create_trail_sphere(parent, pos)
if trail is not None:
create_trail_info(parent.body, trail)
# 创建拖尾球体,并作为字典的key,存放拖尾球体的位置
parent.trails[trail] = pos
......@@ -121,7 +126,7 @@ def create_trails(parent):
break
def create_trail(parent, pos):
def create_trail_sphere(parent, pos):
"""
在天体当前的位置创建一个拖尾球体
:param pos:
......@@ -129,13 +134,43 @@ def create_trail(parent, pos):
"""
# sphere = create_sphere(1,6) diamond sphere
trail = BodyTrail(color=parent.trail_color, scale=parent.trail_scale, position=pos)
trail.set_light_off()
# trail.set_color_off()
# trail.set_color_scale_off()
# trail.enabled = False
return trail
def merge_vectors(vectors):
# 计算速度的大小
x, y, z = vectors[0], vectors[1], vectors[2]
value = math.sqrt(x ** 2 + y ** 2 + z ** 2)
# 计算速度的方向
direction = (x / value, y / value, z / value)
# 返回速度大小和速度方向
return value, direction
def create_trail_line(parent, pos):
"""
在天体当前的位置创建一个拖尾球体
:param pos:
:return:
"""
if hasattr(parent, "trail_last_pos"):
trail_last_pos = parent.trail_last_pos
value, direction = merge_vectors(pos - trail_last_pos)
trail = BodyTrailLine(color=parent.trail_color, scale=parent.trail_scale, position=trail_last_pos,
direction=Vec3(direction))
trail.set_light_off()
parent.last_trail = trail
else:
trail = None
parent.trail_last_pos = pos
return trail
def create_rings(self):
"""
创建行星环(使用土星贴图)
......@@ -250,7 +285,6 @@ def create_trail_info(body, trail):
else:
acc_info = "%.2fmm/s²" % (acc_m * 1000)
vel_direction = velocity[1]
vel_direction = np.array(vel_direction) * 5
......@@ -262,7 +296,6 @@ def create_trail_info(body, trail):
acc_position = acc_direction
# acc_position = (acc_position[0], acc_position[1], acc_position[2])
trail.entity_infos = {"velocity": [vel_info, vel_direction, vel_position],
"acceleration": [acc_info, acc_direction, acc_position]}
if trail is not None:
trail.entity_infos = {"velocity": [vel_info, vel_direction, vel_position],
"acceleration": [acc_info, acc_direction, acc_position]}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册