我目前正处于用Python 3构建交互式元素周期表程序的规划阶段。这不会是一个超级高级的程序,因为我只是Python 3的初学者(4-5个月的自我训练) ).
基本上,当您单击元素周期表中的某个元素时,您将更详细地查看其属性,并且将获得我在 Blender 中创建的动画原子(电子围绕其旋转)的动态 3D 视图。 这里是我刚刚为视觉爱好者制作的一个简单模型(这里缺少很多东西,但这只是基本的外壳)。
好的,所以我的问题是:如何在 Python 3 中与 3D 对象交互?我进行了搜索,发现 PyGame 可以处理这个问题,但似乎它不是处理 3D 图形的最佳选择,而且我不确定 PyGame 是否适合此类程序。当然,有 vpython,但它不适用于 Python 3。那么我该如何做到这一点呢?
请记住,我是初学者,因此您认为可以帮助我的任何资源将不胜感激!
谢谢大家。
PyOpenGL 提供低级接口来显示 3D 对象。 PyOpenGL 可以与 PyQt 或 PyGame 一起使用,在 2D GUI 中实现 3D 显示。
编辑:Windows 上还有一个适用于 32 位 python 3.1 的 vpython 版本
Glass Engine可以帮助您在PyQt程序中添加交互式3D视口。例如,使用Glass Engine绘制氦原子:
from glass_engine import *
from glass_engine.Geometries import *
from PyQt6.QtCore import QTimer
import math
scene, camera, light = ModelView()
light.generate_shadows = False
# calculate nucleon positions
sqrt_6 = math.sqrt(6)
sqrt_2 = math.sqrt(2)
sqrt_3 = math.sqrt(3)
nucleon_positions = \
[
0.1*glm.normalize(glm.vec3( 2/3*sqrt_2, 0, -1/3)), # 0
0.1*glm.normalize(glm.vec3( -sqrt_2/3, sqrt_6/3, -1/3)), # 1
0.1*glm.normalize(glm.vec3( -sqrt_2/3, -sqrt_6/3, -1/3)), # 2
0.1*glm.normalize(glm.vec3( 0, 0, 1)), # 3
]
# assemble He atom
He_atom = SceneNode()
# add two protons
proton1 = Sphere(radius=0.1, color=10*glm.vec3( 0.77, 0.38, 0 ))
proton1.material.shading_model = None
proton1.position = nucleon_positions[0]
He_atom.add_child(proton1)
proton2 = Sphere(radius=0.1, color=10*glm.vec3( 0.77, 0.38, 0 ))
proton2.material.shading_model = None
proton2.position = nucleon_positions[1]
He_atom.add_child(proton2)
# add two neutrons
neutron1 = Sphere(radius=0.1, color=glm.vec3( 0.71, 0.77, 0.89 ))
neutron1.position = nucleon_positions[2]
He_atom.add_child(neutron1)
neutron2 = Sphere(radius=0.1, color=glm.vec3( 0.71, 0.77, 0.89 ))
neutron2.position = nucleon_positions[3]
He_atom.add_child(neutron2)
# add two electrons
electron = Sphere(radius=0.05, color=10*glm.vec3(0.4, 0.7, 0.7))
electron.material.shading_model = None
electron.position.x = 1
electron_orbit = Circle(radius=1, color=10*glm.vec3(0.4, 0.7, 0.7), line_width=1)
electron_orbit.material.shading_model = None
electron1_base_node = SceneNode()
electron1_base_node.roll = -45
electron1_base_node.add_child(electron_orbit)
electron1_node = SceneNode()
electron1_base_node.add_child(electron1_node)
electron1_node.add_child(electron)
He_atom.add_child(electron1_base_node)
electron2_base_node = SceneNode()
electron2_base_node.roll = -135
electron2_base_node.add_child(electron_orbit)
electron2_node = SceneNode()
electron2_base_node.add_child(electron2_node)
electron2_node.add_child(electron)
He_atom.add_child(electron2_base_node)
scene.add(He_atom)
def electron_rotate():
electron1_node.yaw += 2
electron2_node.yaw -= 2
camera.screen.update()
timer = QTimer()
timer.timeout.connect(electron_rotate)
timer.start(20)
camera.screen.bloom = True
camera.screen.FXAA = True
camera.screen.show()
在代码中,
camera.screen
只是一个PyQt的QWidget,你可以将它布局在程序中的任何位置。
查看 Glass Engine 的完整文档https://glass-engine-doc.readthedocs.io/zh/latest