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

Python超人-宇宙模拟器

上级 659169d9
# -*- coding:utf-8 -*-
# title :地月场景模拟
# description :地月场景模拟
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from bodies import Moon, Earth, Body
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import mayavi_run, ursina_run
import math
import random
# def calculate_satellite_velocity(earth: Earth, altitude):
# """
#
# @param earth_raduis:
# @param altitude:
# @return:
# """
# # 地球引力常数
# G = 6.67430e-11
# # 地球质量
# M = earth.mass # 5.97e24
# # 地球半径
# R = earth.raduis + altitude
# # 地球表面的线速度
# v_surface = math.sqrt(G * M / R)
# # 地球卫星轨道速度
# v_satellite = math.sqrt(G * M / (R + altitude))
# return v_satellite - v_surface
import random
import random
import math
def get_satellite_position_velocity(earth_mass, earth_position, earth_radius, altitude):
# 万有引力常数
G = 6.6743 * 10 ** (-11)
# 地球质量
M = earth_mass
# 地球半径+海拔高度
R = earth_radius + altitude
# 随机生成卫星的位置,确保在球面上
phi = random.uniform(0, 2 * math.pi)
costheta = random.uniform(-1, 1)
u = random.uniform(0, 1)
theta = math.acos(costheta)
r = R * (u ** (1 / 3))
x = r * math.sin(theta) * math.cos(phi)
y = r * math.sin(theta) * math.sin(phi)
z = r * math.cos(theta)
# 计算速度的方向
# 位置矢量
r_vec = [x, y, z]
# 速度方向和位置矢量垂直,采用向量叉积的性质
v_dir = [-y, x, 0]
# 归一化
v_dir_norm = [v / math.sqrt(x ** 2 + y ** 2) for v in v_dir]
# 计算速度大小
v = math.sqrt(G * M / R)
# 计算速度矢量
v_vec = [v * dir for dir in v_dir_norm]
# 计算卫星的位置和速度
position = [earth_position[0] + x, earth_position[1] + y, earth_position[2] + z]
velocity = v_vec
return tuple(position), [0, 0, 0]
def generate_satellite_coordinates(earth_radius, altitude):
theta = random.uniform(0, 2 * math.pi) # 在0~2π内随机生成一个角度
phi = random.uniform(0, math.pi) # 在0~π内随机生成一个角度
r = earth_radius + altitude # 地球半径+海拔高度
x = r * math.sin(phi) * math.cos(theta) # 计算x坐标
y = r * math.sin(phi) * math.sin(theta) # 计算y坐标
z = r * math.cos(phi) # 计算z坐标
return [x, y, z]
if __name__ == '__main__':
"""
地球、6个月球
"""
# 地球在中心位置
earth = Earth(init_position=[0, 0, 0], size_scale=1, texture="earth_hd.jpg", init_velocity=[0, 0, 0])
# 北斗卫星高度为2.13-2.15万千米。GPS卫星平均轨道高度2.02万千米。
bodies = [earth]
for i in range(10):
altitude = random.randint(4000, 10000)
position, velocity = get_satellite_position_velocity(earth.mass, earth.init_position, earth.raduis, altitude)
satellite = Body(name=f'卫星{i + 1}', mass=4.4e10, size_scale=1e3, color=(255, 200, 0),
init_position=position,
init_velocity=velocity)
bodies.append(satellite)
# 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_HOUR/60, position=(0, 0, -80000), show_trail=True, view_closely=0.01)
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
from bodies import Moon, Earth, Body from bodies import Moon, Earth, Body
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import mayavi_run, ursina_run from sim_scenes.func import mayavi_run, ursina_run
from bodies.body import AU
if __name__ == '__main__': if __name__ == '__main__':
""" """
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
from ursina import Entity, Mesh, Text, color, destroy, Vec3 from ursina import Entity, Mesh, Text, color, destroy, Vec3
from common.color_utils import get_inverse_color from common.color_utils import get_inverse_color
from simulators.ursina.ursina_mesh import create_label
from simulators.ursina.ursina_mesh import create_arrow_line from simulators.ursina.ursina_mesh import create_arrow_line
...@@ -56,22 +57,46 @@ class BodyTrail(Entity): ...@@ -56,22 +57,46 @@ class BodyTrail(Entity):
self.alpha = 0.3 self.alpha = 0.3
# self.color = get_inverse_color(self.origin_color) # self.color = get_inverse_color(self.origin_color)
vel_info, vel_direction, vel_position = self.entity_infos["velocity"] vel_value, vel_direction, vel_position = self.entity_infos["velocity"]
acc_info, acc_direction, acc_position = self.entity_infos["acceleration"] acc_value, acc_direction, acc_position = self.entity_infos["acceleration"]
v_arrow, v_line, v_text = create_arrow_line((0, 0, 0), tuple(vel_direction), parent=self, if vel_value >= 0.01:
label=vel_info, color=color.red, alpha=0.8, arrow_scale=0.5) vel_info = "%.2fkm/s" % (vel_value)
if str(vel_info).startswith("0.00"): elif vel_value >= 0.00001:
v_text.parent = self vel_info = "%.2fm/s" % (vel_value * 1000)
v_arrow.enabled = False elif vel_value >= 0.00000001:
v_line.enabled = False vel_info = "%.2fmm/s" % (vel_value * 1000 * 1000)
else:
a_arrow, a_line, a_text = create_arrow_line((0, 0, 0), tuple(acc_direction), parent=self, vel_info = "0m/s"
label=acc_info, color=color.green, alpha=0.8, arrow_scale=0.5)
if str(acc_info).startswith("0.00"): acc_m = acc_value * 1000
a_text.parent = self
a_arrow.enabled = False if acc_m >= 0.01:
a_line.enabled = False acc_info = "%.2fm/s²" % (acc_m)
elif acc_m >= 0.00001:
acc_info = "%.2fmm/s²" % (acc_m * 1000)
# elif acc_m >= 0.00000001:
# acc_info = "%.2fμm/s²" % (acc_m * 1000 * 1000)
else:
acc_info = "0m/s²"
if vel_value < 0.00000001:
create_label(parent=self, label=vel_info, pos=Vec3(-0.5, -0.5, -0.5), color=color.red).set_light_off()
# v_text.parent = self
# # v_arrow.enabled = False
# # v_line.enabled = False
else:
v_arrow, v_line, v_text = create_arrow_line((0, 0, 0), tuple(vel_direction), parent=self,
label=vel_info, color=color.red, alpha=0.8, arrow_scale=0.5)
if acc_m < 0.00001:
create_label(parent=self, label=acc_info, pos=Vec3(0.5, 0.5, 0.5), color=color.green).set_light_off()
# a_text.parent = self
# a_arrow.enabled = False
# a_line.enabled = False
else:
a_arrow, a_line, a_text = create_arrow_line((0, 0, 0), tuple(acc_direction), parent=self,
label=acc_info, color=color.green, alpha=0.8, arrow_scale=0.5)
class BodyTrailLine_OK(Entity): class BodyTrailLine_OK(Entity):
......
...@@ -276,14 +276,8 @@ def merge_vectors(vectors): ...@@ -276,14 +276,8 @@ def merge_vectors(vectors):
def create_trail_info(body, trail): def create_trail_info(body, trail):
velocity = merge_vectors(body.velocity) velocity = merge_vectors(body.velocity)
acceleration = merge_vectors(body.acceleration) acceleration = merge_vectors(body.acceleration)
vel_info = "%.2fkm/s" % (velocity[0]) vel_value = velocity[0] # km/s
acc_value = acceleration[0] # km/s²
acc_m = acceleration[0] * 1000
if acc_m >= 0.01:
acc_info = "%.2fm/s²" % (acc_m)
else:
acc_info = "%.2fmm/s²" % (acc_m * 1000)
vel_direction = velocity[1] vel_direction = velocity[1]
vel_direction = np.array(vel_direction) * 5 vel_direction = np.array(vel_direction) * 5
...@@ -297,5 +291,6 @@ def create_trail_info(body, trail): ...@@ -297,5 +291,6 @@ def create_trail_info(body, trail):
acc_position = acc_direction acc_position = acc_direction
# acc_position = (acc_position[0], acc_position[1], acc_position[2]) # acc_position = (acc_position[0], acc_position[1], acc_position[2])
if trail is not None: if trail is not None:
trail.entity_infos = {"velocity": [vel_info, vel_direction, vel_position], trail.entity_infos = {"velocity": [vel_value, vel_direction, vel_position],
"acceleration": [acc_info, acc_direction, acc_position]} "acceleration": [acc_value, acc_direction, acc_position]}
...@@ -91,6 +91,13 @@ def create_arrow(height=0.5, width=0.1): ...@@ -91,6 +91,13 @@ def create_arrow(height=0.5, width=0.1):
return arrow_mesh return arrow_mesh
def create_label(parent, label, pos, color, scale=50, alpha=1.0):
text = Text(label, parent=parent, scale=scale, billboard=True, color=color,
position=Vec3(pos) + Vec3(1, 1, 1), alpha=alpha,
font=UrsinaConfig.CN_FONT, background=False)
return text
def create_arrow_line(from_pos, to_pos, parent=None, label=None, def create_arrow_line(from_pos, to_pos, parent=None, label=None,
set_light_off=True, alpha=1.0, len_scale=0.5, set_light_off=True, alpha=1.0, len_scale=0.5,
color=color.white, thickness=2, color=color.white, thickness=2,
...@@ -125,9 +132,8 @@ def create_arrow_line(from_pos, to_pos, parent=None, label=None, ...@@ -125,9 +132,8 @@ def create_arrow_line(from_pos, to_pos, parent=None, label=None,
arrow.set_light_off() arrow.set_light_off()
if label is not None: if label is not None:
text = Text(label, parent=line, scale=text_scale, billboard=True, color=color, text = create_label(parent=line, label=label, pos=Vec3(to_pos) * len_scale * 1.2,
position=Vec3(to_pos) + Vec3(1, 1, 1), alpha=alpha, color=color, scale=text_scale, alpha=alpha)
font=UrsinaConfig.CN_FONT, background=False)
if set_light_off: if set_light_off:
text.set_light_off() text.set_light_off()
else: else:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册