This commit is contained in:
2024-04-09 17:24:02 +02:00
Unverified
parent 8f9ef3f4ff
commit 8766725953
8 changed files with 156 additions and 71 deletions

View File

@@ -1,82 +1,79 @@
import pygame import pygame as pg
import numpy as np import numpy as np
from math import * from math import *
import src.transformation_matrices as tm import src.constants as cn
import transformation as tm
from src.object_builder import ObjectBuilder
from src.object import Object
from src.camera import Camera
class App: class App:
clock: pygame.time.Clock clock: pg.time.Clock
screen: pygame.Surface screen: pg.Surface
scale: int camera: Camera
points: dict[str, np.matrix] objects = list[Object]
lines: list[str]
projection_matrix: np.matrix
angle_x: float
def __init__(self): def __init__(self):
self.clock = pygame.time.Clock() self.clock = pg.time.Clock()
self.screen = pygame.display.set_mode((1280, 720)) self.screen = pg.display.set_mode(cn.WINDOW_SIZE)
self.scale = 100 self.objects = []
self.angle = 0.05 self.camera = Camera(-5, 6, -55)
self.points = { self.create_objects()
"A": np.matrix([-1, -1, 1]),
"B": np.matrix([ 1, -1, 1]), def create_objects(self):
"C": np.matrix([ 1, 1, 1]), obj_builder = ObjectBuilder()
"D": np.matrix([-1, 1, 1]), va = obj_builder.add_vertex(-1, -1, 1)
"E": np.matrix([-1, -1, -1]), vb = obj_builder.add_vertex( 1, -1, 1)
"F": np.matrix([ 1, -1, -1]), vc = obj_builder.add_vertex( 1, 1, 1)
"G": np.matrix([ 1, 1, -1]), vd = obj_builder.add_vertex(-1, 1, 1)
"H": np.matrix([-1, 1, -1]), ve = obj_builder.add_vertex(-1, -1, -1)
} vf = obj_builder.add_vertex( 1, -1, -1)
self.lines = [ vg = obj_builder.add_vertex( 1, 1, -1)
"AB", vh = obj_builder.add_vertex(-1, 1, -1)
"AD", obj_builder.add_vertices_connection(va, vb)
"DC", obj_builder.add_vertices_connection(va, vd)
"BC", obj_builder.add_vertices_connection(vd, vc)
"EF", obj_builder.add_vertices_connection(vb, vc)
"EH", obj_builder.add_vertices_connection(ve, vf)
"HG", obj_builder.add_vertices_connection(ve, vh)
"FG", obj_builder.add_vertices_connection(vh, vg)
"AE", obj_builder.add_vertices_connection(vf, vg)
"BF", obj_builder.add_vertices_connection(va, ve)
"DH", obj_builder.add_vertices_connection(vb, vf)
"CG" obj_builder.add_vertices_connection(vd, vh)
] obj_builder.add_vertices_connection(vc, vg)
self.projection_matrix = np.matrix([ self.objects.append(obj_builder.build())
[1, 0, 0],
[0, 1, 0]
])
def main(self): def main(self):
self.setup() self.setup()
while True: while True:
self.clock.tick(60) self.clock.tick(cn.FPS)
for event in pygame.event.get(): for event in pg.event.get():
self.handle_event(event) self.handle_event(event)
self.update() self.update()
def handle_event(self, event: pygame.event.Event): def handle_event(self, event: pg.event.Event):
match event.type: match event.type:
case pygame.QUIT: case pg.QUIT:
self.quit() self.quit()
case pygame.KEYDOWN: case pg.KEYDOWN:
match event.key: match event.key:
case pygame.K_ESCAPE: case pg.K_ESCAPE:
self.quit() self.quit()
case pygame.K_s: case pg.K_s:
self.transform(tm.rotation_x(self.angle)) self.camera.move_backward()
case pygame.K_w: case pg.K_w:
self.transform(tm.rotation_x(-self.angle)) self.camera.move_forward()
case pygame.K_d: case pg.K_d:
self.transform(tm.rotation_y(self.angle)) self.camera.move_right()
case pygame.K_a: case pg.K_a:
self.transform(tm.rotation_y(-self.angle)) self.camera.move_left()
case pygame.K_q: case pg.K_SPACE:
self.transform(tm.rotation_z(self.angle)) self.camera.move_up()
case pygame.K_e: case pg.K_LSHIFT:
self.transform(tm.rotation_z(-self.angle)) self.camera.move_down()
def transform(self, transformation_matrix: np.matrix): def transform(self, transformation_matrix: np.matrix):
for key in self.points.keys(): for key in self.points.keys():
@@ -84,11 +81,20 @@ class App:
self.points[key] = np.dot(transformation_matrix, point.reshape((3,1))) self.points[key] = np.dot(transformation_matrix, point.reshape((3,1)))
def setup(self): def setup(self):
pygame.display.set_caption("Virtual camera") pg.display.set_caption("Virtual camera")
def update(self): def update(self):
self.screen.fill((255,255,255)) self.screen.fill((255,255,255))
for obj in self.objects:
obj.draw()
pg.display.update()
def quit(self):
pg.quit()
exit()
"""
projected_points = {} projected_points = {}
for point_key in self.points.keys(): for point_key in self.points.keys():
@@ -98,18 +104,12 @@ class App:
x = int(projected_2D[0][0] * self.scale) + (1280 / 2) x = int(projected_2D[0][0] * self.scale) + (1280 / 2)
y = int(projected_2D[1][0] * self.scale) + (720 / 2) y = int(projected_2D[1][0] * self.scale) + (720 / 2)
pygame.draw.circle(self.screen, (255, 0, 0), (x, y), 5) pg.draw.circle(self.screen, (255, 0, 0), (x, y), 5)
projected_points[point_key] = (x, y) projected_points[point_key] = (x, y)
for line in self.lines: for line in self.lines:
point_a = projected_points[line[0]] point_a = projected_points[line[0]]
point_b = projected_points[line[1]] point_b = projected_points[line[1]]
pygame.draw.line(self.screen, (0,0,0), point_a, point_b) pg.draw.line(self.screen, (0,0,0), point_a, point_b)
"""
pygame.display.update()
def quit(self):
pygame.quit()
exit()

30
src/camera.py Normal file
View File

@@ -0,0 +1,30 @@
import numpy as np
import transformation as tm
class Camera:
moving_speed: float
rotation_speed: float
position: np.ndarray[float]
def __init__(self, x: float, y: int, z: int):
self.moving_speed = 0.3
self.rotation_speed = 0.015
self.position = np.array([x, y, z, 1.0])
def move_forward(self):
self.position += tm.forward_array * self.moving_speed
def move_backward(self):
self.position -= tm.forward_array * self.moving_speed
def move_right(self):
self.position += tm.right_array * self.moving_speed
def move_left(self):
self.position -= tm.right_array * self.moving_speed
def move_up(self):
self.position += tm.up_array * self.moving_speed
def move_down(self):
self.position -= tm.up_array * self.moving_speed

5
src/constants.py Normal file
View File

@@ -0,0 +1,5 @@
WINDOW_SIZE = (1280, 720)
FPS = 60
SCALE = 100
ANGLE = 0.05

12
src/object.py Normal file
View File

@@ -0,0 +1,12 @@
from vertex import Vertex
class Object:
vertices: list[Vertex]
lines = list[(Vertex, Vertex)]
def __init__(self, vertices: list[Vertex], lines: list[(Vertex, Vertex)]):
self.vertices = vertices
self.lines = lines
def draw():
pass

20
src/object_builder.py Normal file
View File

@@ -0,0 +1,20 @@
from object import Object
from vertex import Vertex
class ObjectBuilder:
vertices: list[Vertex]
lines: list[(Vertex, Vertex)]
def __init__(self):
self.vertices = []
def add_vertex(self, x: int, y: int, z: int) -> Vertex:
v = Vertex(x, y, z)
self.vertices.append(v)
return v
def add_vertices_connection(self, vertex1: Vertex, vertex2: Vertex):
self.lines.append((vertex1, vertex2))
def build(self) -> Object:
pass

View File

@@ -18,3 +18,7 @@ rotation_z = lambda angle: np.matrix([
[sin(angle), cos(angle), 0], [sin(angle), cos(angle), 0],
[0, 0, 1], [0, 0, 1],
]) ])
forward_array = np.array([0, 0, 1, 1])
up_array = np.array([0, 1, 0, 1])
right_array = np.array([1, 0, 0, 1])

14
src/vertex.py Normal file
View File

@@ -0,0 +1,14 @@
import numpy as np
class Vertex:
x: int
y: int
z: int
def __init__(self, x: int, y: int, z: int):
self.x = x
self.y = y
self.z = z
def to_matrix(self) -> np.matrix:
return np.matrix([self.x, self.y, self.z])