Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- from enum import IntEnum
- import numpy as np
- import pygame
- from OpenGL.GL import *
- from OpenGL.GLU import *
- from pygame.locals import *
- os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % (-1920, 0)
- class Axis(IntEnum):
- X = 0
- Y = 1
- Z = 2
- W = 3
- class Tesseract:
- def __init__(self, vertices: np.array, edges: list, faces: list, colors: np.array):
- self.vertices = vertices
- self.edges = edges
- self.faces = faces
- self.colors = colors
- self.angle = 0
- self.vertices_4d = vertices
- self.vertices_3d = None
- def _4d_rotation(self, axis: int, other_axis: int) -> np.array:
- c = np.cos(self.angle)
- s = np.sin(self.angle)
- matrix = np.identity(4)
- matrix[axis, axis] = c
- matrix[axis, other_axis] = -s
- matrix[other_axis, axis] = s
- matrix[other_axis, other_axis] = c
- return matrix
- def rotate(self) -> None:
- xw = self._4d_rotation(Axis.X, Axis.W)
- yw = self._4d_rotation(Axis.Y, Axis.W)
- zw = self._4d_rotation(Axis.Z, Axis.W)
- rotation_matrices = xw @ yw @ zw
- self.vertices_4d = self.vertices @ rotation_matrices
- def project_to_3d(self, _w) -> None:
- projection_matrix = np.array(
- [
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [0, 0, 1, 0]
- ]
- )
- self.vertices_3d = np.dot(self.vertices_4d, projection_matrix.T)
- def update(self) -> None:
- self.rotate()
- self.project_to_3d(2)
- self.angle += 0.01 * (60 / 165)
- def _draw_edges(self) -> None:
- glBegin(GL_LINES)
- for edge in self.edges:
- for vertex in edge:
- glColor3fv(self.colors[vertex])
- glVertex3fv(self.vertices_3d[vertex][:3])
- glEnd()
- def _draw_faces(self, opacity: float = 0.5) -> None:
- glBegin(GL_POLYGON)
- for face in self.faces:
- for vertex in face:
- glColor4fv(np.append(self.colors[vertex], opacity))
- glVertex3fv(self.vertices_3d[vertex][:3])
- glEnd()
- def draw(self) -> None:
- self._draw_edges()
- self._draw_faces()
- class Monitors:
- def __init__(self, sizes: list[(int, int)]):
- self.displays = [pygame.Rect((0, 0), (width, height)) for width, height in sizes]
- self.count = len(self.displays)
- @property
- def max_width(self) -> int:
- return sum([display.width for display in self.displays])
- @property
- def max_height(self) -> int:
- return max([display.height for display in self.displays])
- @property
- def max_size(self) -> tuple[int, int]:
- return self.max_width, self.max_height
- def total_width_to(self, index) -> int:
- return sum([display.width for display in self.displays[:index]])
- tesseract_data = {
- "beautiful": {
- "vertices": 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],
- [-1, 1, 1, -1],
- [-1, 1, 1, 1],
- [1, -1, -1, -1],
- [1, -1, -1, 1],
- [1, -1, 1, -1],
- [1, -1, 1, 1],
- [1, 1, -1, -1],
- [1, 1, -1, 1],
- [1, 1, 1, -1],
- [1, 1, 1, 1],
- ]
- ),
- "edges": [
- (0, 1), (0, 2), (0, 4), (0, 8),
- (1, 3), (1, 5), (1, 9),
- (2, 3), (2, 6), (2, 10),
- (3, 7), (3, 11),
- (4, 5), (4, 6), (4, 12),
- (5, 7), (5, 13),
- (6, 7), (6, 14),
- (7, 15),
- (8, 9), (8, 10), (8, 12),
- (9, 11), (9, 13),
- (10, 11), (10, 14),
- (11, 15),
- (12, 13), (12, 14),
- (13, 15),
- (14, 15)
- ],
- "faces": [
- (0, 1, 5, 4),
- (2, 3, 7, 6),
- (0, 1, 3, 2),
- (4, 5, 7, 6),
- (0, 2, 6, 4),
- (1, 3, 7, 5),
- (8, 9, 13, 12),
- (10, 11, 15, 14),
- (8, 9, 11, 10),
- (12, 13, 15, 14),
- (8, 10, 14, 12),
- (9, 11, 15, 13),
- (0, 1, 9, 8),
- (2, 3, 11, 10),
- (0, 2, 10, 8),
- (1, 3, 11, 9),
- (4, 5, 13, 12),
- (6, 7, 15, 14),
- (4, 6, 14, 12),
- (5, 7, 15, 13),
- ],
- "colors": np.array(
- [
- [1, 0, 0],
- [0, 1, 0],
- [0, 0, 1],
- [1, 1, 0],
- [1, 0, 1],
- [0, 1, 1],
- [1, 1, 1],
- [0.5, 0.5, 0.5],
- [1, 0.5, 0],
- [0.5, 1, 0],
- [0, 0.5, 1],
- [1, 1, 0.5],
- [1, 0.5, 1],
- [0.5, 1, 1],
- [1, 0.5, 0.5],
- [0.5, 1, 0.5]
- ]
- )
- }
- }
- def main():
- pygame.init()
- monitors = Monitors(pygame.display.get_desktop_sizes())
- pygame.display.set_mode(monitors.max_size, DOUBLEBUF | OPENGL | NOFRAME)
- clock = pygame.time.Clock()
- running = True
- tesseract = Tesseract(**tesseract_data["beautiful"])
- while running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT or event.type == pygame.KEYDOWN:
- running = False
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
- for index, display in enumerate(monitors.displays):
- glViewport(monitors.total_width_to(index), 0, display.width, display.height)
- glGetIntegerv(GL_VIEWPORT)
- glMatrixMode(GL_PROJECTION)
- glLoadIdentity()
- gluPerspective(55, (display.width / display.height), 0.1, 50.0)
- glMatrixMode(GL_MODELVIEW)
- glLoadIdentity()
- glTranslatef(0.0, 0.3, -5)
- glRotatef(1, 3, 1, 1)
- glEnable(GL_BLEND)
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
- tesseract.update()
- tesseract.draw()
- glDisable(GL_BLEND)
- pygame.display.flip()
- clock.tick(165)
- pygame.quit()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment