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

Python超人-宇宙模拟器

上级 9d760d33
...@@ -27,7 +27,8 @@ AU: float = 149597870.700 ...@@ -27,7 +27,8 @@ AU: float = 149597870.700
""" """
万有引力常数 万有引力常数
""" """
G: float = 6.67e-11 # G: float = 6.67e-11
G: float = 6.67408e-11
""" """
一分钟多少秒 一分钟多少秒
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
from PIL import Image from PIL import Image
from common.consts import AU from common.consts import AU, G
import numpy as np import numpy as np
import random import random
import os import os
...@@ -108,8 +108,6 @@ def calculate_distance(pos1, pos2=[0, 0, 0]): ...@@ -108,8 +108,6 @@ def calculate_distance(pos1, pos2=[0, 0, 0]):
pow(np.array(pos1[2]) - np.array(pos2[2]), 2), 1 / 2) pow(np.array(pos1[2]) - np.array(pos2[2]), 2), 1 / 2)
return d return d
G = 6.67408e-11
# AU = 149597870700.0
def calculate_velocity(mass, semimajor_axis, eccentricity): def calculate_velocity(mass, semimajor_axis, eccentricity):
""" """
...@@ -138,6 +136,101 @@ def calculate_velocity(mass, semimajor_axis, eccentricity): ...@@ -138,6 +136,101 @@ def calculate_velocity(mass, semimajor_axis, eccentricity):
return v * math.sqrt(1 + (2 * mass) / (v ** 2 * AU)) * math.sin(psi) return v * math.sqrt(1 + (2 * mass) / (v ** 2 * AU)) * math.sin(psi)
def get_lagrange_points(m1, m2, r, R, omega):
"""
函数需要5个输入参数:
m1: 大质点的质量(单位:kg)
m2: 小质点的质量(单位:kg)
r: 小质点到拉格朗日点的距离(单位:km)
R: 大质点到拉格朗日点的距离(单位:km)
omega: 两个星体之间的夹角(单位:rad)
函数返回一个元组,其中包括五个元素(Tuple),每个元素又是由七个数据(Tuple)组成:
@param m1:
@param m2:
@param r:
@param R:
@param omega:
@return:
x: 拉格朗日点的x坐标(单位:km)
y: 拉格朗日点的y坐标(单位:km)
z: 拉格朗日点的z坐标(单位:km)
vx: 拉格朗日点物体的x方向速度(单位:km/s)
vy: 拉格朗日点物体的y方向速度(单位:km/s)
vz: 拉格朗日点物体的z方向速度(单位:km/s)
"""
G = 6.673e-20 # gravitational constant in km^3/kg*s^2
M = m1 + m2
# Calculate mass ratio
mu = m2 / M
# Calculate distance between primary and secondary bodies
d = np.sqrt((R * mu) ** 2 + r ** 2 - 2 * R * r * mu * np.cos(omega))
# Calculate L1 point
a = (d - R) / (2 - mu)
x1 = R - a
y1 = 0
z1 = 0
v1 = np.sqrt(G * m2 * a / d) * (1 - mu)
vx1 = 0
vy1 = v1 * (R - x1) / d
vz1 = v1 * y1 / d
# Calculate L2 point
a = (d - R) / (2 - mu)
x2 = R + a
y2 = 0
z2 = 0
v2 = np.sqrt(G * m2 * a / d) * (1 - mu)
vx2 = 0
vy2 = v1 * (R - x2) / d
vz2 = v1 * y2 / d
# Calculate L3 point
a = (d + R) / (2 + mu)
x3 = -a
y3 = 0
z3 = 0
v3 = np.sqrt(G * m1 * a / d) * (1 + mu)
vx3 = 0
vy3 = v3 * (R - x3) / d
vz3 = v3 * -y3 / d
# Calculate L4 and L5 points
x4, y4, z4, v4, vx4, vy4, vz4 = get_l4_l5_points(m1, m2, R, omega, 1)
x5, y5, z5, v5, vx5, vy5, vz5 = get_l4_l5_points(m1, m2, R, omega, -1)
return ((x1, y1, z1, vx1, vy1, vz1),
(x2, y2, z2, vx2, vy2, vz2),
(x3, y3, z3, vx3, vy3, vz3),
(x4, y4, z4, vx4, vy4, vz4),
(x5, y5, z5, vx5, vy5, vz5))
def get_l4_l5_points(m1, m2, R, omega, sign):
# G = 6.673e-20 # gravitational constant in km^3/kg*s^2
M = m1 + m2
# Calculate mass ratio
mu = m2 / M
# Calculate position of L4 or L5 point
x = R * np.cos(omega + sign * 60 * np.pi / 180)
y = R * np.sin(omega + sign * 60 * np.pi / 180)
z = 0
# Calculate velocity of L4 or L5 point
v = np.sqrt(G * M / (3 * R))
vx = -v * y / R
vy = v * x / R
vz = 0
return x, y, z, v, vx, vy, vz
if __name__ == '__main__': if __name__ == '__main__':
# print(calculate_distance([6, 8, 0], [3, 4, 0])) # print(calculate_distance([6, 8, 0], [3, 4, 0]))
# print(find_file("common/func.py")) # print(find_file("common/func.py"))
...@@ -150,3 +243,7 @@ if __name__ == '__main__': ...@@ -150,3 +243,7 @@ if __name__ == '__main__':
velocity_earth = calculate_velocity(mass_earth, semimajor_axis_earth, eccentricity_earth) velocity_earth = calculate_velocity(mass_earth, semimajor_axis_earth, eccentricity_earth)
print("地球在轨道上的速度是:{:.2f} km/s".format(velocity_earth / 1000)) print("地球在轨道上的速度是:{:.2f} km/s".format(velocity_earth / 1000))
"""
你现在是一位资深的天体学家、请使用python完成一个获取拉格朗日点的函数,获取拉格朗日点的坐标(px,py 单位:km)同时,也要返回拉格朗日点物体的速度(vx,vy 单位:km/s),需要返回L1-L5所有的点和速度。返回的L1、L2、L3、L4、L5 格式为:(x1, y1, vx1, vy1),(x2, y2, vx2, vy2), (x3, y3, vx3, vy3), (x4, y4, vx4, vy4) (x5, y5, vx5, vy5),并针对太阳、地球拉格朗日点以及 地球、月球拉格朗日点举例。并使用matlibplot画图,并写上详细的注释。
"""
...@@ -42,6 +42,8 @@ if __name__ == '__main__': ...@@ -42,6 +42,8 @@ if __name__ == '__main__':
text_color=[255, 255, 255], rotation_speed=0.5, # 为演示效果,自转角速度取0.5度/小时,实际为15度/小时 text_color=[255, 255, 255], rotation_speed=0.5, # 为演示效果,自转角速度取0.5度/小时,实际为15度/小时
init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79]) init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79])
earth.rotate_axis_color = (255, 255, 162)
bodies = [ bodies = [
sun, earth, sun, earth,
earth_1, earth_2, earth_3, earth_4, earth_1, earth_2, earth_3, earth_4,
......
...@@ -16,7 +16,7 @@ from simulators.ursina.ursina_event import UrsinaEvent ...@@ -16,7 +16,7 @@ from simulators.ursina.ursina_event import UrsinaEvent
from common.color_utils import adjust_brightness, conv_to_vec4_color, get_inverse_color from common.color_utils import adjust_brightness, conv_to_vec4_color, get_inverse_color
from common.func import find_file from common.func import find_file
from simulators.views.body_view import BodyView from simulators.views.body_view import BodyView
from simulators.ursina.ursina_mesh import create_sphere, create_torus, create_arrow_line from simulators.ursina.ursina_mesh import create_sphere, create_torus, create_arrow_line, create_line
import math import math
...@@ -101,13 +101,14 @@ class Planet(Entity): ...@@ -101,13 +101,14 @@ class Planet(Entity):
if hasattr(self.body, "rotate_angle"): if hasattr(self.body, "rotate_angle"):
if self.body.rotate_angle != 0: if self.body.rotate_angle != 0:
# 为了给天体增加一个倾斜角,增加了一个Entity # 为了给天体增加一个倾斜角,增加了一个Entity
self.rotate_angle = self.body.rotate_angle self.create_rotate_entity()
self.main_entity = Entity() # self.rotate_angle = self.body.rotate_angle
self.main_entity.rotation_x = self.rotate_angle # self.main_entity = Entity()
self.main_entity.body_view = self.body_view # self.main_entity.rotation_x = self.rotate_angle
self.main_entity.body = self.body # self.main_entity.body_view = self.body_view
self.parent = self.main_entity # self.main_entity.body = self.body
self.position = [0, 0, 0] # self.parent = self.main_entity
# self.position = [0, 0, 0]
else: else:
self.rotate_angle = 0 self.rotate_angle = 0
self.main_entity = self self.main_entity = self
...@@ -115,6 +116,14 @@ class Planet(Entity): ...@@ -115,6 +116,14 @@ class Planet(Entity):
self.rotate_angle = 0 self.rotate_angle = 0
self.main_entity = self self.main_entity = self
# Rotation axis color
if hasattr(self.body, "rotate_axis_color"):
if self.body.rotate_axis_color is not None:
axis_color = self.body.rotate_axis_color
axis_color = (axis_color[0] / 255, axis_color[1] / 255, axis_color[2] / 255, 1.0)
axis_color = color.rgba(*axis_color)
self.create_rotate_line(axis_color)
if hasattr(self.body, "torus_stars"): if hasattr(self.body, "torus_stars"):
# 星环小天体群(主要模拟小行星群,非一个天体) # 星环小天体群(主要模拟小行星群,非一个天体)
self.set_light_off() self.set_light_off()
...@@ -143,6 +152,38 @@ class Planet(Entity): ...@@ -143,6 +152,38 @@ class Planet(Entity):
# 创建行星环(目前只有土星环) # 创建行星环(目前只有土星环)
create_rings(self) create_rings(self)
def create_rotate_entity(self):
"""
@return:
"""
self.rotate_angle = self.body.rotate_angle
self.main_entity = Entity()
self.main_entity.rotation_x = self.rotate_angle
self.main_entity.body_view = self.body_view
self.main_entity.body = self.body
self.parent = self.main_entity
self.position = [0, 0, 0]
def create_rotate_line(self, line_color):
from_pos = Vec3(0, 1, 0)
to_pos = Vec3(0, -1, 0)
# UrsinaConfig.SCALE_FACTOR * 10000000 = 5
# UrsinaConfig.auto_scale_factor = 1
# UrsinaConfig.body_size_factor = 1
if self.main_entity is self:
# 没有偏转角度
line_scale = math.pow(self.main_entity.scale_x, 1 / 10) / 1.5
else:
# 有偏转角度
# line_scale = math.pow(self.main_entity.scale_x, 1 / 10)
line_scale = self.scale_x
# camera.scale_x
create_line(from_pos, to_pos, parent=self.main_entity,
len_scale=line_scale, color=line_color, thickness=2)
def change_body_scale(self): def change_body_scale(self):
if hasattr(self.body, "torus_stars"): if hasattr(self.body, "torus_stars"):
# 星环小天体群(主要模拟小行星群,非一个天体)不受 body_size_factor 影响 # 星环小天体群(主要模拟小行星群,非一个天体)不受 body_size_factor 影响
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册