martes, 14 de noviembre de 2017

Esferas 3D


#!/usr/bin/python
# -*- coding: utf-8 -*-
# Librerías del programa
import sys
import math
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


# Iluminación personalizada de la animación
class Luz(object):
    encendida = True
    colores = [(1., 1., 1., 1.), (1., 0.5, 0.5, 1.),
               (0.5,1.,0.5,1.), (0.5,0.5,1.,1.)]
    def __init__(self, luz_id, posicion):
        # Identificador del objeto de iluminación
        self.luz_id = luz_id
        # Posición de la iluminación
        self.posicion = posicion
        # Variable para seleccionar colores
        self.color_actual = 0

    # Tipo de iluminación
    def dibujar(self):
        light_id = self.luz_id
        color = Luz.colores[self.color_actual]
        glLightfv(light_id, GL_POSITION, self.posicion)
        glLightfv(light_id, GL_DIFFUSE, color)
        glLightfv(light_id, GL_CONSTANT_ATTENUATION, 0.1)
        glLightfv(light_id, GL_LINEAR_ATTENUATION, 0.05)

    def cambiar_color(self):
        self.color_actual += 1
        # Reinicia el color actual
        self.color_actual %= len(Luz.colores)


    def enable(self):
        if not Luz.encendida:
            glEnable(GL_LIGHTING)
            Luz.encendida = True
        glEnable(self.luz_id)

# Construcción de la Esfera
class Esfera(object):
    # Divisiones de norte a sur
    meridianos = 40
    # Divisiones este a oeste
    paralelos = 40

    # Constructor de la clase
    def __init__(self, radio, posicion, color):
        self.radio = radio
        self.posicion = posicion
        self.color = color

    # Función que dibuja una esfera
    def dibujar(self):
        # Ubicacion de la figura 3d
        glTranslatef(*self.posicion)
        # Especifica los parametros del material para la iluminación
        # GL_AMBIENT , GL_EMISSION
        glMaterialfv(GL_FRONT, GL_DIFFUSE, self.color)
        # Función especial para dibujar esferas
        glutSolidSphere(self.radio, Esfera.meridianos, Esfera.paralelos)

# Aplicación principal
class App(object):
    # Constructor de la clase
    def __init__(self, largo=800, ancho=600):
        # Titulo de la ventana
        self.titulo = 'Esferas con OpenGL'
        # Medidas de la ventana
        self.largo = largo
        self.ancho = ancho
        # Angulo de vision de la camara
        self.angulo = 0
        # Distancia de la camara
        self.distancia = 20
        # Instancia de la clase Luz
        self.iluminacion = Luz(GL_LIGHT0, (15, 5, 15, 1))
        # Instancia de la clase Esfera
        self.esfera1 = Esfera(2, (0, 0, 0), (1, 1, 1, 1))
        # Instancia de la clase Esfera
        self.esfera2 = Esfera(1, (4, 2, 0), (1, 0.4, 0.4, 1))

    # Función que crea la ventana y los graficos 3d
    def iniciar(self):
        # Inicializa la librería GLUT
        glutInit()

        # Funciones para inicializar la ventana
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH)
        glutInitWindowPosition(50, 50)
        glutInitWindowSize(self.largo, self.ancho)
        glutCreateWindow(self.titulo)

        # Activar las funciones graficas
        glEnable(GL_DEPTH_TEST)
        # Activar iluminación
        glEnable(GL_LIGHTING)
        # Seleccionar la constante de iluminación
        glEnable(GL_LIGHT0)

        # Activar la iluminación con las características de nuestra función
        self.iluminacion.enable()

        # Color de fondo
        glClearColor(.1, .1, .1, 1)

        glMatrixMode(GL_PROJECTION)
        aspect = self.largo / self.ancho
        gluPerspective(40., aspect, 1., 40.)
        glMatrixMode(GL_MODELVIEW)

        # Llamada para dibujar las figuras
        glutDisplayFunc(self.dibujar)
        # Llamada para activar las funciones del teclado
        glutSpecialFunc(self.keyboard)

        #Inicia el ciclo de la libreria
        glutMainLoop()
        # ...

    # Función que dibuja las figuras 3D
    def dibujar(self):
        # Coordenadas de la cámara
        x = math.sin(self.angulo) * self.distancia
        z = math.cos(self.angulo) * self.distancia

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()

        # Coordenadas de la cámara
        # Posición
        # Dirección en la que mira
        # Orientación
        gluLookAt(x, 0, z,
                  0, 0, 0,
                  0, 1, 0)

        # Se crea la iluminación
        self.iluminacion.dibujar()

        # Se crea la primer esfera
        self.esfera1.dibujar()
        # Se crea la segunda esfera
        self.esfera2.dibujar()

        glutSwapBuffers()

    # Funciones del teclado
    def keyboard(self, tecla, x, y):
        if tecla == GLUT_KEY_INSERT:
            # Cerrar ventana
            sys.exit()
        if tecla == GLUT_KEY_UP:
            # Acercar la cámara
            self.distancia -= 0.1
        if tecla == GLUT_KEY_DOWN:
            # Alejar cámara
            self.distancia += 0.1
        if tecla == GLUT_KEY_LEFT:
            # Girar cámara a la izquierda
            self.angulo -= 0.05
        if tecla == GLUT_KEY_RIGHT:
            # Girar cámara a la derecha
            self.angulo += 0.05
        if tecla == GLUT_KEY_F1:
            # Cambiar color de las esferas
            self.iluminacion.cambiar_color()
        # Máxima y mínima distancia de la cámara
        self.distancia = max(10, min(self.distancia, 20))
        # Reiniciar el ángulo de giro
        self.angulo %= math.pi * 2
        # Actualiza el plano 3d y las figuras de acuerdo al movimiento de la camara
        glutPostRedisplay()


if __name__ == '__main__':
    app = App()
    app.iniciar()



https://drive.google.com/file/d/1g01y1-6-TQJOzCVfgJfw6wGtfKfa4KoH/view?usp=sharing


No hay comentarios:

Publicar un comentario