3D 投影:移动相机而不是物体

问题描述 投票:0回答:1

我正在学习 3D 透视投影和 python 中的矩阵。我对基础知识有很好的理解,但我不明白我将如何使用移动对象的代码并应用转换使其成为第一人称,像相机一样的运动(我自己的理解,类似我的世界)。这是我的代码,我从 https://github.com/Josephbakulikira/3D-perspective-projection-with-python- 中获取并修改了它。我似乎找不到关于这种类型的任何信息转换,直接用矩阵完成。如果有人有任何示例或可以解释如何在此代码中实现它,我将不胜感激!我从例子中学到最好的工作。

目前,我所知道的就是围绕它自己的轴旋转对象。

import pygame
import os
import math
from matrix import matrix_multiplication

os.environ["SDL_VIDEO_CENTERED"]='1'
black, white, blue  = (20, 20, 20), (230, 230, 230), (0, 154, 255)
width, height = 640, 480

pygame.init()
pygame.display.set_caption("3D cube Projection")
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
fps = 60

Xangle = 0
Yangle = 0
Zangle = 0
cube_position = [width//2, height//2]
scale = 600
speed = 0.01
points = [n for n in range(8)]

points[0] = [[-1], [-1], [1]]
points[1] = [[1], [-1], [1]]
points[2] = [[1], [1], [1]]
points[3] = [[-1], [1], [1]]
points[4] = [[-1], [-1], [-1]]
points[5] = [[1], [-1], [-1]]
points[6] = [[1], [1], [-1]]
points[7] = [[-1], [1], [-1]]


def connect_point(i, j, k):
    a = k[i]
    b = k[j]
    pygame.draw.line(screen, black, (a[0], a[1]), (b[0], b[1]), 2)

run = True
while run:
    clock.tick(fps)
    screen.fill(white)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        Yangle += speed
    if keys[pygame.K_RIGHT]:
        Yangle -= speed
    if keys[pygame.K_UP]:
        Xangle += speed
    if keys[pygame.K_DOWN]:
        Xangle -= speed
    if keys[pygame.K_p]:
        Zangle += speed
    if keys[pygame.K_o]:
        Zangle -= speed
    if keys[pygame.K_r]:
        Yangle = 0
        Xangle = 0
        Zangle = 0


    index = 0
    projected_points = [j for j in range(len(points))]

    rotation_x = [[1, 0, 0],
                  [0, math.cos(Xangle), -math.sin(Xangle)],
                  [0, math.sin(Xangle), math.cos(Xangle)]]

    rotation_y = [[math.cos(Yangle), 0, -math.sin(Yangle)],
                  [0, 1, 0],
                  [math.sin(Yangle), 0, math.cos(Yangle)]]

    rotation_z = [[math.cos(Zangle), -math.sin(Zangle), 0],
                  [math.sin(Zangle), math.cos(Zangle), 0],
                  [0, 0 ,1]]

    for point in points:
        rotated_2d = matrix_multiplication(rotation_y, point)
        rotated_2d = matrix_multiplication(rotation_x, rotated_2d)
        rotated_2d = matrix_multiplication(rotation_z, rotated_2d)
        distance = 5
        z = 1/(distance - rotated_2d[2][0])
        projection_matrix = [[z, 0, 0],
                            [0, z, 0]]
        projected_2d = matrix_multiplication(projection_matrix, rotated_2d)

        x = int(projected_2d[0][0] * scale) + cube_position[0]
        y = int(projected_2d[1][0] * scale) + cube_position[1]
        projected_points[index] = [x, y]
        pygame.draw.circle(screen, blue, (x, y), 10)
        index += 1
    #draw edges
    for m in range(4):
        connect_point(m, (m+1)%4, projected_points)
        connect_point(m+4, (m+1)%4 + 4, projected_points)
        connect_point(m, m+4, projected_points)

    #Xangle += speed
    #Yangle += speed
    #Zangle += speed
    pygame.display.update()

pygame.quit()
python pygame 3d projection perspectivecamera
1个回答
1
投票

仅移动相机意味着物体的移动方向与您想要移动相机的方向相反。定义一个相机位置并计算物体相对于这个相机位置的位置:

camera_pos = [0, 0, 0]
rotated_2[0][0] += camera_pos[0]
rotated_2[0][1] -= camera_pos[1]
rotated_2[0][2] -= camera_pos[2]

当你改变相机位置时,物体会移动。对于第一人称视角的移动,您必须始终相对于观察方向移动相机。相机旋转是指以相反的方向旋转对象并围绕对象循环移动相机位置。所以你的问题只是找到相机的合适位置。

另见PyGame 做 3d 吗?Pygame 绕轴旋转立方体近距离 3d 显示混乱

© www.soinside.com 2019 - 2024. All rights reserved.