py_hypercube/py_hypercube.py

326 lines
7.9 KiB
Python
Executable file

#!/usr/bin/python
# -*- coding: iso8859-15 -*-
""" projection variable d'un hypercube"""
# pour l'interaction avec le système
# pour sqrt() et pow()
import math
# pour les nombres aléatoires
from random import randint
import pygame as pg
from pygame.locals import *
# importe tout ce qui est contenu dans le package OpenGL
from OpenGL.GL import *
# GLU première couche au dessus d'OpenGL
from OpenGL.GLU import *
# couche supérieure, ressemble à la SDL, permet la gestion simplifiée de la configuration,
# des entrées (clavier souris) et des fonctions de plus haut niveau
from OpenGL.GLUT import *
##
# Constantes
##
MIN_INC = -100
MAX_INC = 100
FPS = 60
##
# Variables globales
##
# points de l'hypercube dans l'hyperespace
hp = [0, 0, 0, 0,
1, 0, 0, 0,
0, 1, 0, 0,
1, 1, 0, 0,
0, 0, 1, 0,
1, 0, 1, 0,
0, 1, 1, 0,
1, 1, 1, 0,
0, 0, 0, 1,
1, 0, 0, 1,
0, 1, 0, 1,
1, 1, 0, 1,
0, 0, 1, 1,
1, 0, 1, 1,
0, 1, 1, 1,
1, 1, 1, 1]
# flags
frepere = 0
flagsAnim = [1, 1, 1, 1]
fullscreen = 0
## coordonnées
# position
x = 0.0
y = 0.0
z = 3.0
# vue
cx = 0.0
cy = 0.0
cz = 0.0
# variables pour l'animation sur les coordonnées de l'espace de projection
# varAnim = [ -100, -33, 33, 100 ]
# variables de départ aléatoires
varAnim = [randint(-100, 100),
randint(-100, 100),
randint(-100, 100),
randint(-100, 100)]
# incAnim = [0.1, 0.1, 0.1, 0.1]
# incAnim = [0.05, 0.05, 0.05, 0.05]
incAnim = [1.0, 1.0, 1.0, 1.0]
# fonction d'affichage principale
def draw():
""" fonction d'affichage principale appelée par GlutMainLoop"""
global x, y, z
global cx, cy, cz
global varAnime
global flagsAnime
global incAnime
global frepere
# couleur par défaut (le fond entre autre)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
if frepere == 1:
draw_repere()
# animation
for i in range(0, 3):
if flagsAnim[i]:
varAnim[i] += incAnim[i]
if (varAnim[i] > MAX_INC) or (varAnim[i] < MIN_INC):
incAnim[i] *= -1
draw_hypercube(varAnim[0], varAnim[1], varAnim[2], varAnim[3])
# gestion du clavier
def keyboard(key):
""" gère les touches normales"""
global frepere
global flagsAnim
global fullscreen
global cx, cy, cz
if key == K_ESCAPE:
pg.quit()
quit()
if key == K_f:
pass
fullscreen = 1 - fullscreen
if key == K_a:
frepere = 1 - frepere
if key == K_u:
flagsAnim[0] = 1 - flagsAnim[0]
if key == K_i:
flagsAnim[1] = 1 - flagsAnim[1]
if key == K_o:
flagsAnim[2] = 1 - flagsAnim[2]
if key == K_p:
flagsAnim[3] = 1 - flagsAnim[3]
if key == K_LEFT:
cx = cx - 1
elif key == K_RIGHT:
cx = cx + 1
elif key == K_UP:
cy = cy + 1
elif key == K_DOWN:
cy = cy - 1
def draw_line(x1, y1, z1, x2, y2, z2):
""" dessine une ligne"""
glBegin(GL_LINES)
glVertex3f(x1, y1, z1)
glVertex3f(x2, y2, z2)
glEnd()
def draw_repere():
""" dessine le repère orthogonal"""
glBegin(GL_LINES)
glColor3f(1.0, 0.0, 0.0)
glVertex2i(0, 0)
glVertex2i(0, 1)
glColor3f(0.0, 1.0, 0.0)
glVertex2i(0, 0)
glVertex2i(1, 0)
glColor3f(0.0, 0.0, 1.0)
glVertex2i(0, 0)
glVertex3i(0, 0, 1)
glEnd()
def draw_hypercube(a1, b1, c1, d1):
"""dessine l'hypercube """
global hp
# normalisation
a = a1 / math.sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2) + pow(d1, 2))
b = b1 / math.sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2) + pow(d1, 2))
c = c1 / math.sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2) + pow(d1, 2))
d = d1 / math.sqrt(pow(a1, 2) + pow(b1, 2) + pow(c1, 2) + pow(d1, 2))
X = list()
Y = list()
Z = list()
# parcours de la liste des points de l'hypercube
for p in range(0,16):
hx = hp[p * 4]
hy = hp[p * 4 + 1]
hz = hp[p * 4 + 2]
ht = hp[p * 4 + 3]
# calcul des coordonnées projetées
X.append( ( b * (pow(b, 2) + pow(c, 2) + pow(d, 2)) + pow(a, 2) * b) * hx + (pow(-b, 2) * a - a * (pow(a, 2) + pow(c, 2) + pow(d, 2))) * hy + (d * (pow(a, 2) + pow(b, 2) + pow(d, 2)) + pow(c, 2) * d) * hz + (c * pow(d, 2) + c * (pow(a, 2) + pow(b, 2) + pow(c, 2))) * ht)
Y.append( (c * (pow(b, 2) + pow(c, 2) + pow(d, 2)) + pow(a, 2) * c) * hx + (-d * (pow(a, 2) + pow(c, 2) + pow(d, 2) ) - pow(b, 2) * d) * hy + (pow(-c, 2) * a-a*(pow(a, 2) + pow(b, 2) + pow(d, 2))) * hz + (-b * pow(d, 2) - b * (pow(a, 2) + pow(b, 2) + pow(c, 2))) * ht)
Z.append( ( d * (pow(b, 2) + pow(c,2) + pow(d, 2)) + pow(a, 2) * d) * hx + (c * (pow(a, 2) + pow(c, 2) + pow(d, 2)) + pow(b, 2) * c) * hy + (pow(-c, 2) * b - b * (pow(a, 2) + pow(b, 2) + pow(d, 2))) * hz + (a * pow(d, 2) + a * (pow(a, 2) + pow(b, 2) + pow(c, 2))) * ht)
# dessine les lignes entre les points afin de dessiner l'hypercube
glBegin(GL_LINES)
glColor4f(1.0, 0.0, 0.0, 0.9)
# A B
glVertex3f(X[0], Y[0], Z[0])
glVertex3f(X[1], Y[1], Z[1])
# A C
glVertex3f(X[0], Y[0], Z[0])
glVertex3f(X[2], Y[2], Z[2])
# B D
glVertex3f(X[1], Y[1], Z[1])
glVertex3f(X[3], Y[3], Z[3])
# C D
glVertex3f(X[2], Y[2], Z[2])
glVertex3f(X[3], Y[3], Z[3])
# A E
glVertex3f(X[0], Y[0], Z[0])
glVertex3f(X[4], Y[4], Z[4])
# B F
glVertex3f(X[1], Y[1], Z[1])
glVertex3f(X[5], Y[5], Z[5])
# E F
glVertex3f(X[4], Y[4], Z[4])
glVertex3f(X[5], Y[5], Z[5])
# C G
glVertex3f(X[2], Y[2], Z[2])
glVertex3f(X[6], Y[6], Z[6])
# E G
glVertex3f(X[4], Y[4], Z[4])
glVertex3f(X[6], Y[6], Z[6])
# D H
glVertex3f(X[3], Y[3], Z[3])
glVertex3f(X[7], Y[7], Z[7])
# F H
glVertex3f(X[5], Y[5], Z[5])
glVertex3f(X[7], Y[7], Z[7])
# G H
glVertex3f(X[7], Y[7], Z[7])
glVertex3f(X[6], Y[6], Z[6])
glColor4f(0.0, 1.0, 0.0, 0.9)
# A I
glVertex3f(X[0], Y[0], Z[0])
glVertex3f(X[8], Y[8], Z[8])
# B J
glVertex3f(X[1], Y[1], Z[1])
glVertex3f(X[9], Y[9], Z[9])
# C K
glVertex3f(X[2], Y[2], Z[2])
glVertex3f(X[10], Y[10], Z[10])
# D L
glVertex3f(X[3], Y[3], Z[3])
glVertex3f(X[11], Y[11], Z[11])
# E M
glVertex3f(X[4], Y[4], Z[4])
glVertex3f(X[12], Y[12], Z[12])
# F N
glVertex3f(X[5], Y[5], Z[5])
glVertex3f(X[13], Y[13], Z[13])
# G O
glVertex3f(X[6], Y[6], Z[6])
glVertex3f(X[14], Y[14], Z[14])
# H P
glVertex3f(X[7], Y[7], Z[7])
glVertex3f(X[15], Y[15], Z[15])
glColor4f(0.0, 0.0, 1.0, 0.9)
# I J
glVertex3f(X[8], Y[8], Z[8])
glVertex3f(X[9], Y[9], Z[9])
# I K
glVertex3f(X[8], Y[8], Z[8])
glVertex3f(X[10], Y[10], Z[10])
# I M
glVertex3f(X[8], Y[8], Z[8])
glVertex3f(X[12], Y[12], Z[12])
# J L
glVertex3f(X[9], Y[9], Z[9])
glVertex3f(X[11], Y[11], Z[11])
# J N
glVertex3f(X[9], Y[9], Z[9])
glVertex3f(X[13], Y[13], Z[13])
# K L
glVertex3f(X[10], Y[10], Z[10])
glVertex3f(X[11], Y[11], Z[11])
# K O
glVertex3f(X[10], Y[10], Z[10])
glVertex3f(X[14], Y[14], Z[14])
# M N
glVertex3f(X[12], Y[12], Z[12])
glVertex3f(X[13], Y[13], Z[13])
# M O
glVertex3f(X[12], Y[12], Z[12])
glVertex3f(X[14], Y[14], Z[14])
# N P
glVertex3f(X[13], Y[13], Z[13])
glVertex3f(X[15], Y[15], Z[15])
# O P
glVertex3f(X[14], Y[14], Z[14])
glVertex3f(X[15], Y[15], Z[15])
# L P
glVertex3f(X[11], Y[11], Z[11])
glVertex3f(X[15], Y[15], Z[15])
glEnd()
# main
pg.init()
windowSize = (1152, 720)
pg.display.set_mode(windowSize, DOUBLEBUF | OPENGL)
clock = pg.time.Clock()
# setup PoV
gluPerspective(60, (windowSize[0]/windowSize[1]), 0.1, 100.0)
glTranslatef(0.0, 0.0, -5)
while True:
for event in pg.event.get():
if event.type == pg.KEYDOWN:
keyboard(event.key)
# print('FPS: ' + str(clock.get_fps()))
clock.tick(FPS)
draw()
pg.display.flip()