diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..041c51b --- /dev/null +++ b/.drone.yml @@ -0,0 +1,13 @@ +kind: pipeline +name: lint + +steps: +- name: markdown lint + image: pipelinecomponents/markdownlint:latest + commands: + - mdl . + +- name: python lint + image: cytopia/pylint + commands: + - find . -type f -name "*.py" | xargs pylint diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3d9310 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Byte-compiled +__pycache__/ +*.py[cod] +*.swp + +.idea/ diff --git a/README.md b/README.md index ffe0611..2dffd52 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # py_hypercube -Conversion of my old 3D "hello world" that animates the 3D projeciton of an hypercube. - -WIth more or less parameters - -PyOpenGL/Glut -> PyGame \ No newline at end of file +Conversion of my old 3D "hello world" that animates the 3D projeciton of an hypercube. + +With more or less parameters + +PyOpenGL/Glut -> PyGame +[![Build Status](https://drone.kleph.eu/api/badges/kleph/py_hypercube/status.svg)](https://drone.kleph.eu/kleph/py_hypercube) diff --git a/py_hypercube.py b/py_hypercube.py new file mode 100755 index 0000000..369ffe0 --- /dev/null +++ b/py_hypercube.py @@ -0,0 +1,354 @@ +#!/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()