我有一个带负坐标的立方体矩阵
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]
])
谢谢!