viernes, 6 de marzo de 2015

Miel hiperbólica

(es) Miel hiperbólica

(eo) Hiperbola mielo

Miel hiperbólica

http://dx.doi.org/10.13140/RG.2.2.34092.90243

 Descripción artística:

Un acercamiento de un panal de miel.

Motivación:

Lectura de un artículo sobre geometría hiperbólica y otra lectura sobre teselaciones.

Descripción técnica:

Una teselación hexagonal de fondo y en frente una teselación hexagonal en geometría hiperbólica proyectada sobre el disco de Poincaré.

Archivos

Código (Python):

#!/usr/bin/env python
# coding: utf-8

# Copyright 2015 Eduardo Adam Navas López
# Este programa es Software Libre liberado bajo la licencia GNU GPLv3 o su versión más reciente:
# http://www.gnu.org/licenses/gpl.html

import pygame
import math
import escala

prueba = False
#prueba = True

INF_IZQ = (-0.5,-0.5)
SUP_DER = (0.5,0.5)

if prueba:
 #En pixeles:
 ANCHO = 1000
 ALTO  = 1000
 GRUESO_LINEA = 5
 #En unidades virtuales:
 RADIO = 0.485

 NUMFILAS = 50
else:
 #En pixeles:
 ANCHO = 8000
 ALTO  = 8000
 GRUESO_LINEA = 40
 #En unidades virtuales:
 RADIO = 0.49 #487

 NUMFILAS = 95


APOTEMA = 0.05
LADO = 2 * APOTEMA / math.sqrt(3)
EXTREMO = LADO*NUMFILAS/2
RADIOTOTAL = 0.5

COLOR_MIEL = (0xFF,0xA8,0x00)
COLOR_LINEAS = (0xFF,0xCC,0x66)

COLOR_MIEL2 = (0xFF,0xBF,0x40)
COLOR_LINEAS2 = (0xFF,0xDD,0x99)

def proyeccion((x,y)):
 """Esta función toma un punto en la escala virtual euclídea y 
 lo devuelve proyectado en el disco de Poincaré.
 """
 r = math.sqrt(x*x+y*y)/(2*math.sqrt(x*x+y*y+1))
 th = math.atan2(y,x)
 return (r*math.cos(th),r*math.sin(th))

def grueso_linea((x,y)):
 return int(GRUESO_LINEA - math.sqrt(x*x+y*y)*(GRUESO_LINEA-1)/RADIOTOTAL)

if __name__ == "__main__":

 pygame.init()
 imagen = pygame.Surface((ANCHO, ALTO))
 imagen.fill(COLOR_MIEL2)
 e = escala.Escala((ANCHO, ALTO), INF_IZQ, SUP_DER)
 

 p1 = (0.0,LADO)
 p2 = (-APOTEMA, LADO/2)
 p3 = (-APOTEMA, -LADO/2)
 p4 = (0.0,-LADO)
 p5 = (APOTEMA, -LADO/2)
 p6 = (APOTEMA, LADO/2)
 poligono = [p1,p2,p3,p4,p5,p6]

 for i in xrange(NUMFILAS/2):
  for j in xrange(NUMFILAS/2):
   pygame.draw.polygon(imagen,COLOR_LINEAS2, 
   map(lambda punto: e.vr(((punto[0]+j*2*APOTEMA+(i%2)*APOTEMA,punto[1]+i*3*LADO/2))),poligono),
   GRUESO_LINEA)

   pygame.draw.polygon(imagen,COLOR_LINEAS2, 
   map(lambda punto: e.vr(((punto[0]+j*2*APOTEMA+(i%2)*APOTEMA,punto[1]-i*3*LADO/2))),poligono),
   GRUESO_LINEA)

   pygame.draw.polygon(imagen,COLOR_LINEAS2, 
   map(lambda punto: e.vr(((punto[0]-j*2*APOTEMA-(i%2)*APOTEMA,punto[1]+i*3*LADO/2))),poligono),
   GRUESO_LINEA)

   pygame.draw.polygon(imagen,COLOR_LINEAS2, 
   map(lambda punto: e.vr(((punto[0]-j*2*APOTEMA-(i%2)*APOTEMA,punto[1]-i*3*LADO/2))),poligono),
   GRUESO_LINEA)

 #Dibujar círculo de miel
 circ = pygame.Rect(e.vrx(-RADIO),e.vry(RADIO),e.magnitudvrx(2*RADIO),e.magnitudvry(-2*RADIO))
 #pygame.draw.ellipse(imagen,COLOR_MIEL,circ)

 for i in xrange(NUMFILAS/2):
  for j in xrange(int(math.sqrt(NUMFILAS*NUMFILAS/4+i*i))-1):
   pol = map(lambda punto: e.vr(proyeccion((punto[0]+j*2*APOTEMA+(i%2)*APOTEMA,punto[1]+i*3*LADO/2))),poligono)
   pygame.draw.polygon(imagen,COLOR_MIEL,pol)
   pygame.draw.polygon(imagen, COLOR_LINEAS, 
   pol,
   grueso_linea(e.rv(pol[0])))

   pol = map(lambda punto: e.vr(proyeccion((punto[0]+j*2*APOTEMA+(i%2)*APOTEMA,punto[1]-i*3*LADO/2))),poligono)
   pygame.draw.polygon(imagen,COLOR_MIEL,pol)
   pygame.draw.polygon(imagen, COLOR_LINEAS, 
   pol,
   grueso_linea(e.rv(pol[0])))

   pol = map(lambda punto: e.vr(proyeccion((punto[0]-j*2*APOTEMA-(i%2)*APOTEMA,punto[1]+i*3*LADO/2))),poligono)
   pygame.draw.polygon(imagen,COLOR_MIEL,pol)
   pygame.draw.polygon(imagen, COLOR_LINEAS, 
   pol,
   grueso_linea(e.rv(pol[0])))

   pol = map(lambda punto: e.vr(proyeccion((punto[0]-j*2*APOTEMA-(i%2)*APOTEMA,punto[1]-i*3*LADO/2))),poligono)
   pygame.draw.polygon(imagen,COLOR_MIEL,pol)
   pygame.draw.polygon(imagen, COLOR_LINEAS, 
   pol,
   grueso_linea(e.rv(pol[0])))

 print "Imagen generada. Guardando..."
 if prueba:
  pygame.image.save(imagen, "panal1000.png")
 else:
  pygame.image.save(imagen, "panal.png")

No hay comentarios:

Publicar un comentario