#!/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 # 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 ## # 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] # 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) glLoadIdentity() # positionne la vue gluLookAt(x, y, z, cx, cy, cz, 0.0, 1.0, 0.0) 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]) # double buffer, on dessine en mémoire et on affiche quand c'est pret glutSwapBuffers() # gestion du clavier def keyboard(key, x, y): """ gère les touches normales""" global frepere global flagsAnim global fullscreen if key == chr(27): sys.exit(0) if key == 'f': if fullscreen: glutReshapeWindow(640, 480) else: glutFullScreen() fullscreen = 1 - fullscreen if key == 'a': frepere = 1 - frepere if key == 'u': flagsAnim[0] = 1 - flagsAnim[0] if key == 'i': flagsAnim[1] = 1 - flagsAnim[1] if key == 'o': flagsAnim[2] = 1 - flagsAnim[2] if key == 'p': flagsAnim[3] = 1 - flagsAnim[3] glutPostRedisplay() 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() def specialkey(key, kx, ky): """ gère les touches spéciales""" global cx, cy, cz if key == GLUT_KEY_LEFT: cx = cx - 1 elif key == GLUT_KEY_RIGHT: cx = cx + 1 elif key == GLUT_KEY_UP: cy = cy + 1 elif key == GLUT_KEY_DOWN: cy = cy - 1 glutPostRedisplay() def mouse_move(mx, my): """ gère les mouvements de la souris lorqu'aucun bouton n'est enfoncé """ pass def mouse_move_button(mx, my): """ gère les mouvements de la souris lorqu'au moins un bouton est enfoncé """ pass def mouse_button(boutton, etat, mx, my): """ gère les appuis et relachement de bouttons de la souris """ pass # main # initialisation glutInit([]) glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE) glutInitWindowSize(640,480) glutCreateWindow(sys.argv[0]) # glutFullScreen() glutDisplayFunc(draw) glutKeyboardFunc(keyboard) glutSpecialFunc(specialkey) glutPassiveMotionFunc(mouse_move) glutMotionFunc(mouse_move_button) glutMouseFunc(mouse_button) glutIdleFunc(draw) glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(-5, 5, -5, 5, -5, 5) glMatrixMode(GL_MODELVIEW) # boucle glut, gère les évènements, et appèle draw() glutMainLoop()