Не работает код для отрисовки трёхмерного куба Python
main.py
import pygame
from object_3d import *
from camera import *
from projection import *
class SoftwareRender:
def __init__(self):
pygame.init()
self.WIDTH, self.HEIGHT = 1200, 700
self.RES = self.WIDTH, self.HEIGHT
self.H_WIDTH, self.H_HEIGHT = self.WIDTH // 2, self.HEIGHT // 2
self.FPS = 60
self.screen = pygame.display.set_mode(self.RES)
self.clock = pygame.time.Clock()
self.create_objact()
def create_objact(self):
self.camera = Camera(self, [0.5, 1, -4])
self.projection = Projection(self)
self.objact = Objact3D(self)
self.objact.translate([0.2, 0.4, 0.2])
self.objact.rotate_y(math.pi/6)
def draw(self):
self.screen.fill(pygame.Color('darkslategray'))
self.objact.draw()
def run(self):
while True:
self.draw()
[exit() for i in pygame.event.get() if i.type == pygame.QUIT]
pygame.display.set_caption(str(self.clock.get_fps()))
pygame.display.flip()
self.clock.tick(self.FPS)
app = SoftwareRender()
app.run()
matrix.py
import math, numpy
def mx_translate(pos):
tx, ty, tz = pos
return numpy.array([
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[tx, ty, tz, 1]
])
def mx_rotate_x(a):
return numpy.array([
[1, 0, 0, 0],
[0, math.cos(a), math.sin(a), 0],
[0, -math.sin(a), math.cos(a), 0],
[0, 0, 0, 1]
])
def mx_rotate_y(a):
return numpy.array([
[math.cos(a), 0, -math.sin(a), 0],
[0, 1, 0, 0],
[math.sin(a), 0, math.cos(a), 0],
[0, 0, 0, 1]
])
def mx_rotate_z(a):
return numpy.array([
[math.cos(a), math.sin(a), 0, 0],
[-math.sin(a), math.cos(a), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
])
def mx_scale(n):
return numpy.array([
[n, 0, 0, 0],
[0, n, 0, 0],
[0, 0, n, 0],
[0, 0, 0, 1]
])
objact_3d.py
import math, numpy
def mx_translate(pos):
tx, ty, tz = pos
return numpy.array([
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[tx, ty, tz, 1]
])
def mx_rotate_x(a):
return numpy.array([
[1, 0, 0, 0],
[0, math.cos(a), math.sin(a), 0],
[0, -math.sin(a), math.cos(a), 0],
[0, 0, 0, 1]
])
def mx_rotate_y(a):
return numpy.array([
[math.cos(a), 0, -math.sin(a), 0],
[0, 1, 0, 0],
[math.sin(a), 0, math.cos(a), 0],
[0, 0, 0, 1]
])
def mx_rotate_z(a):
return numpy.array([
[math.cos(a), math.sin(a), 0, 0],
[-math.sin(a), math.cos(a), 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
])
def mx_scale(n):
return numpy.array([
[n, 0, 0, 0],
[0, n, 0, 0],
[0, 0, n, 0],
[0, 0, 0, 1]
])
camera.py
import pygame
from matrix import *
class Camera:
def __init__ (self, render, position):
self.render = render
self.position = numpy.array([*position, 1.0])
self.forward = numpy.array([0,0,1,1])
self.up = numpy.array([0,1,0,1])
self.right = numpy.array([1,0,0,1])
self.h_fov = math.pi/3
self.v_fov = self.h_fov * (render.HEIGHT / render.WIDTH)
self.near_plane = 0.1
self.far_plane = 100
def translate_matrix(self):
x, y, z, w = self.position
return numpy.array([
[1, 0, 0, 0,],
[0, 1, 0, 0,],
[0, 0, 1, 0,],
[-x, -y, -z, 1,]
])
def rotate_matrix(self):
rx, ry, rz, w = self.right
fx,fy, fz, w = self.forward
ux, uy, uz, w = self.up
return numpy.array([
[rx, ux, fx, 0],
[ry, uy, fy, 0],
[rz, uz, fz, 0],
[0, 0, 0, 1],
])
def camera_matrix(self):
return self.translate_matrix() @ self.rotate_matrix()
projection.py
import math, numpy
class Projection:
def __init__(self, render):
NEAR = render.camera.near_plane
FAR = render.camera.far_plane
RIGHT = math.tan(render.camera.h_fov / 2)
LEFT = -RIGHT
TOP = math.tan(render.camera.v_fov / 2)
BOTTOM = -TOP
m00 = 2 / (RIGHT - LEFT)
m11 = 2 / (TOP / BOTTOM)
m22 = (FAR + NEAR) / (FAR - NEAR)
m32 = -2 * NEAR * FAR / (FAR - NEAR)
self.projection_matrix = numpy.array([
[m00,0,0,0],
[0,m11,0,0],
[0,0,m22,0],
[0,0,m32,0],
])
HW, HH = render.H_WIDTH, render.H_HEIGHT
self.to_screen_matrix = numpy.array([
[HW, 0, 0, 0,],
[0, -HH, 0, 0,],
[0, 0, 1, 0,],
[HW, HH, 0, 1,],
])
Источник: Stack Overflow на русском