From 3c2cd002e41e342780469fb8447f8c27c7251bfd Mon Sep 17 00:00:00 2001 From: march3 Date: Sun, 2 Apr 2023 12:11:35 +0800 Subject: [PATCH] =?UTF-8?q?create=5Farrow=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bodies/body.py | 4 +- bodies/earth.py | 3 +- simulators/ursina/entities/body_trail.py | 61 ++++++------ simulators/ursina/ursina_mesh.py | 118 ++++++++++++++++++++++- simulators/ursina_simulator.py | 18 ++-- 5 files changed, 160 insertions(+), 44 deletions(-) diff --git a/bodies/body.py b/bodies/body.py index dccd38c..ce0b4eb 100644 --- a/bodies/body.py +++ b/bodies/body.py @@ -19,7 +19,7 @@ class Body(metaclass=ABCMeta): 天体基类 """ - def __init__(self, name, mass, init_position, init_velocity, + def __init__(self, name, mass, init_position, init_velocity, rotate_angle=0, density=5e3, color=(125 / 255, 125 / 255, 125 / 255), texture=None, size_scale=1.0, distance_scale=1.0, rotation_speed=None, parent=None, ignore_mass=False, @@ -60,6 +60,8 @@ class Body(metaclass=ABCMeta): self.init_position = np.array(init_position, dtype='float32') self.init_velocity = np.array(init_velocity, dtype='float32') + self.rotate_angle = rotate_angle + # self.__position = copy.deepcopy(self.init_position) # self.__velocity = copy.deepcopy(self.init_velocity) diff --git a/bodies/earth.py b/bodies/earth.py index b847252..0ab341a 100644 --- a/bodies/earth.py +++ b/bodies/earth.py @@ -23,7 +23,7 @@ class Earth(Body):  平均密度: 5507.85 kg/m³ """ - def __init__(self, name="地球", mass=5.97237e24, + def __init__(self, name="地球", mass=5.97237e24,rotate_angle=0, init_position=[1.12 * AU, 0, 0], init_velocity=[0, 29.79, 0], texture="earth1.jpg", size_scale=1.0, distance_scale=1.0, @@ -33,6 +33,7 @@ class Earth(Body): "mass": mass, "init_position": init_position, "init_velocity": init_velocity, + "rotate_angle": rotate_angle, "density": 5507.85, "color": (7, 0, 162), "texture": texture, diff --git a/simulators/ursina/entities/body_trail.py b/simulators/ursina/entities/body_trail.py index ee74053..ae803b5 100644 --- a/simulators/ursina/entities/body_trail.py +++ b/simulators/ursina/entities/body_trail.py @@ -10,6 +10,7 @@ from ursina import Entity, Mesh, Text, color, destroy, Vec3 from simulators.ursina.ursina_config import UrsinaConfig +from simulators.ursina.ursina_mesh import create_arrow_line class BodyTrail(Entity): @@ -44,51 +45,55 @@ class BodyTrail(Entity): # "acceleration": [acc_info, acc_direction, acc_position]} vel_info, vel_direction, vel_position = self.entity_infos["velocity"] acc_info, acc_direction, acc_position = self.entity_infos["acceleration"] - - verts_acc = [(0, 0, 0), tuple(acc_direction)] - verts_vel = [(0, 0, 0), tuple(vel_direction)] + # + # verts_acc = [(0, 0, 0), tuple(acc_direction)] + # verts_vel = [(0, 0, 0), tuple(vel_direction)] # acc_arrow = Arrow(parent=self,from_pos=Vec3((0, 0, 0)), to_pos=Vec3(tuple(acc_direction)),color=color.yellow, alpha=0.5) # acc_arrow.set_light_off() - - acc_line = Entity(parent=self, model=Mesh(vertices=verts_acc, mode='line', thickness=3), - color=color.yellow, alpha=0.5) - acc_line.set_light_off() - - # vel_arrow = Arrow(parent=self,from_pos=Vec3((0, 0, 0)), to_pos=Vec3(tuple(vel_direction)),color=color.red, alpha=0.5) - # vel_arrow.set_light_off() - vel_line = Entity(parent=self, model=Mesh(vertices=verts_vel, mode='line', thickness=3), - color=color.red, alpha=0.5) - vel_line.set_light_off() - - vel_text = Text(vel_info, scale=50, billboard=True, parent=self, - font=UrsinaConfig.CN_FONT, background=False, color=color.red, - position=vel_position, alpha=0.5) - vel_text.set_light_off() - - acc_text = Text(acc_info, scale=50, billboard=True, parent=self, - font=UrsinaConfig.CN_FONT, background=False, color=color.yellow, - position=acc_position, alpha=0.5) - acc_text.set_light_off() + v_arrow, v_line, v_text = create_arrow_line((0, 0, 0), tuple(vel_direction), parent=self, + label=vel_info, color=color.red, alpha=0.8, arrow_scale=0.5) + a_arrow, a_line, a_text = create_arrow_line((0, 0, 0), tuple(acc_direction), parent=self, + label=acc_info, color=color.yellow, alpha=0.8, arrow_scale=0.5) + # acc_line = Entity(parent=self, model=Mesh(vertices=verts_acc, mode='line', thickness=3), + # color=color.yellow, alpha=0.5) + # acc_line.set_light_off() + # + # # vel_arrow = Arrow(parent=self,from_pos=Vec3((0, 0, 0)), to_pos=Vec3(tuple(vel_direction)),color=color.red, alpha=0.5) + # # vel_arrow.set_light_off() + # + # vel_line = Entity(parent=self, model=Mesh(vertices=verts_vel, mode='line', thickness=3), + # color=color.red, alpha=0.5) + # vel_line.set_light_off() + # + # vel_text = Text(vel_info, scale=50, billboard=True, parent=self, + # font=UrsinaConfig.CN_FONT, background=False, color=color.red, + # position=vel_position, alpha=0.5) + # vel_text.set_light_off() + # + # acc_text = Text(acc_info, scale=50, billboard=True, parent=self, + # font=UrsinaConfig.CN_FONT, background=False, color=color.yellow, + # position=acc_position, alpha=0.5) + # acc_text.set_light_off() class Arrow(Entity): def __init__(self, parent, from_pos=(0, 0, 0), to_pos=(1, 0, 0), **kwargs): - from_pos=to_pos/2 + from_pos = to_pos / 2 super().__init__(parent=parent, model='arrow', position=from_pos, **kwargs) # self.x = -pos[1] # self.y = pos[2] # self.z = pos[0] - to_pos=1000*to_pos + to_pos = 1000 * to_pos # to_pos = -to_pos[2],-to_pos[1],to_pos[0] # to_pos = -to_pos[2],-to_pos[0],to_pos[1] # to_pos = to_pos[0],to_pos[2],to_pos[1] # to_pos = -to_pos[0],to_pos[1],to_pos[2] # to_pos = to_pos[1], -to_pos[0], -to_pos[2] # to_pos = to_pos[1], -to_pos[0], -to_pos[2] - self.rotation=(0,0,0) + self.rotation = (0, 0, 0) self.look_at(to_pos) print(self.rotation) # self.model = Mesh(vertices=[ @@ -104,7 +109,6 @@ class Arrow(Entity): # self.look_at(to_pos) # self.scale_z = (to_pos - from_pos).length() - # class Arrow(Entity): # def __init__(self,parent, from_pos, to_pos, **kwargs): # super().__init__(parent=parent, model='arrow', **kwargs) @@ -112,7 +116,6 @@ class Arrow(Entity): # self.look_at(to_pos) - # import numpy as np # def draw_arrow(parent, from_pos, to_pos, color, alpha): # # 计算方向向量和长度 @@ -129,4 +132,4 @@ class Arrow(Entity): # arrow.position = arrow_position # arrow.look_at(p2) # -# return arrow \ No newline at end of file +# return arrow diff --git a/simulators/ursina/ursina_mesh.py b/simulators/ursina/ursina_mesh.py index 9df81df..41c1010 100644 --- a/simulators/ursina/ursina_mesh.py +++ b/simulators/ursina/ursina_mesh.py @@ -7,11 +7,13 @@ # python_version :3.8 # ============================================================================== # pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina -from ursina import Ursina, window, Entity, Mesh, EditorCamera, color, mouse, Vec2, Vec3, load_texture, Texture +from ursina import Ursina, window, Entity, Mesh, EditorCamera, color, mouse, Vec2, Vec3, load_texture, Texture, Text from math import pi, sin, cos import numpy as np import math +from simulators.ursina.ursina_config import UrsinaConfig + def create_sphere(radius, subdivisions): """ @@ -61,6 +63,105 @@ def create_sphere(radius, subdivisions): return Mesh(vertices=verts, triangles=tris, normals=normals, uvs=uvs, mode='triangle') +def create_arrow(height=0.5, width=0.1): + # 创建金字塔的顶点 + r = width / 2 + verts = [ + (0, height, 0), # 顶点 + (-r, 0, -r), # 左后底点 + (r, 0, -r), # 右后底点 + (r, 0, r), # 右前底点 + (-r, 0, r), # 左前底点 + ] + # 修改指向 + verts = [(z, x, y) for x, y, z in verts] + + # 定义金字塔的面 + faces = [ + (0, 1, 2), # 底面1 + (0, 2, 3), # 底面2 + (0, 3, 4), # 底面3 + (0, 4, 1), # 底面4 + (4, 2, 1), # 侧面1 + (4, 3, 2), # 侧面1 + ] + + # 创建一个金字塔的Mesh对象 + arrow_mesh = Mesh(vertices=verts, triangles=faces, mode='triangle') + return arrow_mesh + + +def create_arrow_line(from_pos, to_pos, parent=None, label=None, + set_light_off=True, alpha=1.0, + color=color.white, thickness=2, + arrow_scale=1, text_scale=50): + """ + 创建箭头和箭头线段 + @param from_pos: 箭头线段开始位置 + @param to_pos: 箭头线段结束位置 + @param parent: + @param label: 箭头显示的文字 + @param set_light_off: 是否设置为灯光关闭状态 + @param alpha: 透明度 + @param color: 箭头线颜色 + @param thickness: 线段粗细 + @param arrow_scale: 箭头缩放 + @return: + """ + height = 0.5 * thickness + width = 0.1 * thickness + arrow_mesh = create_arrow(height, width) + verts = (Vec3(from_pos), Vec3(to_pos)) + line = Entity(parent=parent, model=Mesh(vertices=verts, mode='line', thickness=thickness), + color=color, alpha=alpha) + arrow = Entity(parent=line, model=arrow_mesh, position=verts[1], + scale=thickness * arrow_scale, color=color, alpha=alpha) + arrow.look_at(Vec3(to_pos) * 100) + + if set_light_off: + line.set_light_off() + arrow.set_light_off() + + if label is not None: + text = Text(label, parent=line, scale=text_scale, billboard=True, color=color, + position=Vec3(to_pos) + Vec3(1, 1, 1), alpha=alpha, + font=UrsinaConfig.CN_FONT, background=False) + if set_light_off: + text.set_light_off() + else: + text = None + + return arrow, line, text + + +def create_pyramid(): + # 创建金字塔的顶点 + verts = [ + (0, 2, 0), # 顶点 + (-1, 0, -1), # 左后底点 + (1, 0, -1), # 右后底点 + (1, 0, 1), # 右前底点 + (-1, 0, 1), # 左前底点 + ] + + # 定义金字塔的面 + faces = [ + (0, 1, 2), # 底面1 + (0, 2, 3), # 底面2 + (0, 3, 4), # 底面3 + (0, 4, 1), # 底面4 + (4, 2, 1), # 侧面1 + (4, 3, 2), # 侧面1 + ] + + # 创建一个金字塔的Mesh对象 + # verts = [(0, 1, 0), (1, 0, 1), (1, 0, -1), (-1, 0, -1), (-1, 0, 1)] + # faces = [(0, 1, 2), (0, 2, 3), (0, 3, 4), (0, 4, 1), (1, 3, 2)] + pyramid_mesh = Mesh(vertices=verts, triangles=faces, mode='triangle') + + return pyramid_mesh + + def create_body_torus(inner_radius, outer_radius, subdivisions): vertices = [] uvs = [] @@ -195,9 +296,18 @@ if __name__ == '__main__': # torus = create_torus(1.5, 3, 64) # entity = Entity(model=torus, texture=textureRings, rotation=(85, 0, 0), double_sided=True) - body_torus = create_torus(9, 10, 64) - entities = Entity(model=body_torus, texture=textureAsteroids, rotation=(85, 0, 0), double_sided=True) - entities.set_light_off() + # body_torus = create_torus(9, 10, 64) + # entities = Entity(model=body_torus, texture=textureAsteroids, rotation=(85, 0, 0), double_sided=True) + # entities.set_light_off() + + # 创建金字塔的实体对象 + # pyramid = Entity(model=create_pyramid(), texture='brick', color=color.yellow) + # pyramid.set_light_off() + + # arrow = Entity(model=create_arrow(), color=color.yellow) + # arrow.set_light_off() + + arrow, line = create_arrow_line((0, 0, 0), (10, 0, 0)) EditorCamera() app.run() diff --git a/simulators/ursina_simulator.py b/simulators/ursina_simulator.py index a11bc88..9fd1fd3 100644 --- a/simulators/ursina_simulator.py +++ b/simulators/ursina_simulator.py @@ -15,6 +15,7 @@ from simulators.ursina.ursina_event import UrsinaEvent # from simulators.ursina.ursina_ui import UrsinaUI from simulators.ursina.ui.control_ui import ControlUI from simulators.ursina.ui.control_handler import ControlHandler +from simulators.ursina.ursina_mesh import create_arrow_line from simulators.views.ursina_view import UrsinaView from simulators.ursina.entities.ursina_player import UrsinaPlayer @@ -35,6 +36,12 @@ class WorldGrid(Entity): 创建一个宇宙网格对象 """ + def draw_axises(self): + # 坐标轴 + arrow_x, line_x, text_x = create_arrow_line((0, 0, 0), (10, 0, 0), label="X", color=color.red) + arrow_y, line_y, text_y = create_arrow_line((0, 0, 0), (0, 10, 0), label="Y", color=color.green) + arrow_z, line_z, text_z = create_arrow_line((0, 0, 0), (0, 0, 10), label="Z", color=color.yellow) + def __init__(self): super().__init__() s = 100 @@ -42,15 +49,8 @@ class WorldGrid(Entity): position=(0, -80, 0)) grid.set_light_off() - # 坐标轴 - # vertsx = ((0, 0, 0), (10, 0, 0)) - # Entity(model=Mesh(vertices=vertsx, mode='line', thickness=3), color=color.red).set_light_off() - # - # vertsy = [(0, 0, 0), (0, 10, 0)] - # Entity(model=Mesh(vertices=vertsy, mode='line', thickness=3), color=color.green).set_light_off() - # - # vertsz = [(0, 0, 0), (0, 0, 10)] - # Entity(model=Mesh(vertices=vertsz, mode='line', thickness=3), color=color.blue).set_light_off() + # self.draw_axises() + class UrsinaSimulator(Simulator): """ -- GitLab