如何在负坐标的 3D 立方体上添加翻译?

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

我有一个带负坐标的立方体矩阵

self.cube_coords = np.array([
    [-1, -1, -1], [-1, 1, -1], [1, 1, -1], [1, -1, -1],
    [-1, -1, 1], [-1, 1, 1], [1, 1, 1], [1, -1, 1]
    ])

所以,当我尝试通过乘法矩阵来翻译他时,负坐标破坏了一切......

我怎样才能消除这个缺点,使其不影响其他转换?

代码:

import pygame as pg
import math
import numpy as np
from moves import *

pg.init()

'''====================SETTINGS===================='''
WIDTH, HEIGHT = 1500, 1000                  # Screen size
DIS = pg.display.set_mode((WIDTH, HEIGHT))
pg.display.set_caption("3D Cube")           # Name of 'game'

'''Colors'''
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)

FPS = 60

CUBE_TRANSLATION_SPEED = 0.02
CUBE_ROTATE_SPEED = 0.015
CUBE_SIZE = 200

'''====================NON CHANGE===================='''

'''3d to 2d matrix'''
projection_matrix = np.array([
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 0]
])                                      

class Cube:
    def __init__(self):
        # [x, y, z]
        
        # self.cube_coords = np.array([ 
        #     [0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0],
        #     [0, 0, 1], [0, 1, 1], [1, 1, 1], [1, 0, 1]
        # ])                    If rotate around 1 dot
        
        self.cube_coords = np.array([
            [-1, -1, -1], [-1, 1, -1], [1, 1, -1], [1, -1, -1],
            [-1, -1, 1], [-1, 1, 1], [1, 1, 1], [1, -1, 1]
        ])                      #If rotate around cube center
        
        self.cube_lines = np.array([
            [0, 1], [1, 2], [2, 3], [3, 0],
            [4, 5], [5, 6], [6, 7], [7, 4],
            [0, 4], [1, 5], [2, 6], [3, 7]
        ])
        
        self.translxy = [0, 0]       # Movement coords
        self.anglex = 0
        self.angley = 0
        self.anglez = 0
        self.scalec = 1
        
        '''Moves matrices'''
        self.transl_matrix = translation(self.translxy)
        self.rotatex = rotate_x(self.anglez)
        self.rotatey = rotate_y(self.anglez)
        self.rotatez = rotate_z(self.anglez)
        self.scale_matrix = scale(self.scalec)
    
    def transl(self, keys):
        if keys[pg.K_UP]:
            self.translxy[1] -= CUBE_TRANSLATION_SPEED
        if keys[pg.K_DOWN]:
            self.translxy[1] += CUBE_TRANSLATION_SPEED
        if keys[pg.K_LEFT]:
            self.translxy[0] -= CUBE_TRANSLATION_SPEED
        if keys[pg.K_RIGHT]:
            self.translxy[0] += CUBE_TRANSLATION_SPEED
            
        self.transl_matrix = translation(self.translxy)
    
    def rotate(self, keys):
        if keys[pg.K_s]:
            self.anglex += CUBE_ROTATE_SPEED
            self.rotatex = rotate_x(self.anglex)
        if keys[pg.K_w]:
            self.anglex -= CUBE_ROTATE_SPEED
            self.rotatex = rotate_x(self.anglex)
            
        if keys[pg.K_a]:
            self.angley += CUBE_ROTATE_SPEED
            self.rotatey = rotate_y(self.angley)
        if keys[pg.K_d]:
            self.angley -= CUBE_ROTATE_SPEED
            self.rotatey = rotate_y(self.angley)
            
        if keys[pg.K_q]:
            self.anglez += CUBE_ROTATE_SPEED
            self.rotatez = rotate_z(self.anglez)
        if keys[pg.K_e]:
            self.anglez -= CUBE_ROTATE_SPEED
            self.rotatez = rotate_z(self.anglez)
        
    def scale_cube(self, keys):
        if keys[pg.K_z]:
            self.scalec /= 1.02
            self.scale_matrix = scale(self.scalec)
        if keys[pg.K_x]:
            self.scalec *= 1.02
            self.scale_matrix = scale(self.scalec)
        
    def mutation(self):
        '''3D cube coords change and 3D => 2D'''
        transform_matrix = self.scale_matrix @ self.rotatez @ self.rotatey @ self.rotatex @ self.transl_matrix
        project_dots = []
        for i in self.cube_coords:
            transformed_point = i @ transform_matrix
            project_dots.append(transformed_point)
        return project_dots
    
    def draw(self, line_size: int | float, col, X, Y, project_dots):
        for i in project_dots:
            x = int(i[0] * line_size + X)
            y = int(i[1] * line_size + Y)
            pg.draw.circle(DIS, col, (x, y), 5)

        for i in self.cube_lines:
            x1, y1 = project_dots[i[0]][0] * line_size + X, project_dots[i[0]][1] * line_size + Y
            x2, y2 = project_dots[i[1]][0] * line_size + X, project_dots[i[1]][1] * line_size + Y
            pg.draw.line(DIS, col, (x1, y1), (x2, y2))         
    
def main():
    run = True
    clock = pg.time.Clock()
    cube = Cube()
    while run:
        clock.tick(FPS)
        DIS.fill(BLACK)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False
        keys = pg.key.get_pressed()
        cube.transl(keys)
        cube.rotate(keys)
        cube.scale_cube(keys)
        project_dots = cube.mutation()
        cube.draw(CUBE_SIZE, WHITE, WIDTH/2, HEIGHT/2, project_dots)
        pg.display.update()
    
    pg.quit()

if __name__ == "__main__":
    main()

移动模块:

import numpy as np
from math import sin, cos

def translation(coords):
    dx, dy = coords
    return np.array([
        [1, 0, 0],
        [0, 1, 0],
        [dx, dy, 1]
    ])

def rotate_x(a):
    return np.array([
        [1, 0, 0],
        [0, cos(a), -sin(a)],
        [0, sin(a), cos(a)]
    ])
    
def rotate_y(a):
    return np.array([
        [cos(a), 0, sin(a)],
        [0, 1, 0],
        [-sin(a), 0, cos(a)]
    ])

def rotate_z(a):
    return np.array([
        [cos(a), -sin(a), 0],
        [sin(a), cos(a), 0],
        [0, 0, 1]
    ])
    
def scale(k):
    return np.array([
        [k, 0, 0],
        [0, k, 0],
        [0, 0, 1]
    ])

谢谢!

python pygame 3d translation
© www.soinside.com 2019 - 2024. All rights reserved.