martes, 9 de marzo de 2010

Logo y colorines

Hace un par de dias que estoy trasteando con Logo [ en la wikipedia ] , un lenguaje de programacion diseñado con fines didacticos y que en este caso me parece interesante por que hace muy facil dibujar cosas en la pantalla, como lo que llaman "graficos de tortuga", lo de "tortuga" es por que el cursor era representado como una tortuga y se utiliza para referirse a el (a pesar de que en programas como ucblogo no sea una tortuga, sino simplemente una flecha )

[Nota:] probablemente haya una funcion para extraer la imagen, sino siempre os queda el Imprimir pantalla (como hice yo)

[Nota:] al final dejo unos cuantos interpretes, de todas formas, si usais un sistema Unix, casi seguro que podeis conseguir el ucblogo, ya sea por synaptic, port's o su pagina web ( http://www.eecs.berkeley.edu/~bh/logo.html )

No se necesitan muchas instrucciones para utilizarlo y pasar el rato, las instrucciones "basicas" son:

Para avanzar: forward <numero de pasos> (o fd <numero de pasos> )
Para retroceder: back <numero de pasos> (o bk <numero de pasos> )
Para girar a la derecha: right <grados que se gira> (o rt <grados que se gira> )
Para girar a la izquierda: left <grados que se gira> (o lt <grados que se gira>)
Para volver a la posicion inicial: home
Para limpiar la pantalla: clean
Para repetir instrucciones: repeat <veces que se repite> '[' <Instrucciones que se repiten> ']'
Para definir una nueva funcion: to <nueva instruccion a definir> [:<argumento1>] ... [:<argumentoN>]
[instruccion] ... [instruccion] END

Finalizar una funcion antes del stop : stop
Ocultar la tortuga: hideturtle ( o ht )
Mostrar la tortuga: showturtle ( o st )
Condiciones: if <condicion> '[' <acciones> ']'


Asi que, por ejemplo, para hacer una funcion que muestre un cuadrado, escribiriamos:

   to cuadrado
      forward 50
      right 90
      forward 50
      right 90
      forward 50
      right 90
      forward 50
      right 90

   end

o lo que es lo mismo:
 

   to cuadrado
      repeat 4[forward 50 right 90]
   end

Esto dibujaria un cuadrado cada vez que se hace cuadrado con unos lados de 50 pasos

...pero como hariamos para poder elegir la longitud de los lados ?
Veamos, las variables se usan con un ':', asi que...

   to cuadrado :lado
     repeat 4[ forward :lado right 90]
   end


[Nota:]  en los dos casos se podria usar left en vez de right, como sabeis, lo importante es girar 90 grados, no importa la direccion

 Y dibuja un cuadrado cuando se llama a cuadrado <tamaño> , por ejemplo, con  cuadrado 200, dibuja un cuadrado con 200 pasos de lado

Ahora vamos a añadir algo mas, como hariamos una funcion que dibujara una figura con el numero de lados que queramos?
Seguramente ya se te haya ocurrido (no tiene demasiada dificultad precisamente :P), pero para quien no, ahi va la explicacion:

Si te fijas en la "formula del cuadrado", va asi (en pseudocodigo):
  repite 4 veces [ avanza :longitud gira 90 ]
Conclusiones:
  - Se repite el mismo numero de veces que lados hay (4)
  - Los grados que se giran son los mismos que 360 (los de una vuelta completa) entre el numero de lados (hay que empezar y acabar en el mismo punto y con el mismo angulo)

Esta seria una posibilidad
to figura :num_lados :distancia
  repeat :num_lados [ forward :distancia right 360/:num_lados]
end


Entonces, para hacer un triangulo de 100 de lado, solo habria que escribir
figura 3 100


Y para un cuadrado
figura 4 100


Y para un pentagono
figura 5 100


... creo que ya pillais la idea  :)

Vale, sigamos... si lo que queremos dibujar es un circulo, habria que hacer que de una vuelta de 360 grados, girando sin parar (por decirlo de alguna forma), verdad?
to circulo
  repeat 360[forward 1 right 1]
end



Y ahora... espirales :)
Para esto vamos a utilizar funciones recursivas, para quien no sepa lo que son, las funciones recursivas son las que se llaman a si mismas, por ejemplo el factorial:
si x es 0-> factorial(x)=1
sino-> factorial(x)=x*factorial(x-1)

Por supuesto, hay mas formas de hacerlo, pero esta forma de trabajar nos permitira hacer fractales mas adelante *-*

A lo que hiba, para dibujar una espiral se necesitan varios datos, en este caso vamos a usar la distancia del paso, el angulo de giro y un limite de tamaño, el pseudocodigo seria este:

para espiral :distancia :angulo :limite
   si :distancia>:limite [para]
   avanza :distancia
   gira :angulo
   espiral :distancia+1 :angulo :limite



Veamos detalladamente lo que hace:
 
si :distancia>:limite [para]
Si ya pasamos el limite, ya acabamos
...
Sino
avanza :distancia
girar :angulo

Estos dos no necesitan explicacion, no?
espiral :distancia+1 :angulo :limite
Y hacemos que la espiral siga avanzando, pero ahora, que la distancia sea mayor (para que se vaya "abriendo")

Si pasamos el codigo a Logo...
to espiral :distancia :angulo :limite
  if :distancia>:limite [stop]
  forward :distancia
  right :angulo
  espiral :distancia+1 :angulo :limite
end

Asi, haciendo espiral 0 90 200 (un angulo de 90 para que sea cuadrado) conseguimos:
Pero si cambiamos el angulo un poco... espiral 0 91 200



Ademas, le podemos añadir alguna variable mas para controlarlo mejor

to espiral :distancia :angulo :limite :incremento_distancia
  if :distancia>:limite [stop]
  forward :distancia
  right :angulo
  espiral :distancia+:incremento_distancia :angulo :limite :incremento_distancia
end


Esto añade la opcion de separar mas las lineas, por ejemplo, si a la primera figura se le pone 2 de separacion (1 es el que se usaba antes)... espiral 0 90 200 2
o con el angulo cambiado... espiral 0 91 200 2


Ahora a lo divertido... :D

Con esta funcion, y jugando con filtros de imagenes se  pueden conseguir cosas bastante curiosas... por ejemplo:
Usando espiral 0 121 200 1 obtenemos esta imagen:
 
 Y usando un filtro "Olify" de la categoria "Artistic" (o "Pintura al oleo" de "Artistico") del GIMP:
 
Supongo que en estos casos (cuando se pierde informacion al aplicar el filtro) es mejor ampliar la imagen antes de usar el filtro, asi se notara menos ;)

Y si despues añadimos algo de color...



Ya esta :D!

PS: Tenia pensado hacer un script que cambiase el color de una imagen segun cuanta "luz" hay alrededor ( cuantas mas lineas blancas , mas "luz" ), para hacer efectos directamente con las imagenes de Logo, sin necesidad de un programa de manipulacion de imagen, pero se de imagenes lo que un gato de fisica cuantica, asi que no prometo nada :P

Hasta otra!

[Interpretes]
UCBLogo  ( http://www.eecs.berkeley.edu/~bh/logo.html ) (multiplataforma) [GPLv2]
XLogo ( http://xlogo.tuxfamily.org/sp ) (en Java) [GPL]

FMSLogo ( http://www.fmslogo.org ) ( para Windows ) [GPL]

[Referencias]
Wikipedia
http://neoparaiso.com/logo/
http://et.bgcbellevue.org/logo/

No hay comentarios:

Publicar un comentario