4D sztereografikus projekció pythonban
-------------
import math
import sys
import numpy as np
import pygame
# Inicializálás
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Forgó 4D gömb vetület")
clock = pygame.time.Clock()
# Színek
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 4D forgató mátrixok generálása az XY és a ZW síkokban
def get_rotation_matrices(angle_xy, angle_zw):
c_xy, s_xy = np.cos(angle_xy), np.sin(angle_xy)
c_zw, s_zw = np.cos(angle_zw), np.sin(angle_zw)
R_xy = np.array(
[
[c_xy, -s_xy, 0, 0],
[s_xy, c_xy, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
]
)
R_zw = np.array(
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, c_zw, -s_zw],
[0, 0, s_zw, c_zw],
]
)
return R_xy, R_zw
# Hiperszféra (4D gömb) pontjainak generálása
def generate_4d_sphere(num_points, radius):
points = []
# Egyenletes eloszlású pontok 4D-ben (Monte Carlo módszerrel)
while len(points) < num_points:
p = np.random.uniform(-radius, radius, 4)
norm = np.linalg.norm(p)
if norm < radius and norm > 0:
points.append(p / norm * radius)
return np.array(points)
# Paraméterek
POINTS_COUNT = 800
RADIUS = 200
points_4d = generate_4d_sphere(POINTS_COUNT, RADIUS)
angle_xy = 0.0
angle_zw = 0.0
# Fő ciklus
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill(BLACK)
# Forgatási szögek növelése
angle_xy += 0.01
angle_zw += 0.015
R_xy, R_zw = get_rotation_matrices(angle_xy, angle_zw)
for p in points_4d:
# 4D forgatás
p_rot = p @ R_xy @ R_zw
# 4D -> 3D vetítés (sztereografikus projekció)
# W = a negyedik dimenzió. A kamera távolsága miatt osztjuk a (W_távolság - W) értékkel
distance = 3.0
w_factor = 1 / (distance - p_rot[3])
p_3d = np.array([p_rot[0] * w_factor, p_rot[1] * w_factor, p_rot[2] * w_factor])
# 3D -> 2D perspektivikus vetítés
cam_dist = 500
x2d = int(WIDTH / 2 + p_3d[0] * cam_dist / (cam_dist + p_3d[2]))
y2d = int(HEIGHT / 2 + p_3d[1] * cam_dist / (cam_dist + p_3d[2]))
# Pont kirajzolása
brightness = int(
(p_rot[3] + RADIUS) / (2 * RADIUS) * 200 + 55
) # Mélység alapján színezve
color = (brightness, brightness, brightness)
pygame.draw.circle(screen, color, (x2d, y2d), 2)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
------------
Nincsenek megjegyzések:
Megjegyzés küldése