Python 旋转立方体的实现示例
效果图
运行环境
python版本:python3.x
依赖包:
$ pip install pygame $ pip install numpy
完整代码
import numpy as np # 导入 NumPy 库,用于数值计算和处理多维数组 import pygame # 导入 Pygame 库,用于游戏开发和图形界面设计 # 定义屏幕的宽度和高度 WIDTH = 800 HEIGHT = 800 # 定义颜色常量 BLACK = (0, 0, 0) # 黑色 WHITE = (255, 255, 255) # 白色 class Cube: """ 表示一个立方体。 """ def __init__(self, pos: np.ndarray, a: float) -> None: """ 初始化立方体。 :param pos: 立方体的中心位置,是一个包含三个元素的 NumPy 数组。 :param a: 立方体的边长。 """ self.pos = pos # 立方体的中心位置 self.angle = np.pi / 4 # 立方体的旋转角度,初始化为 45 度 self.center_offset = np.array([-a / 2, -a / 2, -a / 2]) # 立方体顶点到中心的偏移量 self.edges = np.array([ # 立方体的边,是一个包含 12 条边的数组 # 前脸的四条边 np.array([np.array([0, 0, 0]), np.array([a, 0, 0])]), np.array([np.array([a, 0, 0]), np.array([a, a, 0])]), np.array([np.array([a, a, 0]), np.array([0, a, 0])]), np.array([np.array([0, a, 0]), np.array([0, 0, 0])]), # 右脸的四条边 np.array([np.array([0, 0, 0]), np.array([0, 0, a])]), np.array([np.array([a, a, 0]), np.array([a, a, a])]), np.array([np.array([a, 0, 0]), np.array([a, 0, a])]), np.array([np.array([0, a, 0]), np.array([0, a, a])]), # 上脸的四条边 np.array([np.array([0, 0, a]), np.array([a, 0, a])]), np.array([np.array([a, 0, a]), np.array([a, a, a])]), np.array([np.array([a, a, a]), np.array([0, a, a])]), np.array([np.array([0, a, a]), np.array([0, 0, a])]), ]) def draw(self, screen: pygame.surface.Surface, rotation_rate: float) -> None: """ 在屏幕上绘制立方体。 :param screen: 要绘制立方体的 Pygame 屏幕对象。 :param rotation_rate: 立方体的旋转速率,用于控制立方体旋转的速度。 """ # 将立方体的边加上中心偏移量,得到实际的顶点位置 rotated_cube = np.add(self.edges, self.center_offset) # 计算绕 X、Y、Z 轴旋转的矩阵 rotation_matrix_x = np.array([ [1, 0, 0], [0, np.cos(self.angle), -np.sin(self.angle)], [0, np.sin(self.angle), np.cos(self.angle)] ]) rotation_matrix_y = np.array([ [np.cos(self.angle), 0, np.sin(self.angle)], [0, 1, 0], [-np.sin(self.angle), 0, np.cos(self.angle)] ]) rotation_matrix_z = np.array([ [np.cos(self.angle), -np.sin(self.angle), 0], [np.sin(self.angle), np.cos(self.angle), 0], [0, 0, 1], ]) # 对立方体进行旋转 rotated_cube = np.matmul(rotated_cube, rotation_matrix_x) rotated_cube = np.matmul(rotated_cube, rotation_matrix_y) rotated_cube = np.matmul(rotated_cube, rotation_matrix_z) # 将旋转后的立方体移动到正确的位置 moved_cube = np.add(self.pos, rotated_cube) # 在屏幕上绘制立方体的边 for edge in moved_cube: # 获取边的两个端点的屏幕坐标 start_pos = edge[0][0:2] end_pos = edge[1][0:2] # 绘制边 pygame.draw.line(screen, WHITE, start_pos, end_pos) # 更新立方体的旋转角度 self.angle += rotation_rate def main(): """ 主函数,启动 Pygame 并创建旋转的立方体。 """ # 初始化 Pygame pygame.init() # 创建屏幕对象 screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口标题 pygame.display.set_caption("旋转立方体 By stormsha") # 创建立方体对象,中心位于 (400, 400, 200),边长为 200 cube = Cube(np.array([400, 400, 200]), 200) # 主循环 running = True while running: # 处理 Pygame 事件,如关闭窗口等 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 清空屏幕 screen.fill(BLACK) # 绘制立方体 cube.draw(screen, 0.001) # 更新屏幕 pygame.display.flip() if __name__ == "__main__": # 如果脚本被直接运行,则执行主函数 main()
实现思路
使用Pygame和NumPy创建旋转立方体
在这篇文章中,我们将详细介绍如何使用Python的Pygame库和NumPy库创建一个旋转的立方体。我们将逐步讲解代码的实现思路,并解释关键部分的作用。
1. 导入库和定义常量
首先,我们需要导入所需的库,包括NumPy和Pygame。NumPy库用于数值计算和处理多维数组,而Pygame库用于游戏开发和图形界面设计。
import numpy as np # 导入 NumPy 库,用于数值计算和处理多维数组 import pygame # 导入 Pygame 库,用于游戏开发和图形界面设计 # 定义屏幕的宽度和高度 WIDTH = 800 HEIGHT = 800 # 定义颜色常量 BLACK = (0, 0, 0) # 黑色 WHITE = (255, 255, 255) # 白色
2. 创建Cube类
接下来,我们创建一个名为Cube的类,用于表示立方体。在Cube类的构造函数中,我们初始化立方体的中心位置、旋转角度和边长。
class Cube: """ 表示一个立方体。 """ def __init__(self, pos: np.ndarray, a: float) -> None: """ 初始化立方体。 :param pos: 立方体的中心位置,是一个包含三个元素的 NumPy 数组。 :param a: 立方体的边长。 """ self.pos = pos # 立方体的中心位置 self.angle = np.pi / 4 # 立方体的旋转角度,初始化为 45 度 self.center_offset = np.array([-a / 2, -a / 2, -a / 2]) # 立方体顶点到中心的偏移量 self.edges = np.array([ # 立方体的边,是一个包含 12 条边的数组 # 前脸的四条边 np.array([np.array([0, 0, 0]), np.array([a, 0, 0])]), np.array([np.array([a, 0, 0]), np.array([a, a, 0])]), np.array([np.array([a, a, 0]), np.array([0, a, 0])]), np.array([np.array([0, a, 0]), np.array([0, 0, 0])]), # 右脸的四条边 np.array([np.array([0, 0, 0]), np.array([0, 0, a])]), np.array([np.array([a, a, 0]), np.array([a, a, a])]), np.array([np.array([a, 0, 0]), np.array([a, 0, a])]), np.array([np.array([0, a, 0]), np.array([0, a, a])]), # 上脸的四条边 np.array([np.array([0, 0, a]), np.array([a, 0, a])]), np.array([np.array([a, 0, a]), np.array([a, a, a])]), np.array([np.array([a, a, a]), np.array([0, a, a])]), np.array([np.array([0, a, a]), np.array([0, 0, a])]), ])
在上面的代码中,我们定义了立方体的12条边,包括前脸、右脸和上脸的边。每条边由两个顶点组成,使用NumPy的数组表示。
3. 实现Cube类的draw方法
接下来,我们实现Cube类的draw方法,用于在屏幕上绘制立方体。在draw方法中,我们首先将立方体的边加上中心偏移量,得到实际的顶点位置。然后,我们计算绕X、Y、Z轴旋转的矩阵,并对立方体进行旋转。最后,我们将旋转后的立方体移动到正确的位置,并在屏幕上绘制立方体的边。
def draw(self, screen: pygame.surface.Surface, rotation_rate: float) -> None: """ 在屏幕上绘制立方体。 :param screen: 要绘制立方体的 Pygame 屏幕对象。 :param rotation_rate: 立方体的旋转速率,用于控制立方体旋转的速度。 """ # 将立方体的边加上中心偏移量,得到实际的顶点位置 rotated_cube = np.add(self.edges, self.center_offset) # 计算绕 X、Y、Z 轴旋转的矩阵 rotation_matrix_x = np.array([ [1, 0, 0], [0, np.cos(self.angle), -np.sin(self.angle)], [0, np.sin(self.angle), np.cos(self.angle)] ]) rotation_matrix_y = np.array([ [np.cos(self.angle), 0, np.sin(self.angle)], [0, 1, 0], [-np.sin(self.angle), 0, np.cos(self.angle)] ]) rotation_matrix_z = np.array([ [np.cos(self.angle), -np.sin(self.angle), 0], [np.sin(self.angle), np.cos(self.angle), 0], [0, 0, 1], ]) # 对立方体进行旋转 rotated_cube = np.matmul(rotated_cube, rotation_matrix_x) rotated_cube = np.matmul(rotated_cube, rotation_matrix_y) rotated_cube = np.matmul(rotated_cube, rotation_matrix_z) # 将旋转后的立方体移动到正确的位置 moved_cube = np.add(self.pos, rotated_cube) # 在屏幕上绘制立方体的边 for edge in moved_cube: # 获取边的两个端点的屏幕坐标 start_pos = edge[0][0:2] end_pos = edge[1][0:2] # 绘制边 pygame.draw.line(screen, WHITE, start_pos, end_pos) # 更新立方体的旋转角度 self.angle += rotation_rate
在上面的代码中,我们使用NumPy的matmul函数进行矩阵乘法,以实现立方体的旋转。然后,我们使用pygame的draw.line函数在屏幕上绘制立方体的边。
4. 实现主函数
最后,我们实现主函数main,用于启动Pygame并创建旋转的立方体。在主函数中,我们首先初始化Pygame,并创建屏幕对象。然后,我们创建一个Cube对象,并进入主循环。在主循环中,我们处理Pygame事件,清空屏幕,绘制立方体,并更新屏幕。
def main(): """ 主函数,启动 Pygame 并创建旋转的立方体。 """ # 初始化 Pygame pygame.init() # 创建屏幕对象 screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口标题 pygame.display.set_caption("旋转立方体 By stormsha") # 创建立方体对象,中心位于 (400, 400, 200),边长为 200 cube = Cube(np.array([400, 400, 200]), 200) # 主循环 running = True while running: # 处理 Pygame 事件,如关闭窗口等 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 清空屏幕 screen.fill(BLACK) # 绘制立方体 cube.draw(screen, 0.001) # 更新屏幕 pygame.display.flip() if __name__ == "__main__": # 如果脚本被直接运行,则执行主函数 main()
在上面的代码中,我们使用pygame的event.get函数获取事件,并判断是否为关闭窗口事件。如果是关闭窗口事件,则退出主循环。然后,我们使用screen.fill函数清空屏幕,并使用cube.draw函数绘制立方体。最后,我们使用pygame的display.flip函数更新屏幕。
到此这篇关于Python 旋转立方体的实现示例的文章就介绍到这了,更多相关Python 旋转立方体内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
python3 cookbook解压可迭代对象赋值给多个变量的问题及解决方案
这篇文章主要介绍了python3 cookbook-解压可迭代对象赋值给多个变量,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2024-01-01Anaconda下配置python+opencv+contribx的实例讲解
今天小编就为大家分享一篇Anaconda下配置python+opencv+contribx的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2018-08-08Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
这篇文章主要介绍了Pycharm使用远程linux服务器conda/python环境在本地运行的方法,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-12-12
最新评论