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

太阳系三体模拟器

上级 322ec9a2
...@@ -32,4 +32,4 @@ if __name__ == '__main__': ...@@ -32,4 +32,4 @@ if __name__ == '__main__':
# mayavi_run(bodies, SECONDS_PER_HALF_DAY / 2, view_azimuth=-45) # mayavi_run(bodies, SECONDS_PER_HALF_DAY / 2, view_azimuth=-45)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
ursina_run(bodies, SECONDS_PER_WEEK, position=(0, 0, 0)) ursina_run(bodies, SECONDS_PER_DAY, position=(0, 0, 0))
...@@ -102,8 +102,9 @@ class UrsinaSimulator(Simulator): ...@@ -102,8 +102,9 @@ class UrsinaSimulator(Simulator):
# 创建一个新的 Entity 对象,作为光晕的容器 # 创建一个新的 Entity 对象,作为光晕的容器
# glow_entity = Entity(parent=entity, model='sphere', scale=entity.scale * 1.2) # glow_entity = Entity(parent=entity, model='sphere', scale=entity.scale * 1.2)
# 创建 PointLight 对象,并设置它的属性 # 创建 PointLight 对象,并设置它的属性
light = PointLight(parent=lights[0], intensity=intensity, color=light_color, attenuation=attenuation) for i in range(2):
lights.append(light) light = PointLight(parent=lights[0], intensity=intensity, color=light_color, attenuation=attenuation)
lights.append(light)
# 把 Entity 对象放到星星的后面,使得光晕看起来像是从星星发出来的 # 把 Entity 对象放到星星的后面,使得光晕看起来像是从星星发出来的
glow_entity.world_position = entity.world_position glow_entity.world_position = entity.world_position
...@@ -134,9 +135,10 @@ class UrsinaSimulator(Simulator): ...@@ -134,9 +135,10 @@ class UrsinaSimulator(Simulator):
scale=math.pow(1.03, i), alpha=0.1) scale=math.pow(1.03, i), alpha=0.1)
lights.append(glow_entity) lights.append(glow_entity)
# 创建 PointLight 对象,作为恒星的灯光源 for i in range(2):
light = PointLight(parent=entity, intensity=10, range=10, color=color.white) # 创建 PointLight 对象,作为恒星的灯光源
lights.append(light) light = PointLight(parent=entity, intensity=10, range=10, color=color.white)
lights.append(light)
# light = DirectionalLight(shadows=True, direction=Vec3(0, 0, 1), color=color.white) # light = DirectionalLight(shadows=True, direction=Vec3(0, 0, 1), color=color.white)
# light.look_at(Vec3(0, 0, -1)) # light.look_at(Vec3(0, 0, -1))
......
...@@ -25,7 +25,7 @@ import math ...@@ -25,7 +25,7 @@ import math
SCALE_FACTOR = 5e-7 SCALE_FACTOR = 5e-7
# 旋转因子为1,则为正常的转速 # 旋转因子为1,则为正常的转速
ROTATION_SPEED_FACTOR = 1.0 ROTATION_SPEED_FACTOR = 1.0
# ROTATION_SPEED_FACTOR = 0.1 ROTATION_SPEED_FACTOR = 0.01
class UrsinaPlayer(FirstPersonController): class UrsinaPlayer(FirstPersonController):
...@@ -74,6 +74,82 @@ class UrsinaPlayer(FirstPersonController): ...@@ -74,6 +74,82 @@ class UrsinaPlayer(FirstPersonController):
return super().input(key) return super().input(key)
from math import pi, sin, cos
# def create_sphere(radius, subdivisions):
# # 生成球体的顶点、UV坐标、法线和三角面
# # radius = 1
# # subdivisions = 16
# theta = np.linspace(0, 2 * np.pi, subdivisions + 1)
# phi = np.linspace(0, np.pi, subdivisions + 1)
# u = np.linspace(0, 1, subdivisions + 1)
# v = np.linspace(0, 1, subdivisions + 1)
# verts = []
# uvs = []
# normals = []
# for i in range(len(theta)):
# for j in range(len(phi)):
# x = radius * np.sin(phi[j]) * np.cos(theta[i])
# y = radius * np.sin(phi[j]) * np.sin(theta[i])
# z = radius * np.cos(phi[j])
# verts.append((x, y, z))
# uvs.append((u[i], v[j]))
# normals.append((x / radius, y / radius, z / radius))
#
# tris = []
# for i in range(len(theta)):
# for j in range(len(phi)):
# a = i * (subdivisions + 1) + j
# b = (i + 1) * (subdivisions + 1) + j
# tris.append((a, b, a + 1))
# tris.append((a + 1, b, b + 1))
#
# # # 反转面法线
# # for i in range(len(tris)):
# # a, b, c = tris[i]
# # tris[i] = (c, b, a)
# # normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c])
# # normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c])
#
# # 创建球体 Mesh 对象并设置材质
# sphere_mesh = Mesh(vertices=verts, uvs=uvs, normals=normals, triangles=tris, mode='triangle')
# return sphere_mesh
def create_sphere(radius, subdivisions):
verts = []
tris = []
normals = []
uvs = []
for y in range(subdivisions + 1):
for x in range(subdivisions + 1):
x_segment = x / subdivisions
y_segment = y / subdivisions
x_pos = cos(x_segment * 2 * pi) * sin(y_segment * pi)
y_pos = cos(y_segment * pi)
z_pos = sin(x_segment * 2 * pi) * sin(y_segment * pi)
verts.append(Vec3(x_pos, y_pos, z_pos) * radius)
uvs.append(Vec2(x_segment, y_segment))
normals.append(Vec3(x_pos, y_pos, z_pos))
for y in range(subdivisions):
for x in range(subdivisions):
first = (y * (subdivisions + 1)) + x
second = first + subdivisions + 1
tris.append((first, second + 1, second))
tris.append((first, first + 1, second + 1))
# 反转面法线
for i in range(len(tris)):
a, b, c = tris[i]
tris[i] = (c, b, a)
# normals[a], normals[b], normals[c] = -Vec3(*normals[a]), -Vec3(*normals[b]), -Vec3(*normals[c])
return Mesh(vertices=verts, triangles=tris, normals=normals, uvs=uvs, mode='triangle')
class Planet(Entity): class Planet(Entity):
def __init__(self, body_view: BodyView): def __init__(self, body_view: BodyView):
self.body_view = body_view self.body_view = body_view
...@@ -84,13 +160,16 @@ class Planet(Entity): ...@@ -84,13 +160,16 @@ class Planet(Entity):
pos = body_view.position * body_view.body.distance_scale * SCALE_FACTOR pos = body_view.position * body_view.body.distance_scale * SCALE_FACTOR
scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR scale = body_view.body.diameter * body_view.body.size_scale * SCALE_FACTOR
subdivisions = 32 # int(scale*20)
if hasattr(body_view, "texture"): if hasattr(body_view, "texture"):
texture = load_texture(body_view.texture) texture = load_texture(body_view.texture)
else: else:
texture = None texture = None
super().__init__( super().__init__(
model="sphere", # model="sphere",
model=create_sphere(0.5, subdivisions),
scale=scale, scale=scale,
texture=texture, texture=texture,
color=color.white, color=color.white,
...@@ -113,7 +192,7 @@ class Planet(Entity): ...@@ -113,7 +192,7 @@ class Planet(Entity):
# self.rotspeed = 30000 / self.body_view.raduis # random.uniform(1.0, 2.0) # self.rotspeed = 30000 / self.body_view.raduis # random.uniform(1.0, 2.0)
else: else:
# 是通过月球保持一面面对地球,调整得到 # 是通过月球保持一面面对地球,调整得到
self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR # / 60 / 24 self.rotspeed = self.rotation_speed * (dt / 3600) / 2.4 * ROTATION_SPEED_FACTOR # / 60 / 24
# rotation_speed 度/小时 dt 秒 = (dt / 3600)小时 # rotation_speed 度/小时 dt 秒 = (dt / 3600)小时
self.rotation_y -= self.rotspeed self.rotation_y -= self.rotspeed
...@@ -142,7 +221,7 @@ class UrsinaView(BodyView): ...@@ -142,7 +221,7 @@ class UrsinaView(BodyView):
:return: :return:
""" """
# 行星环偏移角度 # 行星环偏移角度
self.ring_rotation_x = 70 self.ring_rotation_x = 75
# 创建行星环 # 创建行星环
self.ring = Entity(parent=self.planet, model="circle", texture='../textures/saturnRings.jpg', scale=2, self.ring = Entity(parent=self.planet, model="circle", texture='../textures/saturnRings.jpg', scale=2,
rotation=(self.ring_rotation_x, 0, 0), double_sided=True) rotation=(self.ring_rotation_x, 0, 0), double_sided=True)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册