Tema 27: Programación de animaciones en Haskell con Gloss
Índice
1. Animaciones de dibujos
1.1. Rotando un cuadrado
- Vídeo con la animación
Programa rotando_un_cuadrado.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Rotando un cuadrado" (500,500) (20,20)) green animacion animacion :: Float -> Picture animacion t = rotate (60 * t) (rectangleSolid 100 100)
- Comentarios
(InWindow t (b,a) (x,y))
es una ventana de título t, base b y altura a con el vértice superior izquierdo en el punto (x,y).(animate v c a)
dibuja en la ventana v, con color de fondo c, la animación a.- La variable t toma como valor el tiempo transcurrido.
- Sus valores son [0,0.5..].
- Por tanto, los giros son de [0,30,..].
1.2. Moviendo un círculo
- Vídeo con la animación
Programa moviendo_un_circulo.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Moviendo un circulo" (1800,820) (90,90)) green animacion animacion :: Float -> Picture animacion t = translate (50 * t - 900) 0 (color red (circleSolid 25))
- Comentarios
- La variable t toma como valor el tiempo transcurrido.
- Sus valores son [0,0.5..].
- Por tanto, los desplazamientos son [0,25,..].
1.3. Expandiendo un círculo
- Vídeo con la animación
Programa expandiendo_un_circulo.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Expandiendo un circulo" (1800,820) (90,90)) green animacion animacion :: Float -> Picture animacion t = circle (800 * sin (t / 4))
- Comentarios
- La variable t toma como valor el tiempo transcurrido.
- Sus valores son [0,0.5..].
- Por tanto, los radios son [0,10,..].
1.4. Rotación alrededor de un punto
- Vídeo con la animación
Programa rotacion_alrededor_de_un_punto.hs
main :: IO () main = animate (InWindow "Rotacion alrededor de un punto" (1800,820) (90,90)) green animacion animacion :: Float -> Picture animacion t = rotate (60 * t) (translate 400 0 (circleSolid 10))
1.5. Reloj
- Vídeo con la animación
Programa reloj.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Reloj" (1800,820) (90,90)) green animacion animacion :: Float -> Picture animacion t = reloj t reloj :: Float -> Picture reloj t = pictures [ fondo, minutero t, segundero t ] fondo :: Picture fondo = color (dark white) (circleSolid 250) minutero :: Float -> Picture minutero t = rotate (0.1 * t) (line [(0,0), (0,250)]) segundero :: Float -> Picture segundero t = rotate (6 * t) (line [(0,0), (0,250)])
- Comentarios:
- Giro del minutero:
- 360º ~ 1 hora = 60 minutos = 3.600 segundos
- 1 minuto ~ (360/3.600)º = 0.1º
- Giro del segundero:
- 360º ~ 1 minuto = 60 segundos
- 1 segundo ~ (360/60)º = 6º
- Giro del minutero:
2. Animaciones de fractales
2.1. Árbol animado
- Vídeo con la animación
Programa arbol_animado.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Arbol animado" (1800,820) (90,90)) blue animacion animacion :: Float -> Picture animacion t = Pictures [ Translate 0 150 rectanguloDeFondo , Translate 0 0 rectanguloDeFondo , Translate 0 (-150) rectanguloDeFondo , Translate 0 (-150) (fractalArbol 7 t) ] rectanguloDeFondo :: Picture rectanguloDeFondo = Pictures [ Color red (rectangleSolid 400 100) , Color white (rectangleWire 400 100) ] colorContornoRamas :: Color colorContornoRamas = makeColor 0.3 0.3 1.0 1.0 colorRamas :: Color colorRamas = makeColor 0.0 1.0 0.0 0.5 fractalArbol :: Int -> Float -> Picture fractalArbol 0 _ = Blank fractalArbol n t = Pictures [ Color colorRamas (rectangleUpperSolid 20 300) , Color colorContornoRamas (rectangleUpperWire 20 300) , Translate 0 30 $ Rotate (200 * sin t / fromIntegral n) $ Scale 0.9 0.9 $ fractalArbol (n-1) t , Translate 0 70 $ Rotate (-200 * sin t / fromIntegral n) $ Scale 0.8 0.8 $ fractalArbol (n-1) t ]
2.2. Fractal con relojes animados
- Vídeo con la animación
Programa relojes_animados.hs
import Graphics.Gloss main :: IO () main = animate (InWindow "Relojes animados" (1800,820) (90,90)) black animacion animacion :: Float -> Picture animacion t = Color white $ Scale 110 110 $ Rotate (t * 2*pi) $ fractalReloj 5 t -- El fractal básico está formado por tres círculos desplazados desde el -- origen de la siguiente manera. -- -- 1 -- | -- . -- / \ -- 2 3 -- -- El sentido de giro cambia a medida que aumenta n. Los componentes de -- las iteraciones más altas también giran más rápido. fractalReloj :: Int -> Float -> Picture fractalReloj 0 _ = Blank fractalReloj n s = Pictures [circ1, circ2, circ3, lineas] where a = 1 / sin (2 * pi / 6) b = a * cos (2 * pi / 6) n' = fromIntegral n rot = if even n then 50 * s * log (1 + n') else (-50 * s * log (1 + n')) circNm1 = Pictures [ circle 1 , Scale (a/2.5) (a/2.5) (fractalReloj (n-1) s) , if n > 2 then Color cyan $ Translate (-0.15) 1 $ Scale 0.001 0.001 $ Text (show s) else Blank ] circ1 = Translate 0 a $ Rotate rot circNm1 circ2 = Translate 1 (-b) $ Rotate (-rot) circNm1 circ3 = Translate (-1) (-b) $ Rotate rot circNm1 lineas = Pictures [ Line [(0, 0), ( 0, a)] , Line [(0, 0), ( 1, -b)] , Line [(0, 0), (-1, -b)] ]
3. Bibliografía
- The snake game por Taylor Fausak.
- Titato: Tic tac toe in Haskell por Taylor Fausak.