viernes, 14 de octubre de 2011

La Curva Del Dragón - Python

Bueno se me ha dado por probar de nuevo la matemática entretenida y como resultado he terminado haciendo un fractal; el primero que hice hace mucho tiempo, la "Curva Del Dragón".

Este es el código:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# fDragon.py
# Fractal de la "Curva Del Dragón"
# 2011 - 10 - 14
# http://dakuregashi.blogspot.com/

import sys                          # Control del sistema
import time                         # Control del tiempo
import pygame                       # Graficas y control de eventos
from pygame.locals import *         # Constates

def genPoint(old):                  # Generador de coordenadas
    new = []                        # Lista vacia para nuevos puntos
    i = 0                           # Contador de control
    tok = -1                        # Indica la direccion de la fractura
    lim = len(old)                  # Cantidad de segmentos a evaluar
    
    while(i < lim-1):               # Repita mientras queden segmentos por evaluar
        new.append(old[i])          # Agrega el punto de inicio a la nueva lista de segmentos
        
        x1 = old[i][0]              # Extrae la coordenada x del punto inicial
        x2 = old[i+1][0]            # Extrae la coordenada x del punto final
        
        y1 = old[i][1]              # Extrae la coordenada y del punto inicial
        y2 = old[i+1][1]            # Extrae la coordenada y del punto final
        
        dx = x2 - x1                # Calcula componente en x
        dy = y2 - y1                # Calcula componente en y
        
        ax = dx / 2                 # Calcula punto medio de la componente x
        ay = dy / 2                 # Calcula punto medio de la componente y
        
        x = 0                       # Coordenada x
        y = 0                       # Coordenada y
        
        if(y1 == y2):                   # Si es un segmento horizontal
            x = x1 + ax             
            if(tok * (x2 - x1) < 0):    # Define direccion del segmento
                y = y1 - abs(ax)
            else:
                y = y1 + abs(ax)
        elif(x1 == x2):                 # Si es un segement vertical
            y = y1 + ay                 
            if(tok * (y2 -y1) > 0):     # Define direccion del segmento
                x = x1 - abs(ay)
            else:
                x = x1 + abs(ay)
        else:                           # En caso de ser un segmento diagonal
            m = (y2 - y1) / (x2 - x1)   # Calcula la pendiente de la linea       
            
            if(tok > 0):                # Define la direccion del segmento
                if(m > 0):              # Segun la pendiente
                    x = x1 + (ax - ay)
                    y = y1 + (ax + ay)
                else:
                    x = x1 + (ax - ay)
                    y = y1 - (ax + ay)
            else:
                x = x1 + (ax + ay)
                y = y1 - (ax - ay)
            
        new.append((x, y))              # Agrega el nuevo punto a la lista de segmentos
        tok *= -1                       # Alterna el token de direccion
        i += 1                          # Incrementa el contador
        
    new.append(old[lim-1])              # Agrega el ultimo punto a la lista de segmentos
    return new                          # Devuelve la lista de segmentos

# Colores a usar
NEGRO = (0, 0, 0)
BLANCO = (255, 255, 255)
ROJO = (255, 0, 0)
VERDE = (0, 255, 0)

pygame.init()                                           # Inicializa recursos
pantalla = pygame.display.set_mode((800, 600), 0, 32)   # Define atributos de la centana
pygame.display.set_caption('Curva Del Dragón')          # Titulo de la ventana

lOld = [(200, 384.0), (700, 384.0)]                     # Lista con los puntos de arranque (linea horizontal)
lNew = []                                               # Lista vacia para los futuros segmentos

i = 0                                                   # Contador de control
while True:                                             # Ciclo principal
    if(i < 20):                                         # Limite de iteraciones
        pantalla.fill(NEGRO)                            # Limpia el area de la ventana
        lNew = genPoint(lOld)                           # Genera los nuevos segmentos de la iteración
        pygame.draw.lines(pantalla, ROJO, False, lOld)  # Dibuja los segmentos anteriores con rojo
        pygame.draw.lines(pantalla, VERDE, False, lNew) # Dibuja los nuevos segmentos con verde
        lOld = lNew                                     # Actualiza la lista de originales
        pygame.display.update()                         # Actualiza la imagen de la ventana
        time.sleep(0.5)                                 # Demora de control
        i += 1                                          # Incrementa contador
    
    if(i == 20):                                        # Si se han terminado las iteraciones
        pantalla.fill(BLANCO)                           # Limpia la ventana con blanco
        pygame.draw.lines(pantalla, NEGRO, False, lNew) # Dibuja el fractal con negro
        pygame.display.update()                         # Actualiza imagen    
        
    for event in pygame.event.get():                    # Ciclo de eventos, sale con escape
        if (event.type == QUIT) or (event.type == KEYDOWN and event.key == 27):
            pygame.quit()
            sys.exit()


Hasta la próxima.....Paz y Suerte...........黒オオカミ

1 comentario:

  1. Que interesante algoritmo, enhorabuena por este blog que se perfila como un espacio para el aprendizaje saludable de programación y algoritmia

    ResponderEliminar