提交 202044b2 编写于 作者: M march3

三体运行模拟器

上级 8f7f33a8
......@@ -27,7 +27,7 @@ class Asteroid(Body):
"""
def __init__(self, name="Asteroid", mass=4.1e10,
init_position=[1.5 * AU, 0, 0],
init_position=[1.6 * AU, 0, 0],
init_velocity=[0, 25.37, 0],
texture="", size_scale=1.0, distance_scale=1.0):
params = {
......@@ -43,6 +43,17 @@ class Asteroid(Body):
}
super().__init__(**params)
def ignore_gravity(self, body):
"""
是否忽略引力
:param body:
:return:
"""
# 小行星只对恒星有引力,忽略其他行星的引力
if body.is_fixed_star:
return False
return True
if __name__ == '__main__':
asteroid = Asteroid()
......
......@@ -17,6 +17,7 @@ class Body(metaclass=ABCMeta):
"""
天体信息基类
"""
def __init__(self, name, mass, init_position, init_velocity,
density=5e3, color=(125 / 255, 125 / 255, 125 / 255),
texture=None, size_scale=1.0, distance_scale=1.0):
......@@ -231,6 +232,15 @@ class Body(metaclass=ABCMeta):
(self.name, self.mass, self.raduis,
self.position[0], self.position[1], self.position[2], self.velocity)
def ignore_gravity(self, body):
"""
是否忽略引力
:param body:
:return:
"""
return False
def position_au(self):
"""
获取天体的位置(单位:天文单位 A.U.)
......
......@@ -7,6 +7,9 @@
# python_version :3.8
# ==============================================================================
from PIL import Image
from common.consts import AU
import numpy as np
import random
def get_dominant_colors(infile, resize=(20, 20)):
......@@ -37,3 +40,136 @@ def get_dominant_colors(infile, resize=(20, 20)):
colors.append(tuple(dominant_color))
return colors
def circle_x_y(points, radius=1.6 * AU):
"""
:param points:
:param radius:
:return:
"""
x = radius * np.cos(points)
y = radius * np.sin(points)
return x, y
def get_position_force(angles, force=1, radius=1, radius_offset=None, force_offset=None):
"""
:param angles:
:param force:
:param radius:
:param radius_offset:
:param force_offset:
:return:
"""
angles = np.array(angles * np.pi)
if isinstance(radius_offset, int):
radius = radius + np.random.rand(len(angles)) * radius_offset
if isinstance(force_offset, int):
force = force + np.random.rand(len(angles)) * force_offset
pxs = radius * np.cos(angles)
pys = radius * np.sin(angles)
fys = force * np.cos(angles) # math.cos(math.radians(angle))
fxs = force * np.sin(angles) # math.sin(math.radians(angle))
# return pxs, pys, fxs, fys
return np.round(pxs, 2), np.round(pys, 2), -np.round(fxs, 2), np.round(fys, 2)
#
#
# import math
#
# """
# 用python写一个函数,根据不同角度的参数列表,返回坐标 pos_x, pos_y,以及分解力fx fy
#
# def get_force(angle_list):
# pos_x = 0
# pos_y = 0
# fx = 0
# fy = 0
# for angle in angle_list:
# force_x, force_y = get_force_from_angle(angle)
# pos_x += force_x
# pos_y += force_y
# fx += force_x
# fy += force_y
#
# return pos_x, pos_y, fx, fy
#
# def get_force_from_angle(angle):
# force_x = math.cos(math.radians(angle))
# force_y = math.sin(math.radians(angle))
# return force_x, force_y
# """
#
# """
# ```python
# def get_positions_forces_from_angles(angles,radius, force):
#
# ```
# """
#
#
# def get_position_force(angle_list, radius=1, force=1):
# fxs = []
# fys = []
# angle_list = np.array(angle_list * np.pi)
# pxs = radius * np.cos(angle_list)
# pys = radius * np.sin(angle_list)
#
# for angle in angle_list:
# fx, fy = get_force_from_angle(angle)
# fxs.append(fx * force)
# fys.append(fy * force)
#
# return np.round(pxs, 2), np.round(pys, 2), np.round(fxs, 2), np.round(fys, 2)
#
#
# def get_force_from_angle(angle):
# force_x = math.cos(angle)
# force_y = math.sin(angle)
# # force_x = math.cos(math.radians(angle))
# # force_y = math.sin(math.radians(angle))
# return force_x, force_y
#
#
# if __name__ == '__main__':
# # a = [0, 45, 90, 135, 180, 225, 270, 315, 360]
# # start:返回样本数据开始点
# # stop:返回样本数据结束点
# # num:生成的样本数据量,默认为50
# points = np.linspace(0, 2 * np.pi, 10)
# # points = np.array([0, 45, 90, 135, 180, 225, 270, 315, 360])
# # points = np.array([0. , 0.17453293, 0.34906585, 0.52359878, 0.6981317 ,
# # 0.87266463, 1.04719755, 1.22173048, 1.3962634 , 1.57079633])
# # x, y = circle_x_y(points, 1)
# # print(x, y)
# print(points)
# pos_x, pos_y, fx, fy = circle_x_y_f(points, radius=1.6, force=25.37)
# print(pos_x, pos_y, fx, fy)
#
# """
# asteroids = [
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[1.6 * AU, 0, 0],
# init_velocity=[0, 25.37, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[-1.6 * AU, 0, 0],
# init_velocity=[0, -25.37, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[0, 1.6 * AU, 0],
# init_velocity=[-25.37, 0, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[0, -1.6 * AU, 0],
# init_velocity=[25.37, 0, 0],
# distance_scale=1),
# ]
# """
......@@ -69,6 +69,8 @@ class System(object):
for body2 in self.bodies:
if body1 is body2:
continue
elif body1.ignore_gravity(body2) or body2.ignore_gravity(body1):
continue
r = body2.position - body1.position
# G = 6.67e-11 # 万有引力常数
......
......@@ -7,8 +7,11 @@
# python_version :3.8
# ==============================================================================
from bodies import Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto, Asteroid
from bodies.body import AU
from common.consts import SECONDS_PER_WEEK
from common.func import get_position_force
from scenes.func import mayavi_run
import numpy as np
if __name__ == '__main__':
# 八大行星:木星(♃)、土星(♄)、天王星(♅)、海王星(♆)、地球(⊕)、金星(♀)、火星(♂)、水星(☿)
......@@ -20,18 +23,54 @@ if __name__ == '__main__':
# 以下展示的效果非太阳系真实的距离和大小
# 1、由于宇宙空间尺度非常大,按照实际的大小无法看到行星天体,因此需要对天体的尺寸进行放大
# 2、对每个行星天体的距离进行了缩放
# 构建4个小行星
# asteroids = [
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[1.6 * AU, 0, 0],
# init_velocity=[0, 25.37, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[-1.6 * AU, 0, 0],
# init_velocity=[0, -25.37, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[0, 1.6 * AU, 0],
# init_velocity=[-25.37, 0, 0],
# distance_scale=1),
# Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
# init_position=[0, -1.6 * AU, 0],
# init_velocity=[25.37, 0, 0],
# distance_scale=1),
# ]
# 构建 50 小行星,太多的小行星会影响电脑性能
NUM_OF_ASTEROIDS = 60
asteroids = []
angles = np.linspace(0, 40 * np.pi, NUM_OF_ASTEROIDS)
pxs, pys, fxs, fys = get_position_force(angles,
radius=1.60 * AU,
force=23.37,
radius_offset=0.2 * AU,
force_offset=0.2)
for i, px in enumerate(pxs):
py, fx, fy = pys[i], fxs[i], fys[i]
asteroids.append(Asteroid(size_scale=1e9, # 小行星放大 1000000000 倍,距离保持不变
init_position=[px, py, 0],
init_velocity=[fx, fy, 0],
distance_scale=1.2))
bodies = [
Sun(size_scale=0.8e2), # 太阳放大 80 倍
Mercury(size_scale=4e3, distance_scale=1), # 水星放大 4000 倍,距离保持不变
Venus(size_scale=4e3, distance_scale=1), # 金星放大 4000 倍,距离保持不变
Earth(size_scale=4e3, distance_scale=1), # 地球放大 4000 倍,距离保持不变
Mars(size_scale=4e3, distance_scale=1), # 火星放大 4000 倍,距离保持不变
# Asteroid(size_scale=4e4, distance_scale=1), # 小行星放大 40000 倍,距离保持不变
Sun(size_scale=0.8e2), # 太阳放大 80 倍
Mercury(size_scale=4e3, distance_scale=1.1), # 水星放大 4000 倍,距离保持不变
Venus(size_scale=4e3, distance_scale=1.1), # 金星放大 4000 倍,距离保持不变
Earth(size_scale=4e3, distance_scale=1.1), # 地球放大 4000 倍,距离保持不变
Mars(size_scale=4e3, distance_scale=1.1), # 火星放大 4000 倍,距离保持不变
Jupiter(size_scale=0.8e3, distance_scale=0.5), # 木星放大 800 倍,距离缩小到真实距离的 0.5
Saturn(size_scale=0.8e3, distance_scale=0.38), # 土星放大 800 倍,距离缩小到真实距离的 0.38
Uranus(size_scale=0.8e3, distance_scale=0.26), # 天王星放大 800 倍,距离缩小到真实距离的 0.26
Neptune(size_scale=1e3, distance_scale=0.22), # 海王星放大 1000 倍,距离缩小到真实距离的 0.22
Pluto(size_scale=10e3, distance_scale=0.20), # 冥王星放大 10000 倍,距离缩小到真实距离的 0.2(从太阳系的行星中排除)
]
bodies += asteroids
# mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45)
mayavi_run(bodies, SECONDS_PER_WEEK, view_azimuth=-45, view_distance=3e9, view_focalpoint=[5e2, 5e2, 5e2])
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册