Menú

   

Actualizado

 

Ampliación de Programación - Haskell

Animaciones Funcionales Reactivas

En esta práctica estudiaremos una biblioteca para realizar animaciones reactivas con Haskell.


Para profundizar sobre el tema puedes consultar:

Si te gusta FRAN puedes mirar también PAN:

  • PAN. Connal Elliot.

Ejemplo


 

 

import AP.Animation

orbitT t (rx,ry) = move (rx*wiggleT t, ry*waggleT t)

elasticBall = ellipse (wiggle,waggle)

pulsatingBall = scale (wiggleTRange 3 (0,1)) (circle 0.3)

demo =
 let  center   = slower 5 |> elasticBall
      orbiter  = orbitT 5 (3,2) |> pulsatingBall
 in withColor yellow |> center
    `over`
    withColor blue |> faster 2 |> orbiter
    `over`
    withColor red |> orbiter

main = animate demo


 

Ejercicios


  1. Se trata de implementar un reloj analógico que funcione en tiempo real. Como mínimo, la animación del reloj debe tener agujas para segundos, minutos y horas y marcas en la esfera cada 5 minutos.
    Tu solución debe contener una función reloj que tome tres argumentos, correspondientes a la hora, segundos y minutos y muestre el reloj a partir de de dicha configuración.
    Asegúrate de que tu programa funciona para horas mayor que 12. Por ejemplo, este puede ser el resultado de llamar a la función reloj con parámetros 14 21 00:


    Desde [aquí] puedes bajarte un ejecutable que muestra los distintos pasos del ejercicio.


    1. Comienza definiendo una función tiempo :: (Beh Int,Beh Int,Beh Int) que devuelva una terna con las horas, minutos y segundos (entre 0 y 59) correspondientes al tiempo del sistema. Para ello, usa las funciones time, truncateB y divMod :: Beh Int -> Beh Int -> (Beh Int,Beh Int) para calcular el cociente y resto de una división de enteros. Puedes comprobar el funcionamiento de esta función con la expresión
      animate |> let (h,m,s) = tiempo in scale 10 |> string |> showB (tripleB h m s).

    2. Define una función manecilla :: Beh Image que tan solo muestre una manecilla del reloj en pantalla. Para dibujar la manecilla, usa la función polygon.

    3. Haz que la manecilla complete un giro de 2*pi radianes cada 60 segundos. Para ello, usa la función rotate. Puedes convertir un valor con tipo Beh Int en uno con tipo Beh Double usando la función fromIntegralB.

    4. Añade a la animación, usando la función over, las manecillas de los minutos y horas. Escala el tamaño de éstas usando la función scaleY y asigna un color distinto a cada una usando withColor. Haz que el ángulo de giro de la manecilla dependa de la correspondiente componente devuelta por tiempo y que cada manecilla complete un giro en su correspondiente periodo.

    5. Añade a la animación las marcas de la esfera.

    6. Añade los parámetros correspondientes a horas, minutos y segundos iniciales y ajusta el tiempo, de modo que la animación comience en la hora especificada.

    7. Opcionalmente puedes añadir algún efecto. Un ejercicio algo más complicado es hacer que el reloj sea reactivo y pueda ser ajustado en tiempo de ejecución, de modo que cada vez que se pulse el botón izquierdo del ratón, el reloj avance un minuto y que al pulsar el derecho avance una hora.

  2. Se trata de realizar una animación para simular el giro de la Tierra y la Luna alrededor del Sol, como la siguiente:

    Desde [aquí] puedes bajarte un ejecutable que muestra los distintos pasos del ejercicio.

    1. Comienza definiendo una función (usando la función sin o cos) que tome dos imágenes y haga que una se mueva cíclicamente de un lado a otro de la pantalla por encima de la otra. El radio del desplazamiento y el periodo de éste (cada cuanto se repite el movimiento) deben ser parámetros de la función.

    2. Modifica la función anterior para que cuando la imagen en movimiento vaya de izquierda a derecha se encuentre delante de la imagen estática, pero al ir de derecha a izquierda se encuentre detrás. Aquí tendras que usar la función condB :: Beh Bool -> Beh a -> Beh a -> Beh a.

    3. Modifica la función anterior para la imagen en movimiento vaya cambiando su tamaño, de modo que aumente al aproximarse al observador y disminuya al alejarse. Opcionalmente, puedes modificar la función anterior para la imagen en movimiento vaya cambiando la intensidad de su color, de modo que aumente al aproximarse al observador y disminuya al alejarse. Usa para ello rgb

    4. Utilizando la función anterior crea una animación de la Luna orbitando sobre la Tierra cada 28 segundos.

    5. Utilizando las funciones previas, crea una animación de la Tierra y la Luna orbitando sobre el Sol cada 365 segundos.

    6. Como mejoras opcionales, puedes hacer las orbitas elípticas y que el eje de giro no sea paralelo al eje X.

  3. [Aquí] hay una implementación más elaborada.

  4. Realiza un animación simple (elígela tu) utilizando la librería de esta práctica.