| Inicial | Temas | Manuales | Ejercicios | Exámenes | Documentación

Tema 0: Programas, funciones y dibujos

Índice

1. Introducción

  • En este tema se introduce algunos conceptos de programación definiendo funciones que generan dibujos.
  • Se usará CodeWorld/Haskell que se encuentra en https://code.world/haskell#.

2. Dibujos elementales

2.1. Dibujo de circunferencias

  • Ejemplo: Escribir un programa para pintar una circunferencia de radio 3.
    Circunferencia.png
  • Programa

    import CodeWorld
    
    main = drawingOf circunferencia
    
    circunferencia = circle 3
    
  • Ejecución en CodeWorld/Haskell: Circunferencia1
  • Avisos:

    Line 3, Column 1: Warning:
        Top-level binding with no type signature: main :: IO ()
    
    Line 5, Column 1: Warning:
        Top-level binding with no type signature: circunferencia :: Picture
    
  • Programa 2 (con tipos)

    import CodeWorld
    
    main :: IO ()
    main = drawingOf circunferencia
    
    circunferencia :: Picture
    circunferencia = circle 3
    
  • Ejecución en CodeWorld/Haskell: Circunferencia2
  • Comentarios:
    • Las funciones

      circle :: Double -> Picture
      drawingOf :: Picture -> IO ()
      
    • Definición de las funciones circunferencia y main.
    • Importación de la librería CodeWorld

2.2. Dibujo de círculos

  • Ejemplo: Escribir un programa para pintar un círculo de radio 3.
    Circulo.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf circulo
    
    circulo :: Picture
    circulo = solidCircle 3
    
  • Ejecución en CodeWorld/Haskell: Circulo
  • Comentario: La función

    solidCircle :: Double -> Picture
    

2.3. Dibujo del plano de coordenas

  • Ejemplo: Escribir un programa para pintar el plano de coordenadas.
    Plano_de_coordenadas.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf plano
    
    plano :: Picture
    plano = coordinatePlane
    
  • Ejecución en CodeWorld/Haskell: Plano de coordenadas
  • Comentario: La función

    coordinatePlane :: Picture
    

2.4. Dibujo de rectángulos

  • Ejemplo: Escribir un programa para pintar un rectángulo de base 6 y altura 3.
    Rectangulo.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf rectangulo
    
    rectangulo :: Picture
    rectangulo = rectangle 6 3
    
  • Ejecución en CodeWorld/Haskell: Rectángulo
  • Double -> Double -> Picture=.
  • Ejemplo: Modificar el programa anterior para que los lados del rectángulo tengan una anchura de 0.5.
    Rectangulo_con_anchura.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf rectangulo
    
    rectangulo :: Picture
    rectangulo = thickRectangle 0.5 6 3
    
  • Ejecución en CodeWorld/Haskell: Rectángulo con anchura
  • Comentario: La función

    thickRectangle :: Double -> Double -> Picture
    
  • Ejemplo: Modificar el programa anterior para pintar un área rectangular de base 6 y altura 3.
    Area_rectangular.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf areaRectangular
    
    areaRectangular :: Picture
    areaRectangular = solidRectangle 6 3
    
  • Ejecución en CodeWorld/Haskell: Área rectangular
  • Comentario: La función

    solidRectangle :: Double -> Double -> Picture=.
    

2.5. Dibujo de caminos

  • Ejemplo: Escribir un programa para pintar el camino que pasa por los puntos (-3,3), (3,3), (-3,-3) y (3,-3).
    Camino.png
  • Programa

    import CodeWorld
    
    main :: IO ()
    main = drawingOf camino
    
    camino :: Picture
    camino = polyline [(-3,3),(3,3),(-3,-3),(3,-3)]
    
  • Ejecución en Codeworld Camino
  • Comentario: La función

    polyline :: [Point] -> Picture
    

2.6. Dibujo de polígonos

  • Ejemplo: Escribir un programa para dibujar el triángulo de vértices (-9,-9), (0,9) y (9,-9).
    Triangulo.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf triangulo
    
    triangulo :: Picture
    triangulo = polygon [(-9,-9),(0,9),(9,-9)]
    
  • Ejecución en CodeWorld/Haskell: Triángulo
  • [Point] -> Picture=

2.7. Dibujo de curvas

  • Ejemplo: Escribir un programa para dibujar la curva que pasa por los puntos (-4,8), (0,-8) y (4,8) junto con el plano cartesiano.
    Curva.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf curvaConEjes
    
    curva :: Picture
    curva = curve [(-4,8),(0,-8),(4,8)]
    
    curvaConEjes :: Picture
    curvaConEjes = curva <> coordinatePlane
    
  • Ejecución en CodeWorld/Haskell: Curva
  • Comentario: La función

    curve :: [Point] -> Picture
    
  • Ejemplo: Modificar el programa anterior para que la curva sea cerrada.
    CurvaCerrada.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf curvaConEjes
    
    curva :: Picture
    curva = closedCurve [(-4,8),(0,-8),(4,8)]
    
    curvaConEjes :: Picture
    curvaConEjes = curva <> coordinatePlane
    
  • Ejecución en CodeWorld/Haskell: Curva cerrada
  • Comentario: La función

    closedCurve :: [Point] -> Picture
    

2.8. Otros dibujos elementales

  • En la documentación de CodeWorld/Haskell

    blank            :: Picture
    thickPolyline    :: Double -> [Point] -> Picture
    thickPolygon     :: Double  -> [Point] -> Picture
    solidPolygon     :: [Point] -> Picture
    thickCurve       :: Double  -> [Point] -> Picture
    thickClosedCurve :: Double  -> [Point] -> Picture
    solidClosedCurve :: [Point] -> Picture
    thickRectangle   :: Double -> Double -> Double -> Picture
    thickCircle      :: Double -> Double -> Picture
    arc              :: Double -> Double -> Double -> Picture
    sector           :: Double -> Double -> Double -> Picture
    thickArc         :: Double -> Double -> Double -> Double -> Picture
    text             :: Text -> Picture
    

3. Dibujos compuestos

3.1. Dibujos con dos dibujos

  • Ejemplo: Escribir un programa para dibujar dos cuadrados de lado 6 y los centros en (0,0) y (3,3).
    DosCuadrados.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf dosCuadrados
    
    dosCuadrados :: Picture
    dosCuadrados = cuadrado1 <> cuadrado2
    
    cuadrado1, cuadrado2 :: Picture
    cuadrado1 = polygon [(-3,-3),(-3,3),(3,3),(3,-3)]
    cuadrado2 = polygon [(0,0),(0,6),(6,6),(6,0)]
    
  • Ejecución en CodeWorld/Haskell: Dos cuadrados
  • Comentario: La función

    (<>) :: Picture -> Picture -> Picture
    

3.2. Dibujos con varios dibujos

  • Ejemplo: Escribir un programa para dibujar tres circunferencias de centro en el origen y radios 2, 4 y 6.
    TresCircunferencias.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf tresCircunferencias
    
    tresCircunferencias :: Picture
    tresCircunferencias = pictures [circle 2, circle 4, circle 6]
    
  • Ejecución en CodeWorld/Haskell: Tres circunferencias
  • Comentario: La función

    pictures :: [Picture] -> Picture
    

4. Transformaciones de dibujos

4.1. Traslaciones

  • Ejemplo: Escribir un programa para pintar el el dibujo obtenido con 5 traslaciones del círculo unidad.
    CirculosTrasladados.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf circulosTrasladados
    
    circulo :: Picture
    circulo = circle 1
    
    circulosTrasladados :: Picture
    circulosTrasladados =
      translated (-4) 0 circulo <>
      translated (-2) 0 circulo <>
      translated   0  0 circulo <>
      translated   2  0 circulo <>
      translated   4  0 circulo
    
  • Ejecución en CodeWorld/Haskell: Cículos trasladados
  • Comentario: La función

    translated :: Double -> Double -> Picture -> Picture
    

4.2. Rotaciones

  • Ejemplo: Escribir un programa para dibujar el cuadrado de lado 5 girado 45º (es decir, π/4 radianes).
    CuadradoRotado.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf cuadradoRotado
    
    cuadrado :: Picture
    cuadrado = rectangle 6 6
    
    cuadradoRotado :: Picture
    cuadradoRotado = rotated (pi/4) cuadrado
    
  • Ejecución en CodeWorld/Haskell: Cuadrado rotado
  • Comentarios: Las funciones

    rotated :: Double -> Picture -> Picture
    pi :: Double
    

4.3. Escalamiento

  • Ejemplo: Escribir un programa para pintar el siguiente dibujo
    TextoEscalado.png
  • Programa:

    {-# LANGUAGE OverloadedStrings #-}
    
    import CodeWorld
    
    main :: IO ()
    main = drawingOf textosEscalados
    
    texto :: Picture
    texto = lettering "I1M"
    
    textosEscalados :: Picture
    textosEscalados =
      translated 0 8    texto <>
      translated 0 5    (scaled 2 3 texto) <>
      translated 0 0    (scaled 3 5 texto) <>
      translated 0 (-7) (scaled 5 8 texto)
    
  • Ejecución en CodeWorld/Haskell: Texto escalado
  • Comentarios:
    • La función

      scaled :: Double -> Double -> Picture -> Picture
      
    • El pragma {-# LANGUAGE OverloadedStrings #-}

4.4. Coloreado

  • Ejemplo: Escribir un programa para dibujar un cuadrado verde sobre uno rojo.
    DosCuadradosColoreados1.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf dosCuadradosColoreados
    
    cuadrado :: Picture
    cuadrado = solidRectangle 4 4
    
    cuadradoRojo :: Picture
    cuadradoRojo = colored red cuadrado
    
    cuadradoVerde :: Picture
    cuadradoVerde = colored green cuadrado
    
    dosCuadradosColoreados :: Picture
    dosCuadradosColoreados =
      cuadradoVerde <>
      translated 2 2 cuadradoRojo
    
  • Ejecución en CodeWorld/Haskell: Dos cuadrados coloreados
  • Comentario: La función

    colored :: Color -> Picture -> Picture
    
  • Ejemplo: Modificar el programa anterior para dibujar el rojo sobre el verde.
    DosCuadradosColoreados2.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf dosCuadradosColoreados
    
    cuadrado :: Picture
    cuadrado = solidRectangle 4 4
    
    cuadradoRojo :: Picture
    cuadradoRojo = colored red cuadrado
    
    cuadradoVerde :: Picture
    cuadradoVerde = colored green cuadrado
    
    dosCuadradosColoreados :: Picture
    dosCuadradosColoreados =
      translated 2 2 cuadradoRojo <>
      cuadradoVerde
    
  • Ejecución en CodeWorld/Haskell: Dos cuadrados coloreados
  • Comentario: capas de dibujos.

5. Programación de dibujos

5.1. Dibujo de un semáforo

  • Ejemplo: Escribir un programa para dibujar un semáforo:
    Semaforo.png
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = drawingOf semaforo
    
    marco :: Picture
    marco = rectangle 2.5 7.5
    
    luz :: Color -> Double ->  Picture
    luz c a = colored c (translated 0 a (solidCircle 1))
    
    semaforo :: Picture
    semaforo =
      luz red    2.5    <>
      luz yellow 0      <>
      luz green  (-2.5) <>
      marco
    
  • Ejecución en CodeWorld/Haskell: Semáforo

5.2. Dibujo de una bandera

  • Ejemplo: Escribir un programa para dibujar la siguiente bandera
    Bandera.png
  • Programa:

    import CodeWorld
    
    main :: IO()
    main = drawingOf dibujo
    
    dibujo :: Picture
    dibujo = pictures [ translated 0 4    (rectangulo red)
                      ,                   rectangulo yellow
                      , translated 0 (-4) (rectangulo purple) ]
    
    rectangulo :: Color -> Picture
    rectangulo c = colored c (solidRectangle 16 4)
    
  • Ejecución en CodeWorld/Haskell: Bandera
  • Comentario: Pueden servir como ejercicio pintar banderas de la galería de banderas.

6. Animaciones de dibujos

6.1. Rotando un cuadrado

  • Ejemplo: Escribir un programa para dibujar un cuadrado girando.
    CuadradoGirando.gif
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = animationOf cuadrado
    
    cuadrado :: Double -> Picture
    cuadrado t = rotated t (colored red (solidRectangle 7 7))
    
  • Ejecución en CodeWorld/Haskell: CuadradoGirando
  • Comentarios:
    • La función

      animationOf :: (Double -> Picture) -> IO ()=
      
    • La variable t representa el número de segundos desde el comienzo de la ejecución del programa.

6.2. Transladando un círculo

  • Ejemplo: Escribir un programa para dibujar un círculo que se mueve horizontalmente.
    CirculoTrasladado.gif
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = animationOf circulo
    
    circulo :: Double -> Picture
    circulo t = translated (9*sin(t-9)) 0 (colored red (solidCircle 1))
    
  • Ejecución en CodeWorld/Haskell: CirculoTrasladado
  • Comentario: La función

    sin :: Double -> Double
    

6.3. Expandiendo un círculo

  • Ejemplo: Escribir un programa para dibujar un cículo que se expande y se contrae.
    CirculoCreciente.gif
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = animationOf circulo
    
    circulo :: Double -> Picture
    circulo t = colored red (solidCircle (8 * sin t))
    
  • Ejecución en Codeworld CirculoCreciente

6.4. Simulación de un reloj

  • Ejemplo: Escribir un programa para simular un reloj y el movimiento del minutero y del segundero.
    Reloj.gif
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = animationOf reloj
    
    reloj :: Double -> Picture
    reloj t = pictures [ minutero t,
                         segundero t,
                         fondo]
    
    fondo :: Picture
    fondo = colored yellow (solidCircle 7)
    
    minutero :: Double -> Picture
    minutero t = rotated (-(2*pi/3600)*t) (thickPolyline 0.1 [(0,0), (0,7)])
    
    segundero :: Double -> Picture
    segundero t = rotated (-(2*pi/60)*t) (polyline[(0,0), (0,7)])
    
  • Ejecución en Codeworld Reloj

6.5. Simulación de una noria de feria

  • Ejemplo: Escribir un programa para simular una noria de feria.
    Noria.gif
  • Programa:

    import CodeWorld
    
    main :: IO ()
    main = animationOf escena
    
    escena :: Double -> Picture
    escena t = ruedaNoria t <> fondo t
    
    fondo :: Double -> Picture
    fondo t =  nubeMovida t <> suelo <> cielo
    
    suelo :: Picture
    suelo = colored (light green) (translated 0 (-8) (solidRectangle 20 4))
    
    cielo :: Picture
    cielo = colored (light blue) (solidRectangle 20 20)
    
    nubeMovida :: Double -> Picture
    nubeMovida t =
      translated (fromInteger (rem (round (2*t)) 28) - 14) 8 nube
    
    nube :: Picture
    nube = colored white (   translated     0 (-0.4) (solidCircle 1.6)
                          <> translated (-1.2)  0.4  (solidCircle 1.2)
                          <> translated     1   0.2  (solidCircle 1.2))
    
    ruedaNoria :: Double -> Picture
    ruedaNoria t = parteMovil t <> parteFija
    
    parteFija :: Picture
    parteFija =
         colored (light gray) (solidPolygon [(-8,-8),(0,-4),(8,-8)])
      <> colored (light gray) (solidRectangle 0.4 10)
    
    parteMovil :: Double -> Picture
    parteMovil t =
         rotated t rueda
      <> caminoCircular coche ((pi/3) * 0 + t)
      <> caminoCircular coche ((pi/3) * 1 + t)
      <> caminoCircular coche ((pi/3) * 2 + t)
      <> caminoCircular coche ((pi/3) * 3 + t)
      <> caminoCircular coche ((pi/3) * 4 + t)
      <> caminoCircular coche ((pi/3) * 5 + t)
    
    rueda :: Picture
    rueda =
         thickCircle 0.4 6
      <> rotated ((pi/6) * 0) radio
      <> rotated ((pi/6) * 1) radio
      <> rotated ((pi/6) * 2) radio
      <> rotated ((pi/6) * 3) radio
      <> rotated ((pi/6) * 4) radio
      <> rotated ((pi/6) * 5) radio
    
    radio :: Picture
    radio = solidRectangle 12 0.2
    
    caminoCircular :: Picture -> Double -> Picture
    caminoCircular d a =
      rotated a (translated 6 0 (rotated (-a) d))
    
    coche :: Picture
    coche =
         translated 0 (-0.5) (solidRectangle 0.2 1.2)
      <> translated 0 (-1.2) (solidRectangle 1.6 0.8)
    
  • Ejecución en Codeworld Noria
  • Comentario: Las funciones round, rem y fromInteger.

7. Material complementario

Este tema también se encuentra como vídeo de clase.


| Inicial | Temas | Manuales | Ejercicios | Exámenes | Documentación

José A. Alonso Jiménez

Sevilla, 07 de abril del 2024

Licencia: Creative Commons.