(es) Coronoide
(eo) Kornokurbo
http://dx.doi.org/10.13140/RG.2.2.34092.90243 
Descripción artística:
El trazo de la curva Cornoide, descubierta por el Doctor Alberto Sánchez, salvadoreño, en 1895.
Motivación:
El trabajo de un salvadoreño que aportó la identificación de una curva de construcción relativamente simple que todos los grandes matemáticos de la historia pasaron por alto. La Escuela de Matemática de la Facultad de Ciencias Naturales y Matemática de la Universidad de El Salvador, lleva su nombre en su honor.
Descripción técnica:
El trazo de la curva Cornoide, con ecuación paramétrica:
El procedimiento geométrico para construirla es el siguiente:
Sea  un punto de la circunferencia de diámetro director  y sea  el punto de intersección de la circunferencia con la paralela por el punto  al diámetro . Desde  se traza la recta tangente a la circunferencia y desde  la recta perpendicular a la recta tangente. Sea  el punto intersección de ambas rectas. Cuando el punto  describe la circunferencia, el punto  describe la Cornoide.
Archivos
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
"""Animación del cornoide.
Gerera archivos con nombre: img-*.png
Este comando genera la animación gif a partir de la secuencia de archivos png:
$ convert -delay 10 -loop 0 img-*.png animacion.gif
Con este otro se puede generar la animación al derecho y al revés:
$ convert -delay 10 -loop 0 img-*.png $(ls img-*.png -r) animacion.gif
"""
import pygame
import math
import escala
prueba = False
#prueba = True
if prueba:
 ANCHO = 1000
 ALTO  = 1000
else:
 ANCHO = 8000
 ALTO  = 8000
INF_IZQ = (-1.03,-0.61)
SUP_DER = (1.03,1.45)
NUMPASOS = 50
NUMPASOSCURVA = 100*NUMPASOS
TIEMPO_PAUSA = 50
#En pixeles:
GRUESO_CIRCULO = 10 ####4
GRUESO_CORNOIDE = 10 ####6
GRUESO_LINEA = 4 ####2 
RADIO_PUNTO = 10 ####2
#En unidades virtuales:
RADIO_CIRCULO = 1.0
ROJO   = (255,0,0)
VERDE  = (0,255,0)
AZUL   = (0,0,255)
BLANCO = (255,255,255)
NEGRO  = (0,0,0)
COLOR_CORNOIDE = (112,121,246)
COLOR_CIRCULO = (100,100,100)
#COLOR_RADIO = (0,0,250)
COLOR_TANGENTE = (0,0,200)
#COLOR_SECANTE = (0,0,150)
COLOR_FINAL = (0,0,150)
COLOR_PUNTO = ROJO
def cornoide(t, r=1.0):
 return r*math.cos(t)*math.cos(2*t), r*math.sin(t)*(2+math.cos(2*t))
def actualizar(t):
 """Aquí hay que guardar las imágenes"""
 global pantalla
 if prueba:
  pygame.display.flip()
  #Descomentar la siguiente línea para generar los archivos *.png que componen la animación
  #pygame.image.save(pantalla, "img-{0:.10}.png".format(t))
def dibujar():
 global pantalla, e
 i = 0
 t = 0.0
 pcirc = RADIO_CIRCULO*math.cos(t), RADIO_CIRCULO * math.sin(t)
 #i=i+1
 pantalla.fill(BLANCO)
 while i<=NUMPASOS:
  #Calcular siguiente punto del cornoide:
  t = math.pi/2 * i/NUMPASOS
  p = cornoide(t, RADIO_CIRCULO)
  pr = e.vr(p)
  #Dibujar círculo:
  circunferencia(pantalla, COLOR_CIRCULO, e.vr((0.0,0.0)), int(e.magnitudvrx(RADIO_CIRCULO)), GRUESO_CIRCULO)
  #Centro del círculo:
  pygame.draw.circle(pantalla, COLOR_PUNTO, e.vr((0.0,0.0)), RADIO_PUNTO)
  #Dibujar el Cornoide hasta este punto:
  ii = 0
  Lii = i*NUMPASOSCURVA/float(NUMPASOS)
  while ii<=Lii:
   ttemp = math.pi/2 * ii/NUMPASOSCURVA
   pA = e.vr(cornoide(ttemp, RADIO_CIRCULO))
   pygame.draw.circle(pantalla, COLOR_CORNOIDE, pA, GRUESO_CORNOIDE/2)
   ii=ii+1
  #Punto del círculo:
  pcirc = RADIO_CIRCULO*math.cos(t), RADIO_CIRCULO * math.sin(t)
  #Radio:
  #pygame.draw.line(pantalla, COLOR_RADIO, e.vr((0.0,0.0)), e.vr(pcirc), GRUESO_LINEA)
  #Recta tangente al círculo:
  pygame.draw.line(pantalla, COLOR_TANGENTE, e.vr(p), e.vr(pcirc), GRUESO_LINEA)
  
  ##con esto se prolonga la tangente
  #pendiente = -1.0/math.tan(t)
  #ptan1 = e.minxv, pendiente * (e.minxv - pcirc[0]) + pcirc[1]
  #ptan2 = e.maxxv, pendiente * (e.maxxv - pcirc[0]) + pcirc[1]
  #pygame.draw.line(pantalla, COLOR_TANGENTE, e.vr(ptan1), e.vr(ptan2), GRUESO_LINEA)
  #Secante al círculo:
  pcirc2 = (-pcirc[0], pcirc[1])
  #pygame.draw.line(pantalla, COLOR_SECANTE, e.vr(pcirc2), e.vr(pcirc), GRUESO_LINEA)
  #Segmento final:
  pygame.draw.line(pantalla, COLOR_FINAL, e.vr(pcirc2), pr, GRUESO_LINEA)
  actualizar(t)
  if prueba:
   pygame.time.delay(TIEMPO_PAUSA)
  i = i+1
def dibujarCircunferencia(xc, yc, re, ri, color,lienzo):
 """Dibuja una circunferencia con centro (xc,yc)
 y radio exterior re e interior ri.
 """
 if re <= ri: return #No funcionaría el algoritmo
 def marcarPixel(x,y):
  lienzo.set_at(( x+xc, y+yc), color)
  lienzo.set_at(( x+xc,-y+yc), color)
  lienzo.set_at((-x+xc, y+yc), color)
  lienzo.set_at((-x+xc,-y+yc), color)
  lienzo.set_at(( y+xc, x+yc), color)
  lienzo.set_at(( y+xc,-x+yc), color)
  lienzo.set_at((-y+xc, x+yc), color)
  lienzo.set_at((-y+xc,-x+yc), color)
 def marcarLineaH(xi,xf,y):
  i = xi
  while i<=xf:
   marcarPixel(i,y)
   i = i+1
 limites = {}
 x = 0
 y = re
 d = 1-re
 while y>x:
  if d<0:
   d += x*2+3
  else:
   d += (x-y)*2+5
   limites[y] = [None, x]
   y = y-1
  x = x+1
 x = 0
 y = ri
 d = 1-ri
 if limites.has_key(y):
  limites[y][0] = x
 else:
  limites[y] = [x, None]
 while y>x:
  if d<0:
   d += x*2+3
   x = x+1
  else:
   d += (x-y)*2+5
   y = y-1
   x = x+1
   if limites.has_key(y):
    limites[y][0] = x
   else:
    limites[y] = [x, None]
 for cada_y, (xi,xf) in limites.iteritems():
  if xi is None:
   marcarLineaH(0,xf,cada_y)
  elif xf is None:
   marcarLineaH(xi,cada_y,cada_y)
  else:
   marcarLineaH(xi,xf,cada_y)
def circunferencia(lienzo, color, (xc,yc), radio, ancho=1):
 dibujarCircunferencia(xc, yc, radio+ancho/2, radio-ancho/2, color, lienzo)
if __name__ == "__main__":
 global pantalla, e
 pygame.init()
 if prueba:
  pantalla = pygame.display.set_mode((ANCHO, ALTO))
  pygame.display.set_caption("Cornoide")
 else:
  pantalla = pygame.Surface((ANCHO, ALTO))
 e = escala.Escala((ANCHO, ALTO), INF_IZQ, SUP_DER)
 dibujar()
 if not prueba:
  print "Imagen generada. Guardando..."
  pygame.image.save(pantalla, "cornoide.png")
 raw_input("Presione una tecla para salir")
 
No hay comentarios:
Publicar un comentario