From 88ecf8b5f96c485a5b7e982e2c048d61e266d4f4 Mon Sep 17 00:00:00 2001 From: march3 Date: Thu, 20 Apr 2023 12:30:27 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/consts.py | 3 +- common/func.py | 105 ++++++++++++++++++++++++++- sim_scenes/science/earth_seasons.py | 2 + simulators/ursina/entities/planet.py | 57 +++++++++++++-- 4 files changed, 154 insertions(+), 13 deletions(-) diff --git a/common/consts.py b/common/consts.py index 0d90941..3b0bb4e 100644 --- a/common/consts.py +++ b/common/consts.py @@ -27,7 +27,8 @@ AU: float = 149597870.700 """ 万有引力常数 """ -G: float = 6.67e-11 +# G: float = 6.67e-11 +G: float = 6.67408e-11 """ 一分钟多少秒 diff --git a/common/func.py b/common/func.py index dfa5602..9800bde 100644 --- a/common/func.py +++ b/common/func.py @@ -7,7 +7,7 @@ # python_version :3.8 # ============================================================================== from PIL import Image -from common.consts import AU +from common.consts import AU, G import numpy as np import random import os @@ -108,8 +108,6 @@ 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): """ @@ -138,6 +136,101 @@ def calculate_velocity(mass, semimajor_axis, eccentricity): 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__': # print(calculate_distance([6, 8, 0], [3, 4, 0])) # print(find_file("common/func.py")) @@ -149,4 +242,8 @@ if __name__ == '__main__': 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 + 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画图,并写上详细的注释。 +""" diff --git a/sim_scenes/science/earth_seasons.py b/sim_scenes/science/earth_seasons.py index 1da38a3..429a243 100644 --- a/sim_scenes/science/earth_seasons.py +++ b/sim_scenes/science/earth_seasons.py @@ -42,6 +42,8 @@ if __name__ == '__main__': text_color=[255, 255, 255], rotation_speed=0.5, # 为演示效果,自转角速度取0.5度/小时,实际为15度/小时 init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79]) + earth.rotate_axis_color = (255, 255, 162) + bodies = [ sun, earth, earth_1, earth_2, earth_3, earth_4, diff --git a/simulators/ursina/entities/planet.py b/simulators/ursina/entities/planet.py index 3af4c91..e3d93d4 100644 --- a/simulators/ursina/entities/planet.py +++ b/simulators/ursina/entities/planet.py @@ -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.func import find_file 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 @@ -101,13 +101,14 @@ class Planet(Entity): if hasattr(self.body, "rotate_angle"): if self.body.rotate_angle != 0: # 为了给天体增加一个倾斜角,增加了一个Entity - 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] + self.create_rotate_entity() + # 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] else: self.rotate_angle = 0 self.main_entity = self @@ -115,6 +116,14 @@ class Planet(Entity): self.rotate_angle = 0 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"): # 星环小天体群(主要模拟小行星群,非一个天体) self.set_light_off() @@ -143,6 +152,38 @@ class Planet(Entity): # 创建行星环(目前只有土星环) 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): if hasattr(self.body, "torus_stars"): # 星环小天体群(主要模拟小行星群,非一个天体)不受 body_size_factor 影响 -- GitLab