找回密码
 中文实名注册
搜索
查看: 16|回复: 0

正方体

[复制链接]

2

主题

5

回帖

169

积分

注册会员

积分
169
发表于 3 天前 | 显示全部楼层 |阅读模式
import pygame
import math

# 初始化 Pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pygame 3D Cube Demo")
clock = pygame.time.Clock()

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
ORANGE = (255, 165, 0)

# 3D 坐标点类
class Point3D:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

# 立方体的顶点 (中心在 0,0,0)
vertices = [
    Point3D(-1, -1, -1),
    Point3D( 1, -1, -1),
    Point3D( 1,  1, -1),
    Point3D(-1,  1, -1),
    Point3D(-1, -1,  1),
    Point3D( 1, -1,  1),
    Point3D( 1,  1,  1),
    Point3D(-1,  1,  1)
]

# 定义哪些点连接成边 (索引对应 vertices 列表)
edges = [
    (0, 1), (1, 2), (2, 3), (3, 0), # 后表面
    (4, 5), (5, 6), (6, 7), (7, 4), # 前表面
    (0, 4), (1, 5), (2, 6), (3, 7)  # 连接前后
]

def project(point, width, height, scale, angle_x, angle_y):
    """
    核心函数:将 3D 点投影到 2D 屏幕上
    包含旋转矩阵计算
    """
    x = point.x
    y = point.y
    z = point.z

    # 绕 X 轴旋转
    # y' = y*cos(a) - z*sin(a)
    # z' = y*sin(a) + z*cos(a)
    ry = y * math.cos(angle_x) - z * math.sin(angle_x)
    rz = y * math.sin(angle_x) + z * math.cos(angle_x)

    # 绕 Y 轴旋转 (使用上面旋转后的 z: rz)
    # x' = x*cos(a) + z*sin(a)
    # z' = -x*sin(a) + z*cos(a)
    rx = x * math.cos(angle_y) + rz * math.sin(angle_y)
    rz = -x * math.sin(angle_y) + rz * math.cos(angle_y)

    # 简单的透视投影 (z 越大,物体越小)
    # 这里的 4 是为了把物体推远一点,防止除以零
    f = 4
    z_factor = 1 / (f - rz)

    # 转换到屏幕坐标
    # 加上 width/2 和 height/2 是为了把原点移到屏幕中心
    px = int(rx * z_factor * scale + width / 2)
    py = int(ry * z_factor * scale + height / 2)

    return (px, py)

# 主循环变量
running = True
angle_x = 0
angle_y = 0
scale = 400  # 放大倍数

while running:
    clock.tick(60) # 限制 60 FPS
    screen.fill(BLACK) # 清屏

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 自动旋转
    angle_x += 0.01
    angle_y += 0.01

    # 计算所有投影后的 2D 点
    projected_points = []
    for v in vertices:
        p = project(v, WIDTH, HEIGHT, scale, angle_x, angle_y)
        projected_points.append(p)
        # 画出顶点(可选)
        pygame.draw.circle(screen, ORANGE, p, 5)

    # 画出边
    for edge in edges:
        p1 = projected_points[edge[0]]
        p2 = projected_points[edge[1]]
        pygame.draw.line(screen, WHITE, p1, p2, 2)

    pygame.display.update()

pygame.quit()

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表