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

Python超人-宇宙模拟器

上级 deeab155
...@@ -33,3 +33,6 @@ from bodies.fixed_stars.uy_scuti import UYScuti ...@@ -33,3 +33,6 @@ from bodies.fixed_stars.uy_scuti import UYScuti
from bodies.fixed_stars.eta_carinae import EtaCarinae from bodies.fixed_stars.eta_carinae import EtaCarinae
from bodies.fixed_stars.y_canum_venaticorum import YCanumVenaticorum from bodies.fixed_stars.y_canum_venaticorum import YCanumVenaticorum
from bodies.fixed_stars.carinae_v382 import CarinaeV382 from bodies.fixed_stars.carinae_v382 import CarinaeV382
#
from bodies.color_body import ColorBody
...@@ -86,6 +86,11 @@ class Body(metaclass=ABCMeta): ...@@ -86,6 +86,11 @@ class Body(metaclass=ABCMeta):
self.show_name = show_name self.show_name = show_name
self.resolution = None self.resolution = None
self.light_disable = False
def set_light_disable(self, value):
self.light_disable = value
return self
def set_resolution(self, value): def set_resolution(self, value):
self.resolution = value self.resolution = value
......
# -*- coding:utf-8 -*-
# title :颜色天体
# description :颜色天体
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from bodies.body import Body
from common.consts import MO
from common.image_utils import gen_color_body_texture, find_texture_root_path
import os
import random
class ColorBody(Body):
"""
颜色天体基类
"""
def __init__(self, name="颜色天体", mass=1 * MO,
init_position=[0, 0, 0],
init_velocity=[0, 0, 0],
color=(0xFF, 0xFF, 0xFF),
texture=None, size_scale=1.0, distance_scale=1.0,
rotation_speed=None, ignore_mass=False, density=5e3, trail_color=None,
texture_bright=None, texture_contrast=None, show_name=False):
self.color = color
texture = self.gen_texture(texture, texture_bright, texture_contrast)
if rotation_speed is None:
rotation_speed = random.randint(10, 100) / 50
params = {
"name": name,
"mass": mass,
"init_position": init_position,
"init_velocity": init_velocity,
"density": density,
"color": color,
"texture": texture,
"size_scale": size_scale,
"distance_scale": distance_scale,
"rotation_speed": rotation_speed,
"ignore_mass": ignore_mass,
"trail_color": trail_color,
"show_name": show_name
}
super().__init__(**params)
def gen_texture(self, texture, texture_bright, texture_contrast):
if texture is None:
return None
texture_path = find_texture_root_path()
if texture_path is None:
err_msg = "未找到纹理图片目录"
raise Exception(err_msg)
temp_dir = os.path.join(texture_path, "temp")
if not os.path.exists(temp_dir):
os.mkdir(temp_dir)
texture_name = os.path.basename(texture). \
replace(".", "_").replace("/", "_"). \
replace("\\", "_").replace("__", "_")
save_file = os.path.join(temp_dir, "%s_%s.png" % (texture_name, "_".join([str(i) for i in list(self.color)])))
if os.path.exists(save_file):
return save_file
body_img = os.path.join(texture_path, texture)
gen_color_body_texture(self.color,
bright=texture_bright,
contrast=texture_contrast,
save_file=save_file,
color_body_img=body_img)
return save_file
if __name__ == '__main__':
print(ColorBody())
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# title :天狼 # title :
# description :天狼 # description :
# author :Python超人 # author :Python超人
# date :2023-02-11 # date :2023-02-11
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
...@@ -49,6 +49,7 @@ class FixedStar(Body): ...@@ -49,6 +49,7 @@ class FixedStar(Body):
"show_name": show_name "show_name": show_name
} }
super().__init__(**params) super().__init__(**params)
# 恒星属性
self.light_on = True self.light_on = True
self.glows = (12, 1.009, 0.08) self.glows = (12, 1.009, 0.08)
...@@ -59,9 +60,15 @@ class FixedStar(Body): ...@@ -59,9 +60,15 @@ class FixedStar(Body):
if texture_path is None: if texture_path is None:
err_msg = "未找到纹理图片目录" err_msg = "未找到纹理图片目录"
raise Exception(err_msg) raise Exception(err_msg)
save_file = os.path.join(texture_path, "fixed_star_%s.png" % str(self.__class__.__name__).lower())
temp_dir = os.path.join(texture_path, "temp")
if not os.path.exists(temp_dir):
os.mkdir(temp_dir)
save_file = os.path.join(temp_dir, "fixed_star_%s.png" % str(self.__class__.__name__).lower())
if os.path.exists(save_file): if os.path.exists(save_file):
return save_file return save_file
fixed_star_img = os.path.join(texture_path, texture) fixed_star_img = os.path.join(texture_path, texture)
gen_fixed_star_texture(self.color, gen_fixed_star_texture(self.color,
bright=texture_bright, bright=texture_bright,
......
...@@ -194,6 +194,21 @@ def find_texture(texture): ...@@ -194,6 +194,21 @@ def find_texture(texture):
return "" return ""
def gen_color_body_texture(color, save_file, color_body_img="color_body.jpg", bright=None, contrast=None):
bright = 1 if bright is None else bright
contrast = 1 if contrast is None else contrast
color_body_img = find_texture(color_body_img)
if color_body_img is None:
err_msg = "未找到纹理图片:" % color_body_img
raise Exception(err_msg)
trans_img = trans_png(color_body_img)
bg_img = create_image(trans_img.width, trans_img.height, color)
mixed = mix(bg_img, trans_img)
mixed = image_enhance(mixed, bright=bright, contrast=contrast)
mixed.save(save_file, 'PNG')
return mixed
def gen_fixed_star_texture(color, save_file, fixed_star_img="fixed_star.png", bright=None, contrast=None): def gen_fixed_star_texture(color, save_file, fixed_star_img="fixed_star.png", bright=None, contrast=None):
bright = 1.1 if bright is None else bright bright = 1.1 if bright is None else bright
contrast = 3.2 if contrast is None else contrast contrast = 3.2 if contrast is None else contrast
...@@ -250,7 +265,7 @@ if __name__ == '__main__': ...@@ -250,7 +265,7 @@ if __name__ == '__main__':
# mono = gray_to_mono(gray_img, (0, 0, 255)).show() # mono = gray_to_mono(gray_img, (0, 0, 255)).show()
# image_enhance(mono,bright=1,contrast=2).show() # image_enhance(mono,bright=1,contrast=2).show()
gen_fixed_star_texture((198, 29, 3), "xxx.png",bright=2.2,contrast=3).show() gen_fixed_star_texture((198, 29, 3), "xxx.png", bright=2.2, contrast=3).show()
# fixed_star_img = find_texture("sun.png") # fixed_star_img = find_texture("sun.png")
# colorize_color(fixed_star_img,(0,0xff,0xff)).show() # colorize_color(fixed_star_img,(0,0xff,0xff)).show()
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
from bodies import Sun, Earth, Moon, FixedStar, Body from bodies import Sun, Earth, Moon, FixedStar, ColorBody
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK from common.consts import SECONDS_PER_HOUR, SECONDS_PER_HALF_DAY, SECONDS_PER_DAY, SECONDS_PER_WEEK
from sim_scenes.func import mayavi_run, ursina_run from sim_scenes.func import mayavi_run, ursina_run
from bodies.body import AU from bodies.body import AU
...@@ -18,30 +18,22 @@ def show_text_bodies(): ...@@ -18,30 +18,22 @@ def show_text_bodies():
""" """
显示文本的星球群 显示文本的星球群
""" """
D = 600 D = 6000
mass = 0.5e25
# camera_pos = 左-右+、上+下-、前+后- # camera_pos = 左-右+、上+下-、前+后-
camera_pos = (-100 * D, 0, -5000 * D) camera_pos = (-130 * D, 0, -6000 * D)
def get_position(pos, scale): bodies: list = gen_bodies_from_image(pixel_image="./images/python.png", texture="color_body.jpg",
# [ 远+近- , 左+右- , 上+下-] params={"camera_pos": camera_pos})
return pos[0] + (scale - 1.0) * 200 * (random.randint(90, 110)) * D, pos[1], pos[2] bg = FixedStar(name="bg", texture="fixed_star.png", mass=5e31, color=(0xff, 0xf8, 0xd4),
# return pos[0], pos[1], pos[2] init_position=[3000 * D, 260 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-]
ignore_mass=True)
bodies: list = gen_bodies_from_image(pixel_image="./images/python.png", bg.light_on = True
params={"D": D, "Body": Body, "mass": mass, bodies.append(bg)
"get_position": get_position,
"camera_pos": camera_pos})
face = FixedStar(name="bg", texture="fixed_star.png", mass=mass * 9000, color=(0xff, 0xf8, 0xd4),
init_position=[2000 * D, 260 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-]
ignore_mass=True)
face.light_on = False
bodies.append(face)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos) ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos, view_closely=True)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -17,29 +17,22 @@ def show_eye_of_god(): ...@@ -17,29 +17,22 @@ def show_eye_of_god():
""" """
上帝之眼 上帝之眼
""" """
D = 600 D = 6000
mass = 0.9e25
# camera_pos = 左-右+、上+下-、前+后- # camera_pos = 左-右+、上+下-、前+后-
camera_pos = (-100 * D, 0, -5000 * D) camera_pos = (-100 * D, 0, -6000 * D)
def get_position(pos, scale):
# [ 远+近- , 左+右- , 上+下-]
return pos[0] + (scale - 1.0) * 300 * (random.randint(90, 110)) * D, pos[1], pos[2]
# return pos[0], pos[1], pos[2]
bodies: list = gen_bodies_from_image(pixel_image="./images/eye.png", bodies: list = gen_bodies_from_image(pixel_image="./images/eye.png",
params={"D": D, "Body": Body, "mass": mass, params={"camera_pos": camera_pos})
"get_position": get_position, "camera_pos": camera_pos}) bg = FixedStar(name="bg", texture="fixed_star.png", mass=5e31, color=(0xff, 0xf8, 0xd4),
face = FixedStar(name="face", texture="fixed_star.png", mass=mass * 3000, color=(0xff, 0xf8, 0xd4), init_position=[3000 * D, 200 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-]
init_position=[2000 * D, 200 * D, 100 * D], # [ 远+近- , 左+右- , 上+下-] ignore_mass=True)
ignore_mass=True) # bg.light_on = False
face.light_on = False bodies.append(bg)
bodies.append(face)
# 使用 ursina 查看的运行效果 # 使用 ursina 查看的运行效果
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos) ursina_run(bodies, SECONDS_PER_WEEK * 2, position=camera_pos, view_closely=True)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -6,24 +6,38 @@ ...@@ -6,24 +6,38 @@
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.8 # python_version :3.8
# ============================================================================== # ==============================================================================
from bodies import ColorBody
import random
from PIL import Image
def gen_bodies_from_image(pixel_image, params, body_template=None):
def gen_bodies_from_image(pixel_image, params, texture="color_body.png"):
""" """
根据像素图片以及参数,自动生成星球,注意图片像素不能太多,否则会导致电脑运行太慢 根据像素图片以及参数,自动生成星球,注意图片像素不能太多,否则会导致电脑运行太慢
@param pixel_image: @param pixel_image:
@param params: @param params:
@return: @return:
""" """
from PIL import Image D = 6000
mass = 0.9e25
def get_position(pos, scale):
# [ 远+近- , 左+右- , 上+下-]
return pos[0] + (scale - 1.0) * 300 * (random.randint(90, 110)) * D, pos[1], pos[2]
# return pos[0], pos[1], pos[2]
params["ColorBody"] = ColorBody
params["get_position"] = get_position
params["mass"] = mass
params["D"] = D
img = Image.open(pixel_image).convert('RGBA') img = Image.open(pixel_image).convert('RGBA')
width, height = img.size width, height = img.size
interval_factor = 20 # 星球间距因子 interval_factor = 20 # 星球间距因子
if body_template is None: body_template = 'ColorBody(name="%s", mass=mass, color=(%d, %d, %d), size_scale=%.4f, ' \
body_template = 'Body(name="%s", mass=mass, color=(%d, %d, %d), size_scale=%.4f, ' \ 'init_position=get_position([0, %g * D, %g * D], %.4f), ' \
'init_position=get_position([0, %g * D, %g * D], %.4f), ' \ f'init_velocity=[0, 0, 0], ignore_mass=True, texture="{texture}").set_light_disable(True)'
'init_velocity=[0, 0, 0], ignore_mass=True)'
bodies_str = "[" bodies_str = "["
# 以图片像素为坐标,对角线的距离 # 以图片像素为坐标,对角线的距离
...@@ -44,7 +58,7 @@ def gen_bodies_from_image(pixel_image, params, body_template=None): ...@@ -44,7 +58,7 @@ def gen_bodies_from_image(pixel_image, params, body_template=None):
# 对于纯白色的颜色,就忽略,不生成星球(这样图片中,纯白色越多,对电脑的压力就越小) # 对于纯白色的颜色,就忽略,不生成星球(这样图片中,纯白色越多,对电脑的压力就越小)
if pixel[0] >= 255 and pixel[1] >= 255 and pixel[1] >= 255: if pixel[0] >= 255 and pixel[1] >= 255 and pixel[1] >= 255:
continue continue
body_str = body_template % (f"星球{w}:{h}", pixel[0], pixel[1], pixel[2], scale, body_str = body_template % (f"星球{w}:{h}", pixel[0], pixel[1], pixel[2], scale * 10,
(width - w) * interval_factor, (height - h) * interval_factor, scale) (width - w) * interval_factor, (height - h) * interval_factor, scale)
bodies_str += body_str + ",\n" bodies_str += body_str + ",\n"
......
...@@ -36,6 +36,26 @@ class ControlHandler(EventHandler): ...@@ -36,6 +36,26 @@ class ControlHandler(EventHandler):
key_info = Text(text=key_info_str, font=UrsinaConfig.CN_FONT, position=(-1, 0.5), origin=(-1, 1), key_info = Text(text=key_info_str, font=UrsinaConfig.CN_FONT, position=(-1, 0.5), origin=(-1, 1),
background=True) background=True)
self.camera_info = Text(text="", scale=0.8, position=(0, -0.45), origin=(0, 1),
background=True)
def camera_update(self):
pos = camera.position # WS => [2]
w_pos = camera.world_rotation # 鼠标右键
# rot = camera.rotation
wt = camera.world_transform # QE[0,1,2] AD [0 , 2] 鼠标右键
# print(camera.world_transform)
# print(camera.origin, camera.world_transform)
# LVector3f(-1, 0, 0) Vec3(0, 0, 1) LVector3f(0, 0, -1) Vec3(1, 0, 0) Vec3(1, 1, 1) 1.7777777910232544 LVector3f(0, -1, 0) Vec3(0, 1, 0) Vec3(1, 1, 1) Vec3(0, 0, 0)
# print(camera.left,camera.forward,camera.back,camera.right,camera.scale,camera.aspect_ratio,camera.down,camera.up,camera.world_scale,camera.world_rotation)
# fw = camera.forward
# self.camera_info.text = "pos:[%.2f,%.2f,%.2f] w_pos:[%.2f,%.2f,%.2f] rot:[%.2f,%.2f,%.2f] wt:[%s,%s,%s]" % \
self.camera_info.text = "pos:[%.2f,%.2f,%.2f] w_pos:[%.2f,%.2f,%.2f] wt:[%s,%s]" % \
(pos[0], pos[1], pos[2],
w_pos[0], w_pos[1], w_pos[2],
# rot[0], rot[1], rot[2],
wt[0], wt[1]) # , wt[2]
def sec_per_time_switch_changed(self): def sec_per_time_switch_changed(self):
""" """
按钮组("默认", "天", "周", "月", "年", "十年", "百年") 点击 按钮组("默认", "天", "周", "月", "年", "十年", "百年") 点击
...@@ -195,6 +215,9 @@ class ControlHandler(EventHandler): ...@@ -195,6 +215,9 @@ class ControlHandler(EventHandler):
@return: @return:
""" """
import sys import sys
self.camera_update()
if key == "escape": if key == "escape":
sys.exit() sys.exit()
# print(key) # print(key)
...@@ -230,7 +253,7 @@ class ControlHandler(EventHandler): ...@@ -230,7 +253,7 @@ class ControlHandler(EventHandler):
import math import math
# min=0.01, max=20 # min=0.01, max=20
# # ', up' < > '. up' n m # # ', up' < > '. up' n m
self.ui.slider_control_speed_factor.current_step = self.ui.slider_control_speed_factor.value/2 self.ui.slider_control_speed_factor.current_step = self.ui.slider_control_speed_factor.value / 2
self.slider_decrease(self.ui.slider_control_speed_factor, self.ui.slider_control_speed_factor.current_step) self.slider_decrease(self.ui.slider_control_speed_factor, self.ui.slider_control_speed_factor.current_step)
print(self.ui.slider_control_speed_factor.current_step) print(self.ui.slider_control_speed_factor.current_step)
......
...@@ -130,18 +130,21 @@ class Planet(Entity): ...@@ -130,18 +130,21 @@ class Planet(Entity):
double_sided=True double_sided=True
) )
if hasattr(self.body_view.body, "torus_stars") or \ if hasattr(self.body_view.body, "torus_stars"):
hasattr(self.body_view.body, "light_disable"):
# 星环小天体群(主要模拟小行星群,非一个天体) # 星环小天体群(主要模拟小行星群,非一个天体)
# 或者灯光禁用
self.set_light_off() self.set_light_off()
self.double_sided = True self.double_sided = True
else: else:
# 一个天体 # 一个天体
# 拖尾球体的初始化 # 拖尾球体的初始化
self.trail_init() self.trail_init()
if self.body_view.body.is_fixed_star:
self.create_fixed_star_lights() if self.body_view.body.is_fixed_star:
# 如果是恒星,开启恒星的发光的效果、并作为灯光源
self.create_fixed_star_lights()
elif self.body_view.body.light_disable:
# 如果是非恒星,并且禁用灯光
self.set_light_off()
if self.body_view.body.show_name: if self.body_view.body.show_name:
self.create_name_text() self.create_name_text()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册